diff --git a/doc/dev-doc/manual/getting_started.rst b/doc/dev-doc/manual/getting_started.rst
index 36c8b7516..90ac8abd7 100644
--- a/doc/dev-doc/manual/getting_started.rst
+++ b/doc/dev-doc/manual/getting_started.rst
@@ -1,470 +1,496 @@
 Getting Started
 ===============
 
 Building ``Akantu``
 --------------------
 
 Dependencies
 ````````````
 
-In order to compile ``Akantu``  any compiler supporting fully C++14 should work
+In order to compile ``Akantu``  any compiler supporting fully C++14 should work.
 In addition some libraries are required:
 
  - CMake (>= 3.5.1)
  - Boost (preprocessor and Spirit)
  - zlib
  - blas/lapack
 
 For the python interface:
 
  - Python (>=3 is recommended)
  - pybind11 (if not present the build system will try to download it)
 
 To run parallel simulations:
 
  - MPI
  - Scotch
 
 To use the static or implicit dynamic solvers at least one of the following libraries is needed:
 
  - MUMPS (since this is usually compiled in static you also need MUMPS dependencies)
  - PETSc
 
 To compile the tests and examples:
 
  - Gmsh
  - google-test (if not present the build system will try to download it)
 
 Configuring and compilation
 ```````````````````````````
 
 ``Akantu`` is a `CMake <https://cmake.org/>`_ project, so to configure it, you can either
 follow the usual way::
 
   > cd akantu
   > mkdir build
   > cd build
   > ccmake ..
   [ Set the options that you need ]
   > make
   > make install
 
+Using the python interface
+--------------------------
+
+You can install ``Akantu`` using pip::
+
+  > pip install akantu
+
+You can then import the package in a python script as::
+
+  import akantu
+
+The python API is similar to the C++ one, see :ref:`reference` . If you encouter any problem with the python interface, you are welcome to do a merge request or post an issue on `GitLab <https://gitlab.com/akantu/akantu/-/issues>`_ .
+  
+Tutorials with the python interface
+```````````````````````````````````    
+
+To help getting started, several tutorials using the python interface
+are available as notebooks with pre-installed version of ``Akantu`` on Binder.
+The following tutorials are currently available:
+
+`Plate whith a hole loaded <https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.com%2Fakantu%2Ftutorials.git/HEAD?filepath=plate-hole/plate-hole.ipynb>`_
+
+`Loaded cohesive crack <https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.com%2Fakantu%2Ftutorials.git/HEAD?filepath=cohesive-fracture/cohesive-fracture.ipynb>`_
+
+`Making your constitutive law in python <https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.com%2Fakantu%2Ftutorials.git/HEAD?filepath=constitutive-laws/python_constitutive_law.ipynb>`_
+
 
 Writing a ``main`` function
 ---------------------------
 
 ``Akantu`` first needs to be initialized. The memory management included in the
 core library handles the correct allocation and de-allocation of vectors,
 structures and/or objects. Moreover, in parallel computations, the
 initialization procedure performs the communication setup. This is achieved by
 the function :cpp:func:`initialize <akantu::initialize>` that is used as
 follows::
 
     #include "aka_common.hh"
     #include "..."
 
     using namespace akantu;
 
     int main(int argc, char *argv[]) {
       initialize("input_file.dat", argc, argv);
 
       // your code ...
 
     }
 
 The :cpp:func:`initialize <akantu::initialize>` function takes the text inpute
 file and the program parameters which can be parsed by ``Akantu`` in due form
 (see sect:parser). Obviously it is necessary to include all files needed in
 main. In this manual all provided code implies the usage of ``akantu`` as
 namespace.
 
 Compiling your simulation
 -------------------------
 
 The easiest way to compile your simulation is to create a ``cmake`` project by
 putting all your code in some directory of your choosing. Then, make sure that
 you have ``cmake`` installed and create a ``CMakeLists.txt`` file. An example of
 a minimal ``CMakeLists.txt`` file would look like this:
 
 .. code-block:: cmake
 
    project(my_simu)
    cmake_minimum_required(VERSION 3.0.0)
 
    find_package(Akantu REQUIRED)
 
    add_akantu_simulation(my_simu my_simu.cc)
 
 Then create a directory called ``build`` and inside it execute ``cmake
 -DAkantu_DIR=<path_to_akantu> -DCMAKE_BUILD_TYPE=RelWithDebInfo ..``. If you
 installed ``Akantu`` in a standard directory such as ``/usr/local`` (using
 ``make install``), you can omit the ``-DAkantu_DIR=<path_to_akantu>`` option.
 
 Other why ``path_to_akantu`` is either the folder where you built ``Akantu`` if
 you did not do a ``make install``, or if you installed ``Akantu`` in
 ``CMAKE_INSTALL_PREFIX`` it is ``<CMAKE_INSTALL_PREFIX>/share/cmake/Akantu``.
 
 Once ``cmake`` managed to configure and generate a ``makefile`` you can just do
 ``make``
 
 
 .. _loading_mesh:
 
 Creating and Loading a Mesh
 ---------------------------
 
 In its current state, ``Akantu`` supports three types of meshes: Gmsh, Abaqus and
 Diana. Once a :cpp:class:`akantu::Mesh` object is created with a given spatial
 dimension, it can be filled by reading a mesh input file. The method
 :cpp:func:`read <akantu::Mesh::read>` of the class :cpp:class:`Mesh
 <akantu::Mesh>` infers the mesh type from the file extension. If a non-standard
 file extension is used, the mesh type has to be specified. ::
 
     UInt spatial_dimension = 2;
     Mesh mesh(spatial_dimension);
 
     // Reading Gmsh files
     mesh.read("my_gmsh_mesh.msh");
     mesh.read("my_gmsh_mesh", _miot_gmsh);
 
 The Gmsh reader adds the geometrical and physical tags as mesh data. The
 physical values are stored as a :cpp:type:`UInt <akantu::UInt>` data called
 ``tag_0``, if a string name is provided it is stored as a ``std::string`` data
 named ``physical_names``. The geometrical tag is stored as a :cpp:type:`UInt
 <akantu::UInt>` data named ``tag_1``.
 
 Using Arrays
 ------------
 
 Data in ``Akantu`` can be stored in data containers implemented by the
 :cpp:class:`akantu::Array` class. In its most basic usage, the :cpp:class:`Array
 <akantu::Array>` class implemented in \akantu is similar to the ``std::vector``
 class of the Standard Template Library (STL) for C++. A simple :cpp:class:`Array
 <akantu::Array>` containing a sequence of ``nb_element`` values (of a given
 type) can be generated with::
 
   Array<type> example_array(nb_element);
 
 where ``type`` usually is :cpp:type:`Real <akantu::Real>`, :cpp:type:`Int
 <akantu::Int>`, :cpp:type:`UInt <akantu::UInt>` or ``bool``. Each value is
 associated to an index, so that data can be accessed by typing::
 
   auto & val = example_array(index);
 
 ``Arrays`` can also contain tuples of values for each index. In that case, the
 number of components per tuple must be specified at the :cpp:class:`Array
 <akantu::Array>` creation. For example, if we want to create an
 :cpp:class:`Array <akantu::Array>` to store the coordinates (sequences of three
 values) of ten nodes, the appropriate code is the following::
 
   UInt nb_nodes = 10;
   UInt spatial_dimension = 3;
 
   Array<Real> position(nb_nodes, spatial_dimension);
 
 In this case the :math:`x` position of the eighth node number will be given
 by ``position(7, 0)`` (in C++, numbering starts at 0 and not 1). If
 the number of components for the sequences is not specified, the
 default value of 1 is used. Here is a list of some basic operations
 that can be performed on :cpp:class:`Array <akantu::Array>`:
 
   - :cpp:func:`resize(size) <akantu::ArrayDataLayer::resize>` change the size of
     the :cpp:class:`Array <akantu::Array>`.
   - :cpp:func:`clear <akantu::Array::clear>` reset the size of the
     :cpp:class:`Array <akantu::Array>` to zero. (*warning* this changed in >
     v4.0)
   - :cpp:func:`set(t) <akantu::Array::set>` set all entries of the
     :cpp:class:`Array <akantu::Array>` to ``t``.
   - :cpp:func:`copy(const Array & other) <akantu::Array::copy>` copy another
     :cpp:class:`Array <akantu::Array>` into the current one. The two
     :cpp:class:`Arrays <akantu::Array>` should have the same number of
     components.
   - :cpp:func:`push_back(tuple) <akantu::Array::push_back>` append a tuple with
     the correct number of components at the end of the :cpp:class:`Array <akantu::Array>`.
   - :cpp:func:`erase(i) <akantu::Array::erase>` erase the value at the i-th position.
   - :cpp:func:`find(value) <akantu::Array::find>` search ``value`` in the
     current :cpp:class:`Array <akantu::Array>`. Return position index of the
     first occurence or -1 if not found.
   - :cpp:func:`storage() <akantu::Array::storage>` Return the address of the
     allocated memory of the :cpp:class:`Array <akantu::Array>`.
 
 Array iterators
 ---------------
 
 It is very common in ``Akantu`` to loop over arrays to perform a specific treatment.
 This ranges from geometric calculation on nodal quantities to tensor algebra (in
 constitutive laws for example). The :cpp:class:`Array <akantu::Array>` object
 has the possibility to request iterators in order to make the writing of loops
 easier and enhance readability. For instance, a loop over the nodal coordinates
 can be performed like::
 
   // accessing the nodal coordinates Array
   // with spatial_dimension components
   const auto & nodes = mesh.getNodes();
 
   for (const auto & coords : make_view(nodes, spatial_dimension)) {
     // do what you need ....
   }
 
 In that example, each ``coords`` is a :cpp:class:`Vector\<Real\> <akantu::Vector>`
 containing geometrical array of size ``spatial_dimension`` and the iteration is
 conveniently performed by the :cpp:class:`Array <akantu::Array>` iterator.
 
 The :cpp:class:`Array <akantu::Array>` object is intensively used to store
 second order tensor values. In that case, it should be specified that the
 returned object type is a matrix when constructing the iterator. This is done
 when calling the :cpp:func:`make_view <akantu::make_view>`. For instance,
 assuming that we have a :cpp:class:`Array <akantu::Array>` storing stresses, we
 can loop over the stored tensors by::
 
    for (const auto & stress :
      make_view(stresses, spatial_dimension, spatial_dimension)) {
      // stress is of type `const Matrix<Real>&`
    }
 
 In that last example, the :cpp:class:`Matrix\<Real\> <akantu::Matrix>` objects are
 ``spatial_dimension`` :math:`\times` ``spatial_dimension`` matrices. The light
 objects :cpp:class:`Matrix\<T\> <akantu::Matrix>` and
 :cpp:class:`Vector\<T\> <akantu::Vector>` can be used and combined to do most
 common linear algebra. If the number of component is 1, it is possible to use
 :cpp:func:`make_view <akantu::make_view>` to this effect.
 
 
 In general, a mesh consists of several kinds of elements. Consequently, the
 amount of data to be stored can differ for each element type. The
 straightforward example is the connectivity array, namely the sequences of nodes
 belonging to each element (linear triangular elements have fewer nodes than,
 say, rectangular quadratic elements etc.). A particular data structure called
 :cpp:class:`ElementTypeMapArray\<T\> <akantu::ElementTypeMapArray>` is provided
 to easily manage this kind of data. It consists of a group of ``Arrays``, each
 associated to an element type. The following code can retrieve the
 :cpp:class:`ElementTypeMapArray\<UInt\> <akantu::ElementTypeMapArray>` which
 stores the connectivity arrays for a mesh::
 
   const ElementTypeMapArray<UInt> & connectivities =
     mesh.getConnectivities();
 
 Then, the specific array associated to a given element type can be obtained by::
 
   const Array<UInt> & connectivity_triangle =
     connectivities(_triangle_3);
 
 where the first order 3-node triangular element was used in the presented piece
 of code.
 
 Vector & Matrix
 ```````````````
 
 The :cpp:class:`Array\<T\> <akantu::Array>` iterators as presented in the previous
 section can be shaped as :cpp:class:`Vector\<T\> <akantu::Vector>` or
 :cpp:class:`Matrix\<T\> <akantu::Matrix>`. This objects represent 1st and 2nd order
 tensors. As such they come with some functionalities that we will present a bit
 more into detail in this here.
 
 
 ``Vector<T>``
 '''''''''''''
 
 - Accessors:
 
   - :cpp:func:`v(i) <akantu::Vector::operator()>` gives the ``i`` -th
     component of the vector ``v``
   - :cpp:func:`v[i] <akantu::Vector::operator[]>` gives the ``i`` -th
     component of the vector ``v``
   - :cpp:func:`v.size() <akantu::Vector::size>` gives the number of component
 
 - Level 1: (results are scalars)
 
   - :cpp:func:`v.norm() <akantu::Vector::norm>` returns the geometrical norm
     (:math:`L_2`)
   - :cpp:func:`v.norm\<N\>() <akantu::Vector::norm<>>` returns the :math:`L_N`
     norm defined as :math:`\left(\sum_i |v(i)|^N\right)^{1/N}`. N can take any
     positive integer value. There are also some particular values for the most
     commonly used norms, ``L_1`` for the Manhattan norm, ``L_2`` for the
     geometrical norm and ``L_inf`` for the norm infinity.
   - :cpp:func:`v.dot(x) <akantu::Vector::dot>` return the dot product of
     ``v`` and ``x``
   - :cpp:func:`v.distance(x) <akantu::Vector::distance>` return the
     geometrical norm of :math:`v - x`
 
 - Level 2: (results are vectors)
 
   - :cpp:func:`v += s <akantu::Vector::operator+=>`,
     :cpp:func:`v -= s <akantu::Vector::operator-=>`,
     :cpp:func:`v *= s <akantu::Vector::operator*=>`,
     :cpp:func:`v /= s <akantu::Vector::operator/=>` those are element-wise
     operators that sum, substract, multiply or divide all the component of ``v``
     by the scalar ``s``
   - :cpp:func:`v += x <akantu::Vector::operator+=>`, :cpp:func:`v -= x
     <akantu::Vector::operator-=>` sums or substracts the vector ``x`` to/from
     ``v``
   - :cpp:func:`v.mul(A, x, alpha) <akantu::Vector::mul>` stores the result of
     :math:`\alpha \boldsymbol{A} \vec{x}` in ``v``, :math:`\alpha` is equal to 1
     by default
   - :cpp:func:`v.solve(A, b) <akantu::Vector::solve>` stores the result of
     the resolution of the system :math:`\boldsymbol{A} \vec{x} = \vec{b}` in ``v``
   - :cpp:func:`v.crossProduct(v1, v2) <akantu::Vector::crossProduct>`
     computes the cross product of ``v1`` and ``v2`` and stores the result in
     ``v``
 
 ``Matrix<T>``
 '''''''''''''
 
 - Accessors:
 
   - :cpp:func:`A(i, j) <akantu::Matrix::operator()>` gives the component
     :math:`A_{ij}` of the matrix ``A``
   - :cpp:func:`A(i) <akantu::Matrix::operator()>` gives the :math:`i^{th}`
     column of the matrix as a ``Vector``
   - :cpp:func:`A[k] <akantu::Matrix::operator[]>` gives the :math:`k^{th}`
     component of the matrix, matrices are stored in a column major way, which
     means that to access :math:`A_{ij}`, :math:`k = i + j M`
   - :cpp:func:`A.rows() <akantu::Matrix::rows>` gives the number of rows of
     ``A`` (:math:`M`)
   - :cpp:func:`A.cols() <akantu::Matrix::cols>` gives the number of columns
     of ``A`` (:math:`N`)
   - :cpp:func:`A.size() <akantu::Matrix::size>` gives the number of component
     in the matrix (:math:`M \times N`)
 
 - Level 1: (results are scalars)
 
   - :cpp:func:`A.norm() <akantu::Matrix::norm>` is equivalent to
     ``A.norm<L_2>()``
   - :cpp:func:`A.norm\<N\>() <akantu::Matrix::norm<>>` returns the :math:`L_N`
     norm defined as :math:`\left(\sum_i\sum_j |A(i,j)|^N\right)^{1/N}`. N can take
     any positive integer value. There are also some particular values for the most
     commonly used norms, ``L_1`` for the Manhattan norm, ``L_2`` for the
     geometrical norm and ``L_inf`` for the norm infinity.
   - :cpp:func:`A.trace() <akantu::Matrix::trace>` return the trace of ``A``
   - :cpp:func:`A.det() <akantu::Matrix::det>` return the determinant of ``A``
   - :cpp:func:`A.doubleDot(B) <akantu::Matrix::doubleDot>` return the double
     dot product of ``A`` and ``B``, :math:`\mat{A}:\mat{B}`
 
 - Level 3: (results are matrices)
 
   - :cpp:func:`A.eye(s) <akantu::Matrix::eye>`, ``Matrix<T>::eye(s)``
     fills/creates a matrix with the :math:`s\mat{I}` with :math:`\mat{I}` the
     identity matrix
   - :cpp:func:`A.inverse(B) <akantu::Matrix::inverse>` stores
     :math:`\mat{B}^{-1}` in ``A``
   - :cpp:func:`A.transpose() <akantu::Matrix::transpose>` returns
     :math:`\mat{A}^{t}`
   - :cpp:func:`A.outerProduct(v1, v2) <akantu::Matrix::outerProduct>` stores
     :math:`\vec{v_1} \vec{v_2}^{t}` in ``A``
   - :cpp:func:`C.mul\<t_A, t_B\>(A, B, alpha) <akantu::Matrix::mul>`: stores
     the result of the product of ``A`` and code{B} time the scalar ``alpha`` in
     ``C``. ``t_A`` and ``t_B`` are boolean defining if ``A`` and ``B`` should be
     transposed or not.
 
     +----------+----------+--------------+
     |``t_A``   |``t_B``   |result        |
     |          |          |              |
     +----------+----------+--------------+
     |false     |false     |:math:`\mat{C}|
     |          |          |= \alpha      |
     |          |          |\mat{A}       |
     |          |          |\mat{B}`      |
     |          |          |              |
     +----------+----------+--------------+
     |false     |true      |:math:`\mat{C}|
     |          |          |= \alpha      |
     |          |          |\mat{A}       |
     |          |          |\mat{B}^t`    |
     |          |          |              |
     +----------+----------+--------------+
     |true      |false     |:math:`\mat{C}|
     |          |          |= \alpha      |
     |          |          |\mat{A}^t     |
     |          |          |\mat{B}`      |
     |          |          |              |
     +----------+----------+--------------+
     |true      |true      |:math:`\mat{C}|
     |          |          |= \alpha      |
     |          |          |\mat{A}^t     |
     |          |          |\mat{B}^t`    |
     +----------+----------+--------------+
 
   - :cpp:func:`A.eigs(d, V) <akantu::Matrix::eigs>` this method computes the
     eigenvalues and eigenvectors of ``A`` and store the results in ``d`` and
     ``V`` such that :math:`d(i) = \lambda_i` and :math:`V(i) = \vec{v_i}` with
     :math:`\mat{A}\vec{v_i} = \lambda_i\vec{v_i}` and :math:`\lambda_1 > ... >
     \lambda_i > ... > \lambda_N`
 
 
 .. _sect-common-groups:
 
 Mesh
 ----
 
 
 
 Manipulating group of nodes and/or elements
 ```````````````````````````````````````````
 
 ``Akantu`` provides the possibility to manipulate subgroups of elements and
 nodes. Any :cpp:class:`ElementGroup <akantu::ElementGroup>` and/or
 :cpp:class:`NodeGroup <akantu::NodeGroup>` must be managed by a
 :cpp:class:`GroupManager <akantu::GroupManager>`. Such a manager has the role to
 associate group objects to names. This is a useful feature, in particular for
 the application of the boundary conditions, as will be demonstrated in section
 :ref:`sect-smm-boundary`. To most general group manager is the :cpp:class:`Mesh
 <akantu::Mesh>` class which inherits from :cpp:class:`GroupManager
 <akantu::GroupManager>`.
 
 For instance, the following code shows how to request an element group
 to a mesh:
 
 .. code-block:: c++
 
   // request creation of a group of nodes
   NodeGroup & my_node_group = mesh.createNodeGroup("my_node_group");
   // request creation of a group of elements
   ElementGroup & my_element_group = mesh.createElementGroup("my_element_group");
 
   /* fill and use the groups */
 
 
 The ``NodeGroup`` object
 ''''''''''''''''''''''''
 
 A group of nodes is stored in :cpp:class:`NodeGroup <akantu::NodeGroup>`
 objects. They are quite simple objects which store the indexes of the selected
 nodes in a :cpp:class:`Array\<UInt\> <akantu::Array>`. Nodes are selected by
 adding them when calling :cpp:func:`add <akantu::NodeGroup::add>`. For instance
 you can select nodes having a positive :math:`X` coordinate with the following
 code:
 
 .. code-block:: c++
 
   const auto & nodes = mesh.getNodes();
   auto & group = mesh.createNodeGroup("XpositiveNode");
 
   for (auto && data : enumerate(make_view(nodes, spatial_dimension))){
     auto node = std::get<0>(data);
     const auto & position = std::get<1>(data);
     if (position(0) > 0) group.add(node);
   }
 
 
 The ``ElementGroup`` object
 '''''''''''''''''''''''''''
 
 A group of elements is stored in :cpp:class:`ElementGroup
 <akantu::ElementGroup>` objects. Since a group can contain elements of various
 types the :cpp:class:`ElementGroup <akantu::ElementGroup>` object stores indexes
 in a :cpp:class:`ElementTypeMapArray\<UInt\> <akantu::ElementTypeMapArray>`
 object. Then elements can be added to the group by calling :cpp:func:`add
 <akantu::ElementGroup::add>`.
 
 For instance, selecting the elements for which the barycenter of the
 nodes has a positive :math:`X` coordinate can be made with:
 
 .. code-block:: c++
 
    auto & group = mesh.createElementGroup("XpositiveElement");
    Vector<Real> barycenter(spatial_dimension);
 
    for_each_element(mesh, [&](auto && element) {
      mesh.getBarycenter(element, barycenter);
      if (barycenter(_x) > 0.) { group.add(element); }
    });
diff --git a/examples/python/custom-material/CMakeLists.txt b/examples/python/custom-material/CMakeLists.txt
index aa52caed6..fdd5be1bc 100644
--- a/examples/python/custom-material/CMakeLists.txt
+++ b/examples/python/custom-material/CMakeLists.txt
@@ -1,46 +1,46 @@
 #===============================================================================
 # @file   CMakeLists.txt
 #
 # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date creation: Fri Jan 22 2016
 # @date last modification: Thu Feb 20 2020
 #
 # @brief  CMakeLists for custom-material examples
 #
 #
 # @section LICENSE
 #
 # Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
 # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
 #
 # Akantu is free 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/>.
 #
 #===============================================================================
 
 
 add_mesh(square square.geo DIM 2)
-register_example(bi-material
+register_example(bi_material
   SCRIPT bi-material.py
   PYTHON
   FILES_TO_COPY material.dat
   DEPENDS square)
 
 add_mesh(bar bar.geo DIM 2)
-register_example(custom-material
+register_example(custom_material
   SCRIPT custom-material.py
   PYTHON
   FILES_TO_COPY material.dat
   DEPENDS bar)
diff --git a/extra_packages/extra-materials/src/material_FE2/material_FE2.cc b/extra_packages/extra-materials/src/material_FE2/material_FE2.cc
index 68dd33e7f..e7e22b5f9 100644
--- a/extra_packages/extra-materials/src/material_FE2/material_FE2.cc
+++ b/extra_packages/extra-materials/src/material_FE2/material_FE2.cc
@@ -1,199 +1,199 @@
 /**
  * @file   material_FE2.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @brief Material for multi-scale simulations. It stores an
  * underlying RVE on each integration point of the material.
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_FE2.hh"
 #include "communicator.hh"
 #include "solid_mechanics_model_RVE.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialFE2<spatial_dimension>::MaterialFE2(SolidMechanicsModel & model,
                                             const ID & id)
     : Parent(model, id), C("material_stiffness", *this) {
   AKANTU_DEBUG_IN();
 
   this->C.initialize(voigt_h::size * voigt_h::size);
   this->initialize();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialFE2<spatial_dimension>::~MaterialFE2() = default;
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialFE2<dim>::initialize() {
+template <Int dim> void MaterialFE2<dim>::initialize() {
   this->registerParam("element_type", el_type, _triangle_3,
                       _pat_parsable | _pat_modifiable,
                       "element type in RVE mesh");
   this->registerParam("mesh_file", mesh_file, _pat_parsable | _pat_modifiable,
                       "the mesh file for the RVE");
   this->registerParam("nb_gel_pockets", nb_gel_pockets,
                       _pat_parsable | _pat_modifiable,
                       "the number of gel pockets in each RVE");
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialFE2<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   Parent::initMaterial();
 
   /// create a Mesh and SolidMechanicsModel on each integration point of the
   /// material
   auto C_it = this->C(this->el_type).begin(voigt_h::size, voigt_h::size);
 
   for (auto && data :
        enumerate(make_view(C(this->el_type), voigt_h::size, voigt_h::size))) {
     auto q = std::get<0>(data);
     auto & C = std::get<1>(data);
 
     meshes.emplace_back(std::make_unique<Mesh>(
         spatial_dimension, "RVE_mesh_" + std::to_string(q), q + 1));
 
     auto & mesh = *meshes.back();
     mesh.read(mesh_file);
 
     RVEs.emplace_back(std::make_unique<SolidMechanicsModelRVE>(
         mesh, true, this->nb_gel_pockets, _all_dimensions,
         "SMM_RVE_" + std::to_string(q), q + 1));
 
     auto & RVE = *RVEs.back();
     RVE.initFull(_analysis_method = _static);
 
     /// compute intial stiffness of the RVE
     RVE.homogenizeStiffness(C);
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialFE2<spatial_dimension>::computeStress(ElementType el_type,
                                                    GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   // Compute thermal stresses first
 
   Parent::computeStress(el_type, ghost_type);
   Array<Real>::const_scalar_iterator sigma_th_it =
       this->sigma_th(el_type, ghost_type).begin();
 
   // Wikipedia convention:
   // 2*eps_ij (i!=j) = voigt_eps_I
   // http://en.wikipedia.org/wiki/Voigt_notation
 
   Array<Real>::const_matrix_iterator C_it =
       this->C(el_type, ghost_type).begin(voigt_h::size, voigt_h::size);
 
   // create vectors to store stress and strain in Voigt notation
   // for efficient computation of stress
   Vector<Real> voigt_strain(voigt_h::size);
   Vector<Real> voigt_stress(voigt_h::size);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   const Matrix<Real> & C_mat = *C_it;
   const Real & sigma_th = *sigma_th_it;
 
   /// copy strains in Voigt notation
   for (UInt I = 0; I < voigt_h::size; ++I) {
     /// copy stress in
     Real voigt_factor = voigt_h::factors[I];
     UInt i = voigt_h::vec[I][0];
     UInt j = voigt_h::vec[I][1];
 
     voigt_strain(I) = voigt_factor * (grad_u(i, j) + grad_u(j, i)) / 2.;
   }
 
   // compute stresses in Voigt notation
   voigt_stress.mul<false>(C_mat, voigt_strain);
 
   /// copy stresses back in full vectorised notation
   for (UInt I = 0; I < voigt_h::size; ++I) {
     UInt i = voigt_h::vec[I][0];
     UInt j = voigt_h::vec[I][1];
     sigma(i, j) = sigma(j, i) = voigt_stress(I) + (i == j) * sigma_th;
   }
 
   ++C_it;
   ++sigma_th_it;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialFE2<spatial_dimension>::computeTangentModuli(
     ElementType el_type, Array<Real> & tangent_matrix,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real>::const_matrix_iterator C_it =
       this->C(el_type, ghost_type).begin(voigt_h::size, voigt_h::size);
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
   tangent.copy(*C_it);
   ++C_it;
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialFE2<spatial_dimension>::advanceASR(
     const Matrix<Real> & prestrain) {
   AKANTU_DEBUG_IN();
 
   for (auto && data :
        zip(RVEs,
            make_view(this->gradu(this->el_type), spatial_dimension,
                      spatial_dimension),
            make_view(this->eigengradu(this->el_type), spatial_dimension,
                      spatial_dimension),
            make_view(this->C(this->el_type), voigt_h::size, voigt_h::size),
            this->delta_T(this->el_type))) {
     auto & RVE = *(std::get<0>(data));
 
     /// apply boundary conditions based on the current macroscopic displ.
     /// gradient
     RVE.applyBoundaryConditions(std::get<1>(data));
 
     /// apply homogeneous temperature field to each RVE to obtain thermoelastic
     /// effect
     RVE.applyHomogeneousTemperature(std::get<4>(data));
 
     /// advance the ASR in every RVE
     RVE.advanceASR(prestrain);
 
     /// compute the average eigen_grad_u
     RVE.homogenizeEigenGradU(std::get<2>(data));
 
     /// compute the new effective stiffness of the RVE
     RVE.homogenizeStiffness(std::get<3>(data));
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 INSTANTIATE_MATERIAL(material_FE2, MaterialFE2);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_brittle.cc b/extra_packages/extra-materials/src/material_damage/material_brittle.cc
index 39da8979c..70011de6f 100644
--- a/extra_packages/extra-materials/src/material_damage/material_brittle.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_brittle.cc
@@ -1,123 +1,123 @@
 /**
  * @file   material_brittle.cc
  *
  * @author Aranda Ruiz Josue <josue.arandaruiz@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  *
  * @brief  Specialization of the material class for the brittle material
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_brittle.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialBrittle<spatial_dimension>::MaterialBrittle(SolidMechanicsModel & model,
                                                     const ID & id)
     : MaterialDamage<spatial_dimension>(model, id),
       strain_rate_brittle("strain_rate_brittle", *this) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("S_0", S_0, 157e6, _pat_parsable | _pat_modifiable);
   this->registerParam("E_0", E_0, 27e3, _pat_parsable, "Strain rate threshold");
   this->registerParam("A", A, 1.622e-5, _pat_parsable,
                       "Polynome cubic constant");
   this->registerParam("B", B, -1.3274, _pat_parsable,
                       "Polynome quadratic constant");
   this->registerParam("C", C, 3.6544e4, _pat_parsable,
                       "Polynome linear constant");
   this->registerParam("D", D, -181.38e6, _pat_parsable, "Polynome constant");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialBrittle<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   MaterialDamage<spatial_dimension>::initMaterial();
 
   this->strain_rate_brittle.initialize(spatial_dimension * spatial_dimension);
 
   updateInternalParameters();
 
   // this->Yd.resize();
   // const Mesh & mesh = this->model.getFEEngine().getMesh();
 
   // Mesh::type_iterator it = mesh.firstType(spatial_dimension);
   // Mesh::type_iterator last_type = mesh.lastType(spatial_dimension);
 
   // for(; it != last_type; ++it) {
   //   UInt nb_element  = this->element_filter(*it).getSize();
   //   UInt nb_quad = this->model.getFEEngine().getNbQuadraturePoints(*it);
 
   //   Array <Real> & Yd_rand_vec = Yd_rand(*it);
   //   for(UInt e = 0; e < nb_element; ++e) {
   //     Real rand_part = (2 * drand48()-1) * Yd_randomness * Yd;
 
   //     for(UInt q = 0; q < nb_quad; ++q)
   //    Yd_rand_vec(nb_quad*e+q,0) = Yd + rand_part;
   //   }
   // }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialBrittle<spatial_dimension>::updateInternalParameters() {
   MaterialDamage<spatial_dimension>::updateInternalParameters();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialBrittle<spatial_dimension>::computeStress(ElementType el_type,
                                                        GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(el_type, ghost_type).storage();
 
   Array<Real> & velocity = this->model.getVelocity();
   Array<Real> & strain_rate_brittle =
       this->strain_rate_brittle(el_type, ghost_type);
   Array<UInt> & elem_filter = this->element_filter(el_type, ghost_type);
 
   this->model.getFEEngine().gradientOnIntegrationPoints(
       velocity, strain_rate_brittle, spatial_dimension, el_type, ghost_type,
       elem_filter);
 
   Array<Real>::iterator<Matrix<Real>> strain_rate_it =
       this->strain_rate_brittle(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Real sigma_equivalent = 0;
   Real fracture_stress = 0;
   Matrix<Real> & grad_v = *strain_rate_it;
 
   computeStressOnQuad(grad_u, grad_v, sigma, *dam, sigma_equivalent,
                       fracture_stress);
 
   ++strain_rate_it;
   ++dam;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(brittle, MaterialBrittle);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_brittle.hh b/extra_packages/extra-materials/src/material_damage/material_brittle.hh
index 5466e2c56..25017d150 100644
--- a/extra_packages/extra-materials/src/material_damage/material_brittle.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_brittle.hh
@@ -1,110 +1,110 @@
 /**
  * @file   material_brittle.hh
  *
  * @author Aranda Ruiz Josue <josue.arandaruiz@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  *
  * @brief  Brittle damage law
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "material.hh"
 #include "material_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_BRITTLE_HH_
 #define AKANTU_MATERIAL_BRITTLE_HH_
 
 namespace akantu {
 
 /**
  * Material brittle
  *
  * parameters in the material files :
  *   - S_0      : Critical stress at low strain rate (default: 157e6)
  *   - E_0      : Low strain rate threshold (default: 27e3)
  *   - A,B,C,D  : Fitting parameters for the critical stress at high strain
  * rates
  *                (default: 1.622e-11, -1.3274e-6, 3.6544e-2, -181.38)
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialBrittle : public MaterialDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialBrittle(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   void updateInternalParameters() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost) override;
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(Matrix<Real> & grad_u, Matrix<Real> & grad_v,
                                   Matrix<Real> & sigma, Real & dam,
                                   Real & sigma_equivalent,
                                   Real & fracture_stress);
 
   inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam,
                                            Real & sigma_c,
                                            Real & fracture_stress);
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
 public:
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// strain rate arrays ordered by element types
   InternalField<Real> strain_rate_brittle;
 
   // polynome constants for critical stress value
   Real A;
   Real B;
   Real C;
   Real D;
 
   // minimum strain rate
   Real E_0;
 
   // Critical stress at low strain rates
   Real S_0;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_brittle_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_brittle_HH_ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_brittle_inline_impl.hh b/extra_packages/extra-materials/src/material_damage/material_brittle_inline_impl.hh
index ae01b0f5e..30536c737 100644
--- a/extra_packages/extra-materials/src/material_damage/material_brittle_inline_impl.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_brittle_inline_impl.hh
@@ -1,101 +1,101 @@
 /**
  * @file   material_brittle_inline_impl.hh
  *
  * @author Aranda Ruiz Josue <josue.arandaruiz@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  *
  * @brief  Implementation of the inline functions of the material brittle
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialBrittle<spatial_dimension>::computeStressOnQuad(
     Matrix<Real> & grad_u, Matrix<Real> & grad_v, Matrix<Real> & sigma,
     Real & dam, Real & sigma_equivalent, Real & fracture_stress) {
 
   MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
 
   Real equiv_strain_rate = 0.;
   Real volume_change_rate = grad_v.trace();
   if (spatial_dimension == 2) {
     equiv_strain_rate += 2. / 3. * pow(volume_change_rate / 3., 2.);
   }
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j)
       equiv_strain_rate += 2. / 3. *
                            pow(0.5 * (grad_v(i, j) + grad_v(j, i)) -
                                    (i == j) * volume_change_rate / 3.,
                                2.);
 
   equiv_strain_rate = sqrt(equiv_strain_rate);
 
   fracture_stress = S_0;
   if (equiv_strain_rate > E_0)
     fracture_stress = A;
 
   Vector<Real> principal_stress(spatial_dimension);
   sigma.eig(principal_stress);
   sigma_equivalent = principal_stress(0);
   for (UInt i = 1; i < spatial_dimension; ++i)
     sigma_equivalent = std::max(sigma_equivalent, principal_stress(i));
 
   if (!this->is_non_local) {
     computeDamageAndStressOnQuad(sigma, dam, sigma_equivalent, fracture_stress);
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialBrittle<spatial_dimension>::computeDamageAndStressOnQuad(
     Matrix<Real> & sigma, Real & dam, Real & sigma_c, Real & fracture_stress) {
   if (sigma_c > fracture_stress)
     dam = 1.;
 
   dam = std::min(dam, 1.);
 
   sigma *= 1 - dam;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline UInt MaterialBrittle<spatial_dimension>::getNbData(
     const Array<Element> & elements, const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = MaterialDamage<spatial_dimension>::getNbData(elements, tag);
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialBrittle<spatial_dimension>::packData(
     CommunicationBuffer & buffer, const Array<Element> & elements,
     const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   MaterialDamage<spatial_dimension>::packData(buffer, elements, tag);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void
 MaterialBrittle<spatial_dimension>::unpackData(CommunicationBuffer & buffer,
                                                const Array<Element> & elements,
                                                const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   MaterialDamage<spatial_dimension>::unpackData(buffer, elements, tag);
 
   AKANTU_DEBUG_OUT();
 }
diff --git a/extra_packages/extra-materials/src/material_damage/material_brittle_non_local.hh b/extra_packages/extra-materials/src/material_damage/material_brittle_non_local.hh
index e079ed307..2adff96f1 100644
--- a/extra_packages/extra-materials/src/material_damage/material_brittle_non_local.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_brittle_non_local.hh
@@ -1,88 +1,88 @@
 /**
  * @file   material_brittle_non_local.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  *
  * @brief  MaterialBrittleNonLocal header for non-local damage
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "material_brittle.hh"
 #include "material_damage_non_local.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_BRITTLE_NON_LOCAL_HH_
 #define AKANTU_MATERIAL_BRITTLE_NON_LOCAL_HH_
 
 namespace akantu {
 
 /**
  * Material Brittle Non local
  *
  * parameters in the material files :
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialBrittleNonLocal
     : public MaterialDamageNonLocal<spatial_dimension,
                                     MaterialBrittle<spatial_dimension>> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   typedef MaterialDamageNonLocal<spatial_dimension,
                                  MaterialBrittle<spatial_dimension>>
       MaterialBrittleNonLocalParent;
   MaterialBrittleNonLocal(SolidMechanicsModel & model, const ID & id = "");
 
   virtual ~MaterialBrittleNonLocal(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial();
 
 protected:
   /// constitutive law
   void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
 
   void computeNonLocalStress(ElementType type,
                              GhostType ghost_type = _not_ghost);
 
   /// associate the non-local variables of the material to their neighborhoods
   virtual void nonLocalVariableToNeighborhood();
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Sigma_max, Sigma_max, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   InternalField<Real> Sigma_max;
   InternalField<Real> Sigma_maxnl;
   InternalField<Real> Sigma_fracture;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_brittle_non_local_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_BRITTLE_NON_LOCAL_HH_ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_brittle_non_local_inline_impl.hh b/extra_packages/extra-materials/src/material_damage/material_brittle_non_local_inline_impl.hh
index df37077c9..8790b4350 100644
--- a/extra_packages/extra-materials/src/material_damage/material_brittle_non_local_inline_impl.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_brittle_non_local_inline_impl.hh
@@ -1,116 +1,116 @@
 /**
  * @file   material_brittle_non_local_inline_impl.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  *
  * @brief  MaterialBrittleNonLocal inline function implementation
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #if defined(AKANTU_DEBUG_TOOLS)
 #include "aka_debug_tools.hh"
 #include <string>
 #endif
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialBrittleNonLocal<spatial_dimension>::MaterialBrittleNonLocal(
     SolidMechanicsModel & model, const ID & id)
     : Material(model, id), MaterialBrittleNonLocalParent(model, id),
       Sigma_max("Sigma max", *this), Sigma_maxnl("Sigma_max non local", *this),
       Sigma_fracture("Sigma_fracture", *this) {
   AKANTU_DEBUG_IN();
   this->is_non_local = true;
   this->Sigma_max.initialize(1);
   this->Sigma_maxnl.initialize(1);
   this->Sigma_fracture.initialize(1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialBrittleNonLocal<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   this->model.getNonLocalManager().registerNonLocalVariable(
       this->Sigma_max.getName(), Sigma_maxnl.getName(), 1);
   MaterialBrittleNonLocalParent::initMaterial();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialBrittleNonLocal<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(el_type, ghost_type).storage();
   Real * Sigma_maxt = this->Sigma_max(el_type, ghost_type).storage();
   Real * fracture_stress = this->Sigma_fracture(el_type, ghost_type).storage();
 
   Array<Real> & velocity = this->model.getVelocity();
   Array<Real> & strain_rate_brittle =
       this->strain_rate_brittle(el_type, ghost_type);
   Array<UInt> & elem_filter = this->element_filter(el_type, ghost_type);
 
   this->model.getFEEngine().gradientOnIntegrationPoints(
       velocity, strain_rate_brittle, spatial_dimension, el_type, ghost_type,
       elem_filter);
 
   Array<Real>::iterator<Matrix<Real>> strain_rate_it =
       this->strain_rate_brittle(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & grad_v = *strain_rate_it;
 
   MaterialBrittle<spatial_dimension>::computeStressOnQuad(
       grad_u, grad_v, sigma, *dam, *Sigma_maxt, *fracture_stress);
   ++dam;
   ++strain_rate_it;
   ++Sigma_maxt;
   ++fracture_stress;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialBrittleNonLocal<spatial_dimension>::computeNonLocalStress(
     ElementType type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(type, ghost_type).storage();
   Real * Sigma_maxnlt = this->Sigma_maxnl(type, ghost_type).storage();
   Real * fracture_stress = this->Sigma_fracture(type, ghost_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(type, ghost_type);
   this->computeDamageAndStressOnQuad(sigma, *dam, *Sigma_maxnlt,
                                      *fracture_stress);
 
   ++dam;
   ++Sigma_maxnlt;
   ++fracture_stress;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialBrittleNonLocal<
     spatial_dimension>::nonLocalVariableToNeighborhood() {
   this->model.getNonLocalManager().nonLocalVariableToNeighborhood(
       Sigma_maxnl.getName(), this->name);
 }
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_iterative.cc b/extra_packages/extra-materials/src/material_damage/material_damage_iterative.cc
index ec5bb0e5b..e408873bb 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_iterative.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_iterative.cc
@@ -1,246 +1,246 @@
 /**
  * @file   material_damage_iterative.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Specialization of the class material damage to damage only one gauss
  * point at a time and propagate damage in a linear way. Max principal stress
  * criterion is used as a failure criterion.
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_damage_iterative.hh"
 #include "communicator.hh"
 #include "data_accessor.hh"
 #include "solid_mechanics_model_RVE.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialDamageIterative<spatial_dimension>::MaterialDamageIterative(
     SolidMechanicsModel & model, const ID & id)
     : MaterialDamage<spatial_dimension>(model, id), Sc("Sc", *this),
       reduction_step("damage_step", *this),
       equivalent_stress("equivalent_stress", *this), max_reductions(0),
       norm_max_equivalent_stress(0) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("Sc", Sc, _pat_parsable, "critical stress threshold");
   this->registerParam("prescribed_dam", prescribed_dam, 0.1,
                       _pat_parsable | _pat_modifiable, "prescribed damage");
   this->registerParam(
       "dam_threshold", dam_threshold, 0.8, _pat_parsable | _pat_modifiable,
       "damage threshold at which damage damage will be set to 1");
   this->registerParam(
       "dam_tolerance", dam_tolerance, 0.01, _pat_parsable | _pat_modifiable,
       "damage tolerance to decide if quadrature point will be damageed");
   this->registerParam("max_damage", max_damage, 0.99999,
                       _pat_parsable | _pat_modifiable, "maximum damage value");
   this->registerParam("max_reductions", max_reductions, UInt(10),
                       _pat_parsable | _pat_modifiable, "max reductions");
 
   this->use_previous_stress = true;
   this->use_previous_gradu = true;
   this->Sc.initialize(1);
   this->equivalent_stress.initialize(1);
   this->reduction_step.initialize(1);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::
     computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                       ElementType el_type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// Vector to store eigenvalues of current stress tensor
   Vector<Real> eigenvalues(spatial_dimension);
 
   auto Sc_it = Sc(el_type, ghost_type).begin();
   auto equivalent_stress_it = equivalent_stress(el_type, ghost_type).begin();
 
   Array<Real>::const_matrix_iterator grad_u_it =
       grad_u.begin(spatial_dimension, spatial_dimension);
   Array<Real>::const_matrix_iterator grad_u_end =
       grad_u.end(spatial_dimension, spatial_dimension);
   Real * dam = this->damage(el_type, ghost_type).storage();
   Matrix<Real> sigma(spatial_dimension, spatial_dimension);
   for (; grad_u_it != grad_u_end; ++grad_u_it) {
     sigma.zero();
     MaterialElastic<spatial_dimension>::computeStressOnQuad(*grad_u_it, sigma,
                                                             0.);
     computeDamageAndStressOnQuad(sigma, *dam);
 
     /// compute eigenvalues
     sigma.eig(eigenvalues);
     /// find max eigenvalue and normalize by tensile strength
     *equivalent_stress_it =
         *(std::max_element(eigenvalues.storage(),
                            eigenvalues.storage() + spatial_dimension)) /
         *(Sc_it);
     ++Sc_it;
     ++equivalent_stress_it;
     ++dam;
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::computeAllStresses(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// reset normalized maximum equivalent stress
   if (ghost_type == _not_ghost)
     norm_max_equivalent_stress = 0;
 
   MaterialDamage<spatial_dimension>::computeAllStresses(ghost_type);
 
   /// find global Gauss point with highest stress
   auto rve_model = dynamic_cast<SolidMechanicsModelRVE *>(&this->model);
   if (rve_model == NULL) {
     /// is no RVE model
     const auto & comm = this->model.getMesh().getCommunicator();
     comm.allReduce(norm_max_equivalent_stress, SynchronizerOperation::_max);
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::
     findMaxNormalizedEquivalentStress(ElementType el_type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if (ghost_type == _not_ghost) {
 
     // const Array<Real> & e_stress = equivalent_stress(el_type);
 
     // if (e_stress.begin() != e_stress.end() ) {
     //   auto equivalent_stress_it_max =
     //   std::max_element(e_stress.begin(),e_stress.end());
     //   /// check if max equivalent stress for this element type is greater
     //   than the current norm_max_eq_stress
     //   if (*equivalent_stress_it_max > norm_max_equivalent_stress)
     // 	norm_max_equivalent_stress = *equivalent_stress_it_max;
     // }
     const Array<Real> & e_stress = equivalent_stress(el_type);
     auto equivalent_stress_it = e_stress.begin();
     auto equivalent_stress_end = e_stress.end();
     Array<Real> & dam = this->damage(el_type);
     auto dam_it = dam.begin();
 
     for (; equivalent_stress_it != equivalent_stress_end;
          ++equivalent_stress_it, ++dam_it) {
       /// check if max equivalent stress for this element type is greater than
       /// the current norm_max_eq_stress and if the element is not already fully
       /// damaged
       if (*equivalent_stress_it > norm_max_equivalent_stress &&
           *dam_it < max_damage) {
         norm_max_equivalent_stress = *equivalent_stress_it;
       }
     }
   }
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MaterialDamage<spatial_dimension>::computeStress(el_type, ghost_type);
 
   Real * dam = this->damage(el_type, ghost_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   computeDamageAndStressOnQuad(sigma, *dam);
   ++dam;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   computeNormalizedEquivalentStress(this->gradu(el_type, ghost_type), el_type,
                                     ghost_type);
   norm_max_equivalent_stress = 0;
   findMaxNormalizedEquivalentStress(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 UInt MaterialDamageIterative<spatial_dimension>::updateDamage() {
   UInt nb_damaged_elements = 0;
   AKANTU_DEBUG_ASSERT(prescribed_dam > 0.,
                       "Your prescribed damage must be greater than zero");
 
   if (norm_max_equivalent_stress >= 1.) {
 
     AKANTU_DEBUG_IN();
 
     /// update the damage only on non-ghosts elements! Doesn't make sense to
     /// update on ghost.
     GhostType ghost_type = _not_ghost;
 
     for (auto && el_type : this->model.getFEEngine().getMesh().elementTypes(
              spatial_dimension, ghost_type)) {
       const Array<Real> & e_stress = equivalent_stress(el_type);
       auto equivalent_stress_it = e_stress.begin();
       auto equivalent_stress_end = e_stress.end();
       Array<Real> & dam = this->damage(el_type);
       auto dam_it = dam.begin();
       auto reduction_it = this->reduction_step(el_type, ghost_type).begin();
 
       for (; equivalent_stress_it != equivalent_stress_end;
            ++equivalent_stress_it, ++dam_it, ++reduction_it) {
 
         /// check if damage occurs
         if (*equivalent_stress_it >=
             (1 - dam_tolerance) * norm_max_equivalent_stress) {
           /// check if this element can still be damaged
           if (*reduction_it == this->max_reductions)
             continue;
           *reduction_it += 1;
           if (*reduction_it == this->max_reductions) {
             *dam_it = max_damage;
           } else {
             *dam_it += prescribed_dam;
           }
           nb_damaged_elements += 1;
         }
       }
     }
   }
 
   auto * rve_model = dynamic_cast<SolidMechanicsModelRVE *>(&this->model);
   if (rve_model == NULL) {
     const auto & comm = this->model.getMesh().getCommunicator();
     comm.allReduce(nb_damaged_elements, SynchronizerOperation::_sum);
   }
 
   AKANTU_DEBUG_OUT();
   return nb_damaged_elements;
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::updateEnergiesAfterDamage(
     ElementType el_type) {
   MaterialDamage<spatial_dimension>::updateEnergies(el_type);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(damage_iterative, MaterialDamageIterative);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_iterative.hh b/extra_packages/extra-materials/src/material_damage/material_damage_iterative.hh
index c844568f1..c45a88927 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_iterative.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_iterative.hh
@@ -1,145 +1,145 @@
 /**
  * @file   material_damage_iterative.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Specialization of the class material damage to damage only one gauss
  * point at a time and propagate damage in a linear way. Max principal stress
  * criterion is used as a failure criterion.
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "material.hh"
 #include "material_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_DAMAGE_ITERATIVE_HH_
 #define AKANTU_MATERIAL_DAMAGE_ITERATIVE_HH_
 
 namespace akantu {
 
 /**
  * Material damage iterative
  *
  * parameters in the material files :
  *   - Sc
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialDamageIterative : public MaterialDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialDamageIterative(SolidMechanicsModel & model, const ID & id = "");
 
   ~MaterialDamageIterative() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   ///  virtual void updateInternalParameters();
 
   void computeAllStresses(GhostType ghost_type = _not_ghost) override;
 
   /// update internal field damage
   virtual UInt updateDamage();
 
   UInt updateDamage(UInt quad_index, Real eq_stress,
                     ElementType el_type, GhostType ghost_type);
 
   /// update energies after damage has been updated
   void updateEnergiesAfterDamage(ElementType el_type) override;
 
   /// compute the equivalent stress on each Gauss point (i.e. the max prinicpal
   /// stress) and normalize it by the tensile strength
   virtual void
   computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                     ElementType el_type,
                                     GhostType ghost_type = _not_ghost);
 
   /// find max normalized equivalent stress
   void findMaxNormalizedEquivalentStress(ElementType el_type,
                                          GhostType ghost_type = _not_ghost);
 
 protected:
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                              GhostType ghost_type = _not_ghost) override;
 
   inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam);
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor 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;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get max normalized equivalent stress
   AKANTU_GET_MACRO(NormMaxEquivalentStress, norm_max_equivalent_stress, Real);
 
   /// get a non-const reference to the max normalized equivalent stress
   AKANTU_GET_MACRO_NOT_CONST(NormMaxEquivalentStress,
                              norm_max_equivalent_stress, Real &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// resistance to damage
   RandomInternalField<Real> Sc;
 
   /// the reduction
   InternalField<UInt> reduction_step;
 
   /// internal field to store equivalent stress on each Gauss point
   InternalField<Real> equivalent_stress;
 
   /// the number of total reductions steps until complete failure
   UInt max_reductions;
 
   /// damage increment
   Real prescribed_dam;
 
   /// maximum equivalent stress
   Real norm_max_equivalent_stress;
 
   /// deviation from max stress at which Gauss point will still get damaged
   Real dam_tolerance;
 
   /// define damage threshold at which damage will be set to 1
   Real dam_threshold;
 
   /// maximum damage value
   Real max_damage;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_damage_iterative_inline_impl.hh"
 
 #endif /* AKANTU_MATERIAL_DAMAGE_ITERATIVE_HH_ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_inline_impl.hh b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_inline_impl.hh
index 1e6f9c816..96b2799f1 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_inline_impl.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_inline_impl.hh
@@ -1,91 +1,91 @@
 /**
  * @file   material_damage_iterative_inline_impl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Implementation of inline functions of the material damage iterative
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "material_damage_iterative.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void
 MaterialDamageIterative<spatial_dimension>::computeDamageAndStressOnQuad(
     Matrix<Real> & sigma, Real & dam) {
   sigma *= 1 - dam;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 UInt MaterialDamageIterative<spatial_dimension>::updateDamage(
     UInt quad_index, const Real /*eq_stress*/, ElementType el_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_ASSERT(prescribed_dam > 0.,
                       "Your prescribed damage must be greater than zero");
 
   Array<Real> & dam = this->damage(el_type, ghost_type);
   Real & dam_on_quad = dam(quad_index);
 
   /// check if damage occurs
   if (equivalent_stress(el_type, ghost_type)(quad_index) >=
       (1 - dam_tolerance) * norm_max_equivalent_stress) {
     if (dam_on_quad < dam_threshold)
       dam_on_quad += prescribed_dam;
     else
       dam_on_quad = max_damage;
     return 1;
   }
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline UInt MaterialDamageIterative<spatial_dimension>::getNbData(
     const Array<Element> & elements, const SynchronizationTag & tag) const {
 
   if (tag == SynchronizationTag::_user_2) {
     return sizeof(Real) * this->getModel().getNbIntegrationPoints(elements);
   }
 
   return MaterialDamage<spatial_dimension>::getNbData(elements, tag);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialDamageIterative<spatial_dimension>::packData(
     CommunicationBuffer & buffer, const Array<Element> & elements,
     const SynchronizationTag & tag) const {
   if (tag == SynchronizationTag::_user_2) {
     DataAccessor<Element>::packElementalDataHelper(
         this->damage, buffer, elements, true, this->damage.getFEEngine());
   }
 
   return MaterialDamage<spatial_dimension>::packData(buffer, elements, tag);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialDamageIterative<spatial_dimension>::unpackData(
     CommunicationBuffer & buffer, const Array<Element> & elements,
     const SynchronizationTag & tag) {
   if (tag == SynchronizationTag::_user_2) {
     DataAccessor<Element>::unpackElementalDataHelper(
         this->damage, buffer, elements, true, this->damage.getFEEngine());
   }
   return MaterialDamage<spatial_dimension>::unpackData(buffer, elements, tag);
 }
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.cc b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.cc
index aaa58fc13..6ccc56a33 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.cc
@@ -1,41 +1,41 @@
 /**
  * @file   material_damage_iterative.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Implementation of MaterialDamageIterativeNonLocal
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_damage_iterative_non_local.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageIterativeNonLocal<
     spatial_dimension>::computeNonLocalStresses(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// reset normalized maximum equivalent stress
   if (ghost_type == _not_ghost)
     this->norm_max_equivalent_stress = 0;
 
   MaterialDamageIterativeNonLocalParent::computeNonLocalStresses(ghost_type);
 
   /// find global Gauss point with highest stress
   const auto & comm = this->model.getMesh().getCommunicator();
   comm.allReduce(this->norm_max_equivalent_stress, SynchronizerOperation::_max);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 INSTANTIATE_MATERIAL(damage_iterative_non_local,
                      MaterialDamageIterativeNonLocal);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.hh b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.hh
index af8b329eb..e760aa00b 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local.hh
@@ -1,80 +1,80 @@
 /**
  * @file   material_damage_iterative_non_local.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  MaterialDamageIterativeNonLocal header for non-local damage
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "material_damage_iterative.hh"
 #include "material_damage_non_local.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_DAMAGE_ITERATIVE_NON_LOCAL_HH_
 #define AKANTU_MATERIAL_DAMAGE_ITERATIVE_NON_LOCAL_HH_
 
 namespace akantu {
 
 /**
  * Material Damage Iterative Non local
  *
  * parameters in the material files :
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialDamageIterativeNonLocal
     : public MaterialDamageNonLocal<
           spatial_dimension, MaterialDamageIterative<spatial_dimension>> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   typedef MaterialDamageNonLocal<spatial_dimension,
                                  MaterialDamageIterative<spatial_dimension>>
       MaterialDamageIterativeNonLocalParent;
   MaterialDamageIterativeNonLocal(SolidMechanicsModel & model,
                                   const ID & id = "");
 
   virtual ~MaterialDamageIterativeNonLocal(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial();
   virtual void computeNonLocalStresses(GhostType ghost_type);
 
 protected:
   void computeStress(ElementType type, GhostType ghost_type);
 
   void computeNonLocalStress(ElementType type,
                              GhostType ghost_type = _not_ghost);
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   InternalField<Real> grad_u_nl;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_damage_iterative_non_local_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_DAMAGE_ITERATIVE_NON_LOCAL_HH_ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local_inline_impl.hh b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local_inline_impl.hh
index 906cc0802..9c3af9681 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local_inline_impl.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_iterative_non_local_inline_impl.hh
@@ -1,88 +1,88 @@
 /**
  * @file   material_damage_iterative_non_local_inline_impl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  MaterialDamageIterativeNonLocal inline function implementation
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #if defined(AKANTU_DEBUG_TOOLS)
 #include "aka_debug_tools.hh"
 #include <string>
 #endif
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialDamageIterativeNonLocal<spatial_dimension>::
     MaterialDamageIterativeNonLocal(SolidMechanicsModel & model, const ID & id)
     : MaterialDamageIterativeNonLocalParent(model, id),
       grad_u_nl("grad_u non local", *this) {
   AKANTU_DEBUG_IN();
   this->is_non_local = true;
   this->grad_u_nl.initialize(spatial_dimension * spatial_dimension);
   this->model.getNonLocalManager().registerNonLocalVariable(
       this->gradu.getName(), grad_u_nl.getName(),
       spatial_dimension * spatial_dimension);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageIterativeNonLocal<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   MaterialDamageIterativeNonLocalParent::initMaterial();
 
   this->model.getNonLocalManager().nonLocalVariableToNeighborhood(
       grad_u_nl.getName(), this->name);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageIterativeNonLocal<spatial_dimension>::computeStress(
     ElementType /*type*/, GhostType /*ghost_type*/) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageIterativeNonLocal<spatial_dimension>::computeNonLocalStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// compute the stress (based on the elastic law)
   MaterialDamage<spatial_dimension>::computeStress(el_type, ghost_type);
 
   /// multiply the stress by (1-d) to get the effective stress
   Real * dam = this->damage(el_type, ghost_type).storage();
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   this->computeDamageAndStressOnQuad(sigma, *dam);
   ++dam;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   /// compute the normalized equivalent stress
   this->computeNormalizedEquivalentStress(this->grad_u_nl(el_type, ghost_type),
                                           el_type, ghost_type);
   /// find the maximum
   this->norm_max_equivalent_stress = 0;
   this->findMaxNormalizedEquivalentStress(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_linear.cc b/extra_packages/extra-materials/src/material_damage/material_damage_linear.cc
index cfe635419..e74a17cbb 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_linear.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_linear.cc
@@ -1,73 +1,73 @@
 /**
  * @file   material_damage_linear.cc
  *
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  *
  *
  * @brief  Specialization of the material class for the damage material
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_damage_linear.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialDamageLinear<spatial_dimension>::MaterialDamageLinear(
     SolidMechanicsModel & model, const ID & id)
     : MaterialDamage<spatial_dimension>(model, id), K("K", *this) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("Sigc", Sigc, 1e5, _pat_parsable, "Sigma Critique");
   this->registerParam("Gc", Gc, 2., _pat_parsable, "Gc");
 
   this->K.initialize(1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageLinear<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   MaterialDamage<spatial_dimension>::initMaterial();
 
   Epsmin = Sigc / this->E;
   Epsmax = 2 * Gc / Sigc + Epsmin;
 
   this->K.setDefaultValue(Epsmin);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialDamageLinear<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(el_type, ghost_type).storage();
   Real * K = this->K(el_type, ghost_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   this->computeStressOnQuad(grad_u, sigma, *dam, *K);
   ++dam;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(damage_linear, MaterialDamageLinear);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_linear.hh b/extra_packages/extra-materials/src/material_damage/material_damage_linear.hh
index 7c00c44f3..08ca68f3e 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_linear.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_linear.hh
@@ -1,85 +1,85 @@
 /**
  * @file   material_damage_linear.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  *
  *
  * @brief  Material isotropic elastic + linear softening
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "material_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_DAMAGE_LINEAR_HH_
 #define AKANTU_MATERIAL_DAMAGE_LINEAR_HH_
 
 namespace akantu {
 
 /**
  * Material liner damage
  *
  * parameters in the material files :
  *   - Sigc : (default: 1e5)
  *   - Gc  : (default: 2)
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialDamageLinear : public MaterialDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialDamageLinear(SolidMechanicsModel & model, const ID & id = "");
 
   virtual ~MaterialDamageLinear(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial();
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(Matrix<Real> & F, Matrix<Real> & sigma,
                                   Real & damage, Real & K);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// kind of toughness
   Real Gc;
 
   /// critical stress
   Real Sigc;
 
   /// damage internal variable
   InternalField<Real> K;
 
   Real Epsmin, Epsmax;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_damage_linear_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_DAMAGE_LINEAR_HH_ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_damage_linear_inline_impl.hh b/extra_packages/extra-materials/src/material_damage/material_damage_linear_inline_impl.hh
index e3c27fbc9..fe200d068 100644
--- a/extra_packages/extra-materials/src/material_damage/material_damage_linear_inline_impl.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_damage_linear_inline_impl.hh
@@ -1,43 +1,43 @@
 /**
  * @file   material_damage_linear_inline_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  *
  *
  * @brief  Implementation of the inline functions of the material damage linear
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialDamageLinear<spatial_dimension>::computeStressOnQuad(
     Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam, Real & K) {
   Real Fdiag[3];
   Real Fdiagp[3];
 
   Math::matrix33_eigenvalues(grad_u.storage(), Fdiag);
 
   Fdiagp[0] = std::max(0., Fdiag[0]);
   Fdiagp[1] = std::max(0., Fdiag[1]);
   Fdiagp[2] = std::max(0., Fdiag[2]);
 
   Real Ehat = sqrt(Fdiagp[0] * Fdiagp[0] + Fdiagp[1] * Fdiagp[1] +
                    Fdiagp[2] * Fdiagp[2]);
 
   MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
 
   Real Fd = Ehat - K;
 
   if (Fd > 0) {
     dam = (Ehat - Epsmin) / (Epsmax - Epsmin) * (Ehat / Epsmax);
     dam = std::min(dam, 1.);
     K = Ehat;
   }
 
   sigma *= 1 - dam;
 }
diff --git a/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.cc b/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.cc
index 2b5046261..57af71a11 100644
--- a/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.cc
@@ -1,203 +1,203 @@
 /**
  * @file   material_iterative_stiffness_reduction.cc
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Thu Feb 18 16:03:56 2016
  *
  * @brief  Implementation of material iterative stiffness reduction
  *
  *
  * 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 "material_iterative_stiffness_reduction.hh"
 #include "communicator.hh"
 #include "solid_mechanics_model_RVE.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialIterativeStiffnessReduction<spatial_dimension>::
     MaterialIterativeStiffnessReduction(SolidMechanicsModel & model,
                                         const ID & id)
     : MaterialDamageIterative<spatial_dimension>(model, id),
       eps_u("ultimate_strain", *this), D("tangent", *this), Gf(0.),
       crack_band_width(0.), reduction_constant(0.) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("Gf", Gf, _pat_parsable | _pat_modifiable,
                       "fracture energy");
   this->registerParam("crack_band_width", crack_band_width,
                       _pat_parsable | _pat_modifiable, "crack_band_width");
   this->registerParam("reduction_constant", reduction_constant, 2.,
                       _pat_parsable | _pat_modifiable, "reduction constant");
 
   this->eps_u.initialize(1);
   this->D.initialize(1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIterativeStiffnessReduction<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   MaterialDamageIterative<spatial_dimension>::initMaterial();
 
   for (auto ghost_type : ghost_types) {
     /// loop over all types in the filter
     for (auto & el_type :
          this->element_filter.elementTypes(_ghost_type = ghost_type)) {
       /// get the stiffness on each quad point
       auto Sc_it = this->Sc(el_type, ghost_type).begin();
       /// get the tangent of the tensile softening on each quad point
       auto D_it = this->D(el_type, ghost_type).begin();
       auto D_end = this->D(el_type, ghost_type).end();
       /// get the ultimate strain on each quad
       auto eps_u_it = this->eps_u(el_type, ghost_type).begin();
       // compute the tangent and the ultimate strain for each quad
       for (; D_it != D_end; ++Sc_it, ++D_it, ++eps_u_it) {
         *eps_u_it = ((2. * this->Gf) / (*Sc_it * this->crack_band_width));
         *D_it = *(Sc_it) / ((*eps_u_it) - ((*Sc_it) / this->E));
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIterativeStiffnessReduction<spatial_dimension>::
     computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                       ElementType el_type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// storage for the current stress
   Matrix<Real> sigma(spatial_dimension, spatial_dimension);
   /// Vector to store eigenvalues of current stress tensor
   Vector<Real> eigenvalues(spatial_dimension);
 
   /// iterators on the needed internal fields
   auto Sc_it = this->Sc(el_type, ghost_type).begin();
   auto dam_it = this->damage(el_type, ghost_type).begin();
   auto equivalent_stress_it =
       this->equivalent_stress(el_type, ghost_type).begin();
   auto grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
   auto grad_u_end = grad_u.end(spatial_dimension, spatial_dimension);
 
   /// loop over all the quadrature points and compute the equivalent stress
   for (; grad_u_it != grad_u_end; ++grad_u_it) {
     /// compute the stress
     sigma.zero();
     MaterialElastic<spatial_dimension>::computeStressOnQuad(*grad_u_it, sigma,
                                                             0.);
     MaterialDamageIterative<spatial_dimension>::computeDamageAndStressOnQuad(
         sigma, *dam_it);
     /// compute eigenvalues
     sigma.eig(eigenvalues);
 
     /// find max eigenvalue and normalize by tensile strength
     *equivalent_stress_it =
         *(std::max_element(eigenvalues.storage(),
                            eigenvalues.storage() + spatial_dimension)) /
         (*Sc_it);
     ++Sc_it;
     ++equivalent_stress_it;
     ++dam_it;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 UInt MaterialIterativeStiffnessReduction<spatial_dimension>::updateDamage() {
   UInt nb_damaged_elements = 0;
 
   if (this->norm_max_equivalent_stress >= 1.) {
 
     AKANTU_DEBUG_IN();
 
     /// update the damage only on non-ghosts elements! Doesn't make sense to
     /// update on ghost.
     GhostType ghost_type = _not_ghost;
 
     /// loop over all the elements
     for (auto && el_type : this->model.getFEEngine().getMesh().elementTypes(
              spatial_dimension, ghost_type)) {
 
       /// get iterators on the needed internal fields
       auto equivalent_stress_it =
           this->equivalent_stress(el_type, ghost_type).begin();
       auto equivalent_stress_end =
           this->equivalent_stress(el_type, ghost_type).end();
       auto dam_it = this->damage(el_type, ghost_type).begin();
       auto reduction_it = this->reduction_step(el_type, ghost_type).begin();
       auto eps_u_it = this->eps_u(el_type, ghost_type).begin();
       auto Sc_it = this->Sc(el_type, ghost_type).begin();
       auto D_it = this->D(el_type, ghost_type).begin();
 
       /// loop over all the quads of the given element type
       for (; equivalent_stress_it != equivalent_stress_end;
            ++equivalent_stress_it, ++dam_it, ++reduction_it, ++eps_u_it,
            ++Sc_it, ++D_it) {
 
         /// check if damage occurs
         if (*equivalent_stress_it >=
             (1 - this->dam_tolerance) * this->norm_max_equivalent_stress) {
 
           /// check if this element can still be damaged
           if (*reduction_it == this->max_reductions)
             continue;
 
           /// increment the counter of stiffness reduction steps
           *reduction_it += 1;
           if (*reduction_it == this->max_reductions)
             *dam_it = this->max_damage;
           else {
             /// update the damage on this quad
             *dam_it =
                 1. - (1. / std::pow(this->reduction_constant, *reduction_it));
             /// update the stiffness on this quad
             *Sc_it = (*eps_u_it) * (1. - (*dam_it)) * this->E * (*D_it) /
                      ((1. - (*dam_it)) * this->E + (*D_it));
           }
           nb_damaged_elements += 1;
         }
       }
     }
   }
 
   auto rve_model = dynamic_cast<SolidMechanicsModelRVE *>(&this->model);
   if (rve_model == NULL) {
     const auto & comm = this->model.getMesh().getCommunicator();
     comm.allReduce(nb_damaged_elements, SynchronizerOperation::_sum);
   }
   AKANTU_DEBUG_OUT();
   return nb_damaged_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(iterative_stiffness_reduction,
                      MaterialIterativeStiffnessReduction);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.hh b/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.hh
index 0d8a00349..10435a4c7 100644
--- a/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_iterative_stiffness_reduction.hh
@@ -1,104 +1,104 @@
 /**
  * @file   material_iterative_stiffness_reduction.hh
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Thu Feb 18 15:25:05 2016
  *
  * @brief  Damage material with constant stiffness reduction
  *
  *
  * 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 "material_damage_iterative.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_MATERIAL_ITERATIVE_STIFFNESS_REDUCTION_HH_
 #define AKANTU_MATERIAL_ITERATIVE_STIFFNESS_REDUCTION_HH_
 
 namespace akantu {
 
 /**
  * Material damage iterative
  *
  * parameters in the material files :
  *   - Gfx
  *   - h
  *   - Sc
  */
 /// Proposed by Rots and Invernizzi, 2004: Regularized sequentially linear
 // saw-tooth softening model (section 4.2)
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialIterativeStiffnessReduction
     : public MaterialDamageIterative<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialIterativeStiffnessReduction(SolidMechanicsModel & model,
                                       const ID & id = "");
 
   virtual ~MaterialIterativeStiffnessReduction(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// init the material
   virtual void initMaterial();
 
   /// compute the equivalent stress on each Gauss point (i.e. the max prinicpal
   /// stress) and normalize it by the tensile stiffness
   virtual void
   computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                     ElementType el_type,
                                     GhostType ghost_type = _not_ghost);
 
   /// update internal field damage
   virtual UInt updateDamage();
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the ultimate strain
   InternalField<Real> eps_u;
 
   /// the tangent of the tensile stress-strain softening
   InternalField<Real> D;
 
   /// fracture energy
   Real Gf;
 
   /// crack_band_width for normalization of fracture energy
   Real crack_band_width;
 
   /// the reduction constant (denoated by a in the paper of rots)
   Real reduction_constant;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_ITERATIVE_STIFFNESS_REDUCTION_HH_ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.cc b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.cc
index c96f40708..c91227dc5 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.cc
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.cc
@@ -1,375 +1,375 @@
 /**
  * @file   material_damage_iterative.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date   Sun Mar  8 12:54:30 2015
  *
  * @brief  Specialization of the class material damage to damage only one gauss
  * point at a time and propagate damage in a linear way. Max principal stress
  * criterion is used as a failure criterion.
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_orthotropic_damage_iterative.hh"
 #include "communicator.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialOrthotropicDamageIterative<spatial_dimension>::
     MaterialOrthotropicDamageIterative(SolidMechanicsModel & model,
                                        const ID & id)
     : MaterialOrthotropicDamage<spatial_dimension>(model, id), Sc("Sc", *this),
       equivalent_stress("equivalent_stress", *this),
       stress_dir("equiv_stress_dir", *this), norm_max_equivalent_stress(0) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("Sc", Sc, _pat_parsable, "critical stress threshold");
   this->registerParam("prescribed_dam", prescribed_dam, 0.1,
                       _pat_parsable | _pat_modifiable,
                       "increase of damage in every step");
   this->registerParam(
       "dam_threshold", dam_threshold, 0.8, _pat_parsable | _pat_modifiable,
       "damage threshold at which damage damage will be set to 1");
 
   this->use_previous_stress = true;
   this->use_previous_gradu = true;
   this->Sc.initialize(1);
   this->equivalent_stress.initialize(1);
   this->stress_dir.initialize(spatial_dimension * spatial_dimension);
 
   /// the Gauss point with the highest stress can only be of type _not_ghost
   q_max.ghost_type = _not_ghost;
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialOrthotropicDamageIterative<spatial_dimension>::
     computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                       ElementType el_type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// Vector to store eigenvalues of current stress tensor
   Vector<Real> eigenvalues(spatial_dimension);
 
   auto Sc_it = Sc(el_type).begin();
   auto equivalent_stress_it = equivalent_stress(el_type).begin();
 
   Array<Real>::const_matrix_iterator grad_u_it =
       grad_u.begin(spatial_dimension, spatial_dimension);
   Array<Real>::const_matrix_iterator grad_u_end =
       grad_u.end(spatial_dimension, spatial_dimension);
 
   Array<Real>::matrix_iterator stress_dir_it =
       this->stress_dir(el_type).begin(spatial_dimension, spatial_dimension);
 
   /// initialize matrix to store the stress for the criterion (only different in
   /// non-local)
   Matrix<Real> sigma(spatial_dimension, spatial_dimension);
 
   Array<Real>::matrix_iterator damage_iterator =
       this->damage(el_type, ghost_type)
           .begin(this->spatial_dimension, this->spatial_dimension);
   Array<Real>::matrix_iterator damage_dir_it =
       this->damage_dir_vecs(el_type, ghost_type)
           .begin(this->spatial_dimension, this->spatial_dimension);
 
   /// for the computation of the Cauchy stress the matrices (1-D) and
   /// (1-D)^(1/2) are needed. For the formulation see Engineering
   /// Damage Mechanics by Lemaitre and Desmorat.
 
   Matrix<Real> one_minus_D(this->spatial_dimension, this->spatial_dimension);
   Matrix<Real> sqrt_one_minus_D(this->spatial_dimension,
                                 this->spatial_dimension);
   Matrix<Real> one_minus_D_rotated(this->spatial_dimension,
                                    this->spatial_dimension);
   Matrix<Real> sqrt_one_minus_D_rotated(this->spatial_dimension,
                                         this->spatial_dimension);
   Matrix<Real> rotation_tmp(this->spatial_dimension, this->spatial_dimension);
 
   /// create matrix to store the first term of the computation of the
   /// Cauchy stress
   Matrix<Real> first_term(this->spatial_dimension, this->spatial_dimension);
   Matrix<Real> third_term(this->spatial_dimension, this->spatial_dimension);
 
   for (; grad_u_it != grad_u_end;
        ++Sc_it, ++equivalent_stress_it, ++stress_dir_it, ++grad_u_it) {
     sigma.zero();
     MaterialOrthotropicDamage<spatial_dimension>::computeStressOnQuad(
         *grad_u_it, sigma, 0.);
 
     /// rotate the tensors from the damage principal coordinate system to the CS
     /// of the computation
     if (!(Math::are_float_equal((*damage_iterator).trace(), 0))) {
       /// compute (1-D) and (1-D)^1/2
       this->computeOneMinusD(one_minus_D, *damage_iterator);
       this->computeSqrtOneMinusD(one_minus_D, sqrt_one_minus_D);
 
       this->rotateIntoComputationFrame(one_minus_D, one_minus_D_rotated,
                                        *damage_dir_it, rotation_tmp);
 
       this->rotateIntoComputationFrame(sqrt_one_minus_D,
                                        sqrt_one_minus_D_rotated, *damage_dir_it,
                                        rotation_tmp);
     } else {
       this->computeOneMinusD(one_minus_D_rotated, *damage_iterator);
       this->computeSqrtOneMinusD(one_minus_D_rotated, sqrt_one_minus_D_rotated);
     }
 
     computeDamageAndStressOnQuad(sigma, one_minus_D_rotated,
                                  sqrt_one_minus_D_rotated, *damage_iterator,
                                  first_term, third_term);
 
     /// compute the maximum principal stresses and their directions
     sigma.eig(eigenvalues, *stress_dir_it);
     *equivalent_stress_it = eigenvalues(0) / *(Sc_it);
     ++damage_dir_it;
     ++damage_iterator;
   }
 
   // for(;sigma_it != sigma_end; ++sigma_it,
   // 	++Sc_it, ++equivalent_stress_it, ++stress_dir_it) {
   //   /// compute the maximum principal stresses and their directions
   //   (*sigma_it).eig(eigenvalues, *stress_dir_it);
   //   *equivalent_stress_it = eigenvalues(0) / *(Sc_it);
   // }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialOrthotropicDamageIterative<spatial_dimension>::computeAllStresses(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// reset normalized maximum equivalent stress
   if (ghost_type == _not_ghost)
     norm_max_equivalent_stress = 0;
 
   MaterialOrthotropicDamage<spatial_dimension>::computeAllStresses(ghost_type);
 
   /// find global Gauss point with highest stress
   this->model.getMesh().getCommunicator().allReduce(
       norm_max_equivalent_stress, SynchronizerOperation::_max);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialOrthotropicDamageIterative<spatial_dimension>::
     findMaxNormalizedEquivalentStress(ElementType el_type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if (ghost_type == _not_ghost) {
     /// initialize the iterators for the equivalent stress and the damage
     const Array<Real> & e_stress = equivalent_stress(el_type);
     auto equivalent_stress_it = e_stress.begin();
     auto equivalent_stress_end = e_stress.end();
     Array<Real> & dam = this->damage(el_type);
     auto dam_it = dam.begin(this->spatial_dimension, this->spatial_dimension);
     auto damage_directions_it =
         this->damage_dir_vecs(el_type, _not_ghost)
             .begin(this->spatial_dimension, this->spatial_dimension);
     auto stress_dir_it = this->stress_dir(el_type, _not_ghost)
                              .begin(spatial_dimension, spatial_dimension);
 
     /// initialize the matrices for damage rotation results
     Matrix<Real> tmp(spatial_dimension, spatial_dimension);
     Matrix<Real> dam_in_computation_frame(spatial_dimension, spatial_dimension);
     Matrix<Real> dam_in_stress_frame(spatial_dimension, spatial_dimension);
 
     for (; equivalent_stress_it != equivalent_stress_end;
          ++equivalent_stress_it, ++dam_it, ++damage_directions_it,
          ++stress_dir_it) {
       /// check if max equivalent stress for this element type is greater than
       /// the current norm_max_eq_stress
       if (*equivalent_stress_it > norm_max_equivalent_stress &&
           (spatial_dimension * this->max_damage - (*dam_it).trace() >
            Math::getTolerance())) {
 
         if (Math::are_float_equal((*dam_it).trace(), 0)) {
           /// gauss point has not been damaged yet
           norm_max_equivalent_stress = *equivalent_stress_it;
           q_max.type = el_type;
           q_max.global_num = equivalent_stress_it - e_stress.begin();
         }
 
         else {
           /// find the damage increment on this Gauss point
           /// rotate damage into stress frame
           this->rotateIntoComputationFrame(*dam_it, dam_in_computation_frame,
                                            *damage_directions_it, tmp);
           this->rotateIntoNewFrame(dam_in_computation_frame,
                                    dam_in_stress_frame, *stress_dir_it, tmp);
 
           /// add damage increment
           dam_in_stress_frame(0, 0) += prescribed_dam;
           /// find new principal directions of damage
           Vector<Real> dam_eigenvalues(spatial_dimension);
           dam_in_stress_frame.eig(dam_eigenvalues);
           bool limit_reached = false;
           for (UInt i = 0; i < spatial_dimension; ++i) {
             if (dam_eigenvalues(i) + Math::getTolerance() > this->max_damage)
               limit_reached = true;
           }
           if (!limit_reached) {
             norm_max_equivalent_stress = *equivalent_stress_it;
             q_max.type = el_type;
             q_max.global_num = equivalent_stress_it - e_stress.begin();
           }
         }
       } /// end if equiv_stress > max_equiv_stress
     }   /// end loop over all gauss points of this element type
   }     // end if(_not_ghost)
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialOrthotropicDamageIterative<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MaterialOrthotropicDamage<spatial_dimension>::computeStress(el_type,
                                                               ghost_type);
 
   auto damage_iterator =
       this->damage(el_type, ghost_type)
           .begin(this->spatial_dimension, this->spatial_dimension);
   auto damage_dir_it =
       this->damage_dir_vecs(el_type, ghost_type)
           .begin(this->spatial_dimension, this->spatial_dimension);
 
   /// for the computation of the Cauchy stress the matrices (1-D) and
   /// (1-D)^(1/2) are needed. For the formulation see Engineering
   /// Damage Mechanics by Lemaitre and Desmorat.
 
   Matrix<Real> one_minus_D(this->spatial_dimension, this->spatial_dimension);
   Matrix<Real> sqrt_one_minus_D(this->spatial_dimension,
                                 this->spatial_dimension);
   Matrix<Real> one_minus_D_rotated(this->spatial_dimension,
                                    this->spatial_dimension);
   Matrix<Real> sqrt_one_minus_D_rotated(this->spatial_dimension,
                                         this->spatial_dimension);
   Matrix<Real> rotation_tmp(this->spatial_dimension, this->spatial_dimension);
 
   /// create matrix to store the first term of the computation of the
   /// Cauchy stress
   Matrix<Real> first_term(this->spatial_dimension, this->spatial_dimension);
   Matrix<Real> third_term(this->spatial_dimension, this->spatial_dimension);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   /// rotate the tensors from the damage principal coordinate system to the CS
   /// of the computation
   if (!(Math::are_float_equal((*damage_iterator).trace(), 0))) {
     /// compute (1-D) and (1-D)^1/2
     this->computeOneMinusD(one_minus_D, *damage_iterator);
     this->computeSqrtOneMinusD(one_minus_D, sqrt_one_minus_D);
 
     this->rotateIntoComputationFrame(one_minus_D, one_minus_D_rotated,
                                      *damage_dir_it, rotation_tmp);
 
     this->rotateIntoComputationFrame(sqrt_one_minus_D, sqrt_one_minus_D_rotated,
                                      *damage_dir_it, rotation_tmp);
   } else {
     this->computeOneMinusD(one_minus_D_rotated, *damage_iterator);
     this->computeSqrtOneMinusD(one_minus_D_rotated, sqrt_one_minus_D_rotated);
   }
 
   computeDamageAndStressOnQuad(sigma, one_minus_D_rotated,
                                sqrt_one_minus_D_rotated, *damage_iterator,
                                first_term, third_term);
 
   ++damage_dir_it;
   ++damage_iterator;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   computeNormalizedEquivalentStress(this->gradu(el_type, ghost_type), el_type,
                                     ghost_type);
   norm_max_equivalent_stress = 0;
   findMaxNormalizedEquivalentStress(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 UInt MaterialOrthotropicDamageIterative<spatial_dimension>::updateDamage() {
   UInt nb_damaged_elements = 0;
   AKANTU_DEBUG_ASSERT(prescribed_dam > 0.,
                       "Your prescribed damage must be greater than zero");
 
   if (norm_max_equivalent_stress >= 1.) {
     AKANTU_DEBUG_IN();
     /// get the arrays and iterators for the element_type of the highest
     /// quadrature point
     ElementType el_type = q_max.type;
     UInt q_global_num = q_max.global_num;
     Array<Real> & dam = this->damage(el_type, _not_ghost);
     auto dam_it = dam.begin(this->spatial_dimension, this->spatial_dimension);
     auto damage_directions_it =
         this->damage_dir_vecs(el_type, _not_ghost)
             .begin(this->spatial_dimension, this->spatial_dimension);
     auto stress_dir_it = this->stress_dir(el_type, _not_ghost)
                              .begin(spatial_dimension, spatial_dimension);
 
     /// initialize the matrices for damage rotation results
     Matrix<Real> tmp(spatial_dimension, spatial_dimension);
     Matrix<Real> dam_in_computation_frame(spatial_dimension, spatial_dimension);
     Matrix<Real> dam_in_stress_frame(spatial_dimension, spatial_dimension);
 
     /// references to damage and directions of highest Gauss point
     Matrix<Real> q_dam = dam_it[q_global_num];
     Matrix<Real> q_dam_dir = damage_directions_it[q_global_num];
     Matrix<Real> q_stress_dir = stress_dir_it[q_global_num];
 
     /// increment damage
     /// find the damage increment on this Gauss point
     /// rotate damage into stress frame
     this->rotateIntoComputationFrame(q_dam, dam_in_computation_frame, q_dam_dir,
                                      tmp);
     this->rotateIntoNewFrame(dam_in_computation_frame, dam_in_stress_frame,
                              q_stress_dir, tmp);
 
     /// add damage increment
     dam_in_stress_frame(0, 0) += prescribed_dam;
     /// find new principal directions of damage
     Vector<Real> dam_eigenvalues(spatial_dimension);
     dam_in_stress_frame.eig(dam_eigenvalues, q_dam_dir);
     for (UInt i = 0; i < spatial_dimension; ++i) {
       q_dam(i, i) = dam_eigenvalues(i);
       if (q_dam(i, i) + Math::getTolerance() >= dam_threshold)
         q_dam(i, i) = this->max_damage;
     }
     nb_damaged_elements += 1;
   }
 
   this->model.getMesh().getCommunicator().allReduce(
       nb_damaged_elements, SynchronizerOperation::_sum);
   AKANTU_DEBUG_OUT();
   return nb_damaged_elements;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialOrthotropicDamageIterative<
     spatial_dimension>::updateEnergiesAfterDamage(ElementType el_type) {
   MaterialOrthotropicDamage<spatial_dimension>::updateEnergies(el_type);
 }
 
 /* -------------------------------------------------------------------------- */
 INSTANTIATE_MATERIAL(orthotropic_damage_iterative,
                      MaterialOrthotropicDamageIterative);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.hh b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.hh
index 8a54d3998..ec03ca85b 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative.hh
@@ -1,127 +1,127 @@
 /**
  * @file   material_orthtropic_damage_iterative.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date   Sun Mar  8 12:54:30 2015
  *
  * @brief Specialization of the class material orthotropic damage to
  * damage only one gauss point at a time and propagate damage in a
  * linear way. Max principal stress criterion is used as a failure
  * criterion.
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "material.hh"
 #include "material_orthotropic_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_ITERATIVE_HH_
 #define AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_ITERATIVE_HH_
 
 namespace akantu {
 
 /**
  * Material damage iterative
  *
  * parameters in the material files :
  *   - Sc
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialOrthotropicDamageIterative
     : public MaterialOrthotropicDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialOrthotropicDamageIterative(SolidMechanicsModel & model,
                                      const ID & id = "");
 
   virtual ~MaterialOrthotropicDamageIterative(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   ///  virtual void updateInternalParameters();
 
   virtual void computeAllStresses(GhostType ghost_type = _not_ghost);
 
   /// update internal field damage
   UInt updateDamage();
 
   /// update energies after damage has been updated
   virtual void updateEnergiesAfterDamage(ElementType el_type);
 
 protected:
   /// constitutive law for all element of a type
   virtual void computeStress(ElementType el_type,
                              GhostType ghost_type = _not_ghost);
 
   /// compute the equivalent stress on each Gauss point (i.e. the max prinicpal
   /// stress) and normalize it by the tensile strength
   void computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                          ElementType el_type,
                                          GhostType ghost_type = _not_ghost);
 
   /// find max normalized equivalent stress
   void findMaxNormalizedEquivalentStress(ElementType el_type,
                                          GhostType ghost_type = _not_ghost);
 
   inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma,
                                            Matrix<Real> & one_minus_D,
                                            Matrix<Real> & root_one_minus_D,
                                            Matrix<Real> & damage,
                                            Matrix<Real> & first_term,
                                            Matrix<Real> & third_term);
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get max normalized equivalent stress
   AKANTU_GET_MACRO(NormMaxEquivalentStress, norm_max_equivalent_stress, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// resistance to damage
   RandomInternalField<Real> Sc;
 
   /// internal field to store equivalent stress on each Gauss point
   InternalField<Real> equivalent_stress;
 
   /// internal field to store the direction of the current damage frame
   InternalField<Real> stress_dir;
 
   /// damage increment
   Real prescribed_dam;
 
   /// maximum equivalent stress
   Real norm_max_equivalent_stress;
 
   /// define damage threshold at which damage will be set to 1
   Real dam_threshold;
 
   /// quadrature point with highest equivalent Stress
   IntegrationPoint q_max;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_orthotropic_damage_iterative_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_ITERATIVE_HH_ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_inline_impl.hh b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_inline_impl.hh
index 0db4cc577..e35fb7c69 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_inline_impl.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_inline_impl.hh
@@ -1,69 +1,69 @@
 /**
  * @file   material_damage_iterative_inline_impl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date   Sun Mar  8 12:54:30 2015
  *
  * @brief  Implementation of inline functions of the material damage iterative
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialOrthotropicDamageIterative<spatial_dimension>::
     computeDamageAndStressOnQuad(Matrix<Real> & sigma,
                                  Matrix<Real> & one_minus_D,
                                  Matrix<Real> & sqrt_one_minus_D,
                                  Matrix<Real> & damage,
                                  Matrix<Real> & first_term,
                                  Matrix<Real> & third_term) {
 
   // Real dmax = *(std::max_element(damage.storage(), damage.storage() +
   // spatial_dimension*spatial_dimension) );
   Real eta_effective = 0;
 
   // if ( (1 - dmax*dmax)  < (1 - this->eta / spatial_dimension *
   // damage.trace()) ) {
 
   //   eta_effective = this->spatial_dimension * dmax * dmax / damage.trace();
 
   // }
   // else
   eta_effective = this->eta;
 
   /// hydrostatic sensitivity parameter
   // Real eta = 3.;
 
   /// Definition of Cauchy stress based on second order damage tensor:
   /// "Anisotropic damage modelling of biaxial behaviour and rupture
   /// of concrete strucutres", Ragueneau et al., 2008, Eq. 7
   first_term.mul<false, false>(sqrt_one_minus_D, sigma);
   first_term *= sqrt_one_minus_D;
 
   Real second_term = 0;
   for (UInt i = 0; i < this->spatial_dimension; ++i) {
     for (UInt j = 0; j < this->spatial_dimension; ++j)
       second_term += sigma(i, j) * one_minus_D(i, j);
   }
 
   second_term /= (this->spatial_dimension - damage.trace());
 
   // for (UInt i = 0; i < this->spatial_dimension; ++i) {
   //   for (UInt j = 0; j < this->spatial_dimension; ++j)
   //     one_minus_D(i,j) *= second_term;
   // }
   one_minus_D *= second_term;
 
   third_term.eye(
       1. / this->spatial_dimension * sigma.trace() *
       (1 - std::min(eta_effective / (this->spatial_dimension) * damage.trace(),
                     this->max_damage)));
 
   sigma.copy(first_term);
   sigma -= one_minus_D;
   sigma += third_term;
 }
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local.hh b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local.hh
index 0f3cd4585..6154b3f8f 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local.hh
@@ -1,84 +1,84 @@
 /**
  * @file   material_orthotropic_damage_iterative_non_local.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  MaterialOrthotropicDamageIterativeNonLocal header for non-local
  * damage
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "material_damage_non_local.hh"
 #include "material_orthotropic_damage_iterative.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_ITERATIVE_NON_LOCAL_HH_
 #define AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_ITERATIVE_NON_LOCAL_HH_
 
 namespace akantu {
 
 /**
  * Material Damage Iterative Non local
  *
  * parameters in the material files :
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialOrthotropicDamageIterativeNonLocal
     : public MaterialDamageNonLocal<
           spatial_dimension,
           MaterialOrthotropicDamageIterative<spatial_dimension>> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   typedef MaterialDamageNonLocal<
       spatial_dimension, MaterialOrthotropicDamageIterative<spatial_dimension>>
       MaterialOrthotropicDamageIterativeNonLocalParent;
   MaterialOrthotropicDamageIterativeNonLocal(SolidMechanicsModel & model,
                                              const ID & id = "");
 
   virtual ~MaterialOrthotropicDamageIterativeNonLocal(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial();
 
 protected:
   void computeStress(ElementType type, GhostType ghost_type);
 
   void computeNonLocalStress(ElementType type,
                              GhostType ghost_type = _not_ghost);
 
   /// associate the non-local variables of the material to their neighborhoods
   virtual void nonLocalVariableToNeighborhood();
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   InternalField<Real> grad_u_nl;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_orthotropic_damage_iterative_non_local_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_ORTHOTROPIC_DAMAGE_ITERATIVE_NON_LOCAL_HH_ */
diff --git a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local_inline_impl.hh b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local_inline_impl.hh
index 7e60ec245..f20fbdade 100644
--- a/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local_inline_impl.hh
+++ b/extra_packages/extra-materials/src/material_damage/material_orthotropic_damage_iterative_non_local_inline_impl.hh
@@ -1,140 +1,140 @@
 /**
  * @file   material_orthotropic_damage_iterative_non_local_inline_impl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief MaterialOrthotropicDamageIterativeNonLocal inline function
  * implementation
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #if defined(AKANTU_DEBUG_TOOLS)
 #include "aka_debug_tools.hh"
 #include <string>
 #endif
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialOrthotropicDamageIterativeNonLocal<spatial_dimension>::
     MaterialOrthotropicDamageIterativeNonLocal(SolidMechanicsModel & model,
                                                const ID & id)
     : Material(model, id),
       MaterialOrthotropicDamageIterativeNonLocalParent(model, id),
       grad_u_nl("grad_u non local", *this) {
   AKANTU_DEBUG_IN();
   this->is_non_local = true;
   this->grad_u_nl.initialize(spatial_dimension * spatial_dimension);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialOrthotropicDamageIterativeNonLocal<
     spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   this->model.getNonLocalManager().registerNonLocalVariable(
       this->gradu.getName(), grad_u_nl.getName(),
       spatial_dimension * spatial_dimension);
   MaterialOrthotropicDamageIterativeNonLocalParent::initMaterial();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialOrthotropicDamageIterativeNonLocal<
     spatial_dimension>::computeStress(ElementType type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialOrthotropicDamageIterativeNonLocal<
     spatial_dimension>::computeNonLocalStress(ElementType el_type,
                                               GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MaterialOrthotropicDamage<spatial_dimension>::computeStress(el_type,
                                                               ghost_type);
 
   Array<Real>::matrix_iterator damage_iterator =
       this->damage(el_type, ghost_type)
           .begin(this->spatial_dimension, this->spatial_dimension);
   Array<Real>::matrix_iterator damage_dir_it =
       this->damage_dir_vecs(el_type, ghost_type)
           .begin(this->spatial_dimension, this->spatial_dimension);
 
   /// for the computation of the Cauchy stress the matrices (1-D) and
   /// (1-D)^(1/2) are needed. For the formulation see Engineering
   /// Damage Mechanics by Lemaitre and Desmorat.
 
   Matrix<Real> one_minus_D(this->spatial_dimension, this->spatial_dimension);
   Matrix<Real> sqrt_one_minus_D(this->spatial_dimension,
                                 this->spatial_dimension);
   Matrix<Real> one_minus_D_rotated(this->spatial_dimension,
                                    this->spatial_dimension);
   Matrix<Real> sqrt_one_minus_D_rotated(this->spatial_dimension,
                                         this->spatial_dimension);
   Matrix<Real> rotation_tmp(this->spatial_dimension, this->spatial_dimension);
 
   /// create matrix to store the first term of the computation of the
   /// Cauchy stress
   Matrix<Real> first_term(this->spatial_dimension, this->spatial_dimension);
   Matrix<Real> third_term(this->spatial_dimension, this->spatial_dimension);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   /// rotate the tensors from the damage principal coordinate system to the CS
   /// of the computation
   if (!(Math::are_float_equal((*damage_iterator).trace(), 0))) {
     /// compute (1-D) and (1-D)^1/2
     this->computeOneMinusD(one_minus_D, *damage_iterator);
     this->computeSqrtOneMinusD(one_minus_D, sqrt_one_minus_D);
 
     this->rotateIntoComputationFrame(one_minus_D, one_minus_D_rotated,
                                      *damage_dir_it, rotation_tmp);
 
     this->rotateIntoComputationFrame(sqrt_one_minus_D, sqrt_one_minus_D_rotated,
                                      *damage_dir_it, rotation_tmp);
   } else {
     MaterialOrthotropicDamage<spatial_dimension>::computeOneMinusD(
         one_minus_D_rotated, *damage_iterator);
     MaterialOrthotropicDamage<spatial_dimension>::computeSqrtOneMinusD(
         one_minus_D_rotated, sqrt_one_minus_D_rotated);
   }
 
   this->computeDamageAndStressOnQuad(sigma, one_minus_D_rotated,
                                      sqrt_one_minus_D_rotated, *damage_iterator,
                                      first_term, third_term);
 
   ++damage_dir_it;
   ++damage_iterator;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   this->computeNormalizedEquivalentStress(this->grad_u_nl(el_type, ghost_type),
                                           el_type, ghost_type);
   this->norm_max_equivalent_stress = 0;
   this->findMaxNormalizedEquivalentStress(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialOrthotropicDamageIterativeNonLocal<
     spatial_dimension>::nonLocalVariableToNeighborhood() {
   this->model.getNonLocalManager().nonLocalVariableToNeighborhood(
       grad_u_nl.getName(), this->name);
 }
diff --git a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.cc b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.cc
index 1068fa7a4..5e8cb79ee 100644
--- a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.cc
+++ b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.cc
@@ -1,107 +1,107 @@
 /**
  * @file   material_viscoplastic.cc
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  *
  *
  * @brief  Specialization of the material class for isotropic viscoplastic
  * (small deformation)
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "material_viscoplastic.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialViscoPlastic<dim>::MaterialViscoPlastic(SolidMechanicsModel & model,
                                                 const ID & id)
     : MaterialPlastic<dim>(model, id) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("rate", rate, 0., _pat_parsable | _pat_modifiable,
                       "Rate sensitivity component");
   this->registerParam("edot0", edot0, 0., _pat_parsable | _pat_modifiable,
                       "Reference strain rate");
   this->registerParam("ts", ts, 0., _pat_parsable | _pat_modifiable,
                       "Time Step");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialViscoPlastic<dim>::computeStress(ElementType el_type,
                                               GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * iso_hardening = this->iso_hardening(el_type, ghost_type).storage();
 
   auto previous_grad_u_it =
       this->gradu.previous(el_type, ghost_type).begin(dim, dim);
 
   auto previous_sigma_it =
       this->stress.previous(el_type, ghost_type).begin(dim, dim);
 
   auto inelastic_strain_it =
       this->inelastic_strain(el_type, ghost_type).begin(dim, dim);
 
   auto previous_inelastic_strain_it =
       this->inelastic_strain.previous(el_type, ghost_type).begin(dim, dim);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   computeStressOnQuad(grad_u, *previous_grad_u_it, sigma, *previous_sigma_it,
                       *inelastic_strain_it, *previous_inelastic_strain_it,
                       *iso_hardening);
 
   ++inelastic_strain_it;
   ++iso_hardening;
   ++previous_grad_u_it;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialViscoPlastic<dim>::computeTangentModuli(
     __attribute__((unused)) ElementType el_type,
     Array<Real> & tangent_matrix,
     __attribute__((unused)) GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto previous_sigma_it =
       this->stress.previous(el_type, ghost_type).begin(dim, dim);
 
   auto previous_strain_it =
       this->gradu.previous(el_type, ghost_type).begin(dim, dim);
 
   Real * iso_hardening = this->iso_hardening(el_type, ghost_type).storage();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
 
   Matrix<Real> & previous_grad_u = *previous_strain_it;
   Matrix<Real> & previous_sigma_tensor = *previous_sigma_it;
 
   computeTangentModuliOnQuad(tangent, grad_u, previous_grad_u, sigma,
                              previous_sigma_tensor, *iso_hardening);
   ++previous_sigma_it;
   ++previous_strain_it;
   ++iso_hardening;
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 INSTANTIATE_MATERIAL(visco_plastic, MaterialViscoPlastic);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.hh b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.hh
index eabfd8768..7be9f5195 100644
--- a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.hh
+++ b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic.hh
@@ -1,99 +1,99 @@
 /**
  * @file   material_viscoplastic.hh
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  *
  *
  * @brief  Specialization of the material class for
  * MaterialLinearIsotropicHardening to include viscous effects (small
  * deformation)
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_voigthelper.hh"
 #include "material_plastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_VISCOPLASTIC_HH_
 #define AKANTU_MATERIAL_VISCOPLASTIC_HH_
 
 namespace akantu {
 
 /**
  * Material plastic isotropic
  *
  * parameters in the material files :
  *   - h : Hardening parameter (default: 0)
  *   - sigmay : Yield stress
  *   - rate : Rate sensitivity
  *   - edot0 : Reference strain rate
  *
  *   - ts: Time step
  */
 
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialViscoPlastic : public MaterialPlastic<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialViscoPlastic(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// constitutive law for all element of a type
   virtual void computeStress(ElementType el_type,
                              GhostType ghost_type = _not_ghost);
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(ElementType el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost);
 
 protected:
   inline void
   computeStressOnQuad(const Matrix<Real> & grad_u,
                       const Matrix<Real> & previous_grad_u,
                       Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
                       Matrix<Real> & inelastic_strain,
                       const Matrix<Real> & previous_inelastic_strain,
                       Real & iso_hardening) const;
 
   inline void computeTangentModuliOnQuad(
       Matrix<Real> & tangent, const Matrix<Real> & grad_u,
       const Matrix<Real> & previous_grad_u, const Matrix<Real> & sigma_tensor,
       const Matrix<Real> & previous_sigma_tensor,
       const Real & iso_hardening) const;
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// Rate sensitivity component (rate)
   Real rate;
 
   /// Reference strain rate (edot0)
   Real edot0;
 
   /// Time step (ts)
   Real ts;
 };
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "material_viscoplastic_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_VISCOPLASTIC_HH_ */
diff --git a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic_inline_impl.hh b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic_inline_impl.hh
index c149c9531..3a67284b7 100644
--- a/extra_packages/extra-materials/src/material_plastic/material_viscoplastic_inline_impl.hh
+++ b/extra_packages/extra-materials/src/material_plastic/material_viscoplastic_inline_impl.hh
@@ -1,89 +1,89 @@
 /**
  * @file   material_viscoplastic_inline_impl.hh
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  *
  *
  * @brief  Implementation of the inline functions of the material viscoplastic
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 #include "material_viscoplastic.hh"
 #include <cmath>
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialViscoPlastic<dim>::computeStressOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
     Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
     Matrix<Real> & inelastic_strain,
     const Matrix<Real> & previous_inelastic_strain,
     Real & iso_hardening) const {
   // Infinitesimal plastic
   // Compute stress magnitude
   Real s = sigma.doubleDot(sigma);
   Real sigma_mag = sqrt(s);
 
   // Compute plastic strain increment
   Real factor = (this->ts * this->edot0 * pow(sigma_mag, (this->rate - 1.)) /
                  pow(this->sigma_y + iso_hardening, this->rate));
 
   Matrix<Real> delta_inelastic_strain(sigma);
   delta_inelastic_strain *= factor;
 
   // Compute plastic strain increment magnitude
   s = delta_inelastic_strain.doubleDot(delta_inelastic_strain);
   Real dep_mag = std::sqrt(s);
 
   Matrix<Real> grad_delta_u(grad_u);
   grad_delta_u -= previous_grad_u;
 
   // Update stress and plastic strain
   Matrix<Real> grad_u_elastic(dim, dim);
   grad_u_elastic = grad_delta_u;
   grad_u_elastic -= delta_inelastic_strain;
 
   Matrix<Real> sigma_elastic(dim, dim);
   MaterialElastic<dim>::computeStressOnQuad(grad_u_elastic, sigma_elastic);
   sigma += sigma_elastic;
 
   inelastic_strain += delta_inelastic_strain;
 
   // Update resistance stress
   iso_hardening = iso_hardening + this->h * dep_mag;
 
   MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
       grad_delta_u, sigma, previous_sigma, inelastic_strain,
       previous_inelastic_strain, delta_inelastic_strain);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialViscoPlastic<dim>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent, const Matrix<Real> & /*grad_u*/,
     const Matrix<Real> & /*previous_grad_u*/,
     const Matrix<Real> & /*sigma_tensor*/,
     const Matrix<Real> & /*previous_sigma_tensor*/,
     const Real & /*iso_hardening*/) const {
   UInt cols = tangent.cols();
   UInt rows = tangent.rows();
 
   for (UInt m = 0; m < rows; ++m) {
     UInt i = VoigtHelper<dim>::vec[m][0];
     UInt j = VoigtHelper<dim>::vec[m][1];
 
     for (UInt n = 0; n < cols; ++n) {
       UInt k = VoigtHelper<dim>::vec[n][0];
       UInt l = VoigtHelper<dim>::vec[n][1];
       tangent(m, n) = (i == k) * (j == l) * 2. * this->mu +
                       (i == j) * (k == l) * this->lambda;
       tangent(m, n) -= (m == n) * (m >= dim) * this->mu;
     }
   }
 }
diff --git a/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.cc b/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.cc
index 2bdf201b2..d6ddc6d49 100644
--- a/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.cc
+++ b/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.cc
@@ -1,121 +1,121 @@
 /**
  * @file   material_stiffness_proportional.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  *
  * @brief  Special. of the material class for the caughey viscoelastic material
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_stiffness_proportional.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialStiffnessProportional<spatial_dimension>::MaterialStiffnessProportional(
     SolidMechanicsModel & model, const ID & id)
     : MaterialElastic<spatial_dimension>(model, id),
       stress_viscosity("stress_viscosity", *this),
       stress_elastic("stress_elastic", *this) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("Alpha", alpha, 0., _pat_parsable | _pat_modifiable,
                       "Artificial viscous ratio");
 
   this->stress_viscosity.initialize(spatial_dimension * spatial_dimension);
   this->stress_elastic.initialize(spatial_dimension * spatial_dimension);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialStiffnessProportional<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   MaterialElastic<spatial_dimension>::initMaterial();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialStiffnessProportional<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   Array<UInt> & elem_filter = this->element_filter(el_type, ghost_type);
   Array<Real> & stress_visc = stress_viscosity(el_type, ghost_type);
   Array<Real> & stress_el = stress_elastic(el_type, ghost_type);
 
   MaterialElastic<spatial_dimension>::computeStress(el_type, ghost_type);
 
   Array<Real> & velocity = this->model.getVelocity();
 
   Array<Real> strain_rate(0, spatial_dimension * spatial_dimension,
                           "strain_rate");
 
   this->model.getFEEngine().gradientOnIntegrationPoints(
       velocity, strain_rate, spatial_dimension, el_type, ghost_type,
       elem_filter);
 
   Array<Real>::matrix_iterator strain_rate_it =
       strain_rate.begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator stress_visc_it =
       stress_visc.begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator stress_el_it =
       stress_el.begin(spatial_dimension, spatial_dimension);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   Matrix<Real> & grad_v = *strain_rate_it;
   Matrix<Real> & sigma_visc = *stress_visc_it;
   Matrix<Real> & sigma_el = *stress_el_it;
 
   MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_v, sigma_visc);
 
   sigma_visc *= alpha;
   sigma_el.copy(sigma);
   sigma += sigma_visc;
 
   ++strain_rate_it;
   ++stress_visc_it;
   ++stress_el_it;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialStiffnessProportional<spatial_dimension>::computePotentialEnergy(
     ElementType el_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & stress_el = stress_elastic(el_type);
   Array<Real>::matrix_iterator stress_el_it =
       stress_el.begin(spatial_dimension, spatial_dimension);
 
   Real * epot = this->potential_energy(el_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
   Matrix<Real> & sigma_el = *stress_el_it;
   MaterialElastic<spatial_dimension>::computePotentialEnergyOnQuad(
       grad_u, sigma_el, *epot);
   epot++;
   ++stress_el_it;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 INSTANTIATE_MATERIAL(ve_stiffness_prop, MaterialStiffnessProportional);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.hh b/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.hh
index dbb3bac45..97e13223f 100644
--- a/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.hh
+++ b/extra_packages/extra-materials/src/material_viscoelastic/material_stiffness_proportional.hh
@@ -1,98 +1,98 @@
 /**
  * @file   material_stiffness_proportional.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  *
  * @brief  Material isotropic visco-elastic with viscosity proportional to the
  * stiffness
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "material.hh"
 #include "material_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_STIFFNESS_PROPORTIONAL_HH_
 #define AKANTU_MATERIAL_STIFFNESS_PROPORTIONAL_HH_
 
 namespace akantu {
 
 /**
  * Material visco-elastic @f[\sigma = E\epsilon + \alpha E*
  * \frac{d\epsilon}{dt}@f]
  * it can be seen as a Kelvin-Voigt solid with @f[\eta = \alpha E @f]
  *
  * The material satisfies the Caughey condition, the visco-elastic solid has the
  * same eigen-modes as the elastic one. (T.K. Caughey 1960 - Journal of Applied
  * Mechanics 27, 269-271. Classical normal modes in damped linear systems.)
  *
  * parameters in the material files :
  *   - rho : density (default: 0)
  *   - E   : Young's modulus (default: 0)
  *   - nu  : Poisson's ratio (default: 1/2)
  *   - Plane_Stress : if 0: plane strain, else: plane stress (default: 0)
  *   - alpha : viscous ratio
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialStiffnessProportional
     : public MaterialElastic<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialStiffnessProportional(SolidMechanicsModel & model,
                                 const ID & id = "");
 
   virtual ~MaterialStiffnessProportional(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost) override;
 
   /// compute the potential energy for all elements
   void computePotentialEnergy(ElementType el_type) override;
 
 protected:
   /// constitutive law for a given quadrature point
   // inline void computeStress(Real * F, Real * sigma);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// stress due to viscosity
   InternalField<Real> stress_viscosity;
 
   /// stress due to elasticity
   InternalField<Real> stress_elastic;
 
   /// viscous ratio
   Real alpha;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 //#include "material_elastic_caughey_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_STIFFNESS_PROPORTIONAL_HH_ */
diff --git a/extra_packages/igfem/src/fe_engine_template_tmpl_igfem.hh b/extra_packages/igfem/src/fe_engine_template_tmpl_igfem.hh
index 3fe2d31a8..78a9392c6 100644
--- a/extra_packages/igfem/src/fe_engine_template_tmpl_igfem.hh
+++ b/extra_packages/igfem/src/fe_engine_template_tmpl_igfem.hh
@@ -1,117 +1,117 @@
 /**
  * @file   shape_igfem_inline_impl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @brief  ShapeIGFEM inline implementation
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "integrator_gauss_igfem.hh"
 #include "shape_igfem.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_FE_ENGINE_TEMPLATE_TMPL_IGFEM_HH_
 #define AKANTU_FE_ENGINE_TEMPLATE_TMPL_IGFEM_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* compatibility functions */
 /* -------------------------------------------------------------------------- */
 
 template <>
 inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem,
                              DefaultIntegrationOrderFunctor>::
     initShapeFunctions(const Array<Real> & nodes,
                        GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh::type_iterator it =
       mesh.firstType(element_dimension, ghost_type, _ek_igfem);
   Mesh::type_iterator end =
       mesh.lastType(element_dimension, ghost_type, _ek_igfem);
   for (; it != end; ++it) {
     ElementType type = *it;
     integrator.initIntegrator(nodes, type, ghost_type);
 
 #define INIT(_type)                                                            \
   do {                                                                         \
     const Matrix<Real> & all_quads =                                           \
         integrator.getIntegrationPoints<_type>(ghost_type);                    \
     const Matrix<Real> & quads_1 = integrator.getIntegrationPoints<            \
         ElementClassProperty<_type>::sub_element_type_1>(ghost_type);          \
     const Matrix<Real> & quads_2 = integrator.getIntegrationPoints<            \
         ElementClassProperty<_type>::sub_element_type_2>(ghost_type);          \
     shape_functions.initShapeFunctions(nodes, all_quads, quads_1, quads_2,     \
                                        _type, ghost_type);                     \
   } while (0)
 
     AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(INIT);
 #undef INIT
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem,
                              DefaultIntegrationOrderFunctor>::
     computeIntegrationPointsCoordinates(
         Array<Real> & quadrature_points_coordinates, ElementType type,
         GhostType ghost_type,
-        const Array<UInt> & filter_elements) const {
+        const Array<Int> & filter_elements) const {
 
   const Array<Real> & nodes_coordinates = mesh.getNodes();
   UInt spatial_dimension = mesh.getSpatialDimension();
   /// create an array with the nodal coordinates that need to be
   /// interpolated. The nodal coordinates of the enriched nodes need
   /// to be set to zero, because they represent the enrichment of the
   /// position field, and the enrichments for this field are all zero!
   /// There is no gap in the mesh!
   Array<Real> igfem_nodes(nodes_coordinates.getSize(), spatial_dimension);
   shape_functions.extractValuesAtStandardNodes(nodes_coordinates, igfem_nodes,
                                                ghost_type);
 
   interpolateOnIntegrationPoints(igfem_nodes, quadrature_points_coordinates,
                                  spatial_dimension, type, ghost_type,
                                  filter_elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_igfem,
                              DefaultIntegrationOrderFunctor>::
     computeIntegrationPointsCoordinates(
         ElementTypeMapArray<Real> & quadrature_points_coordinates,
         const ElementTypeMapArray<UInt> * filter_elements) const {
 
   const Array<Real> & nodes_coordinates = mesh.getNodes();
   UInt spatial_dimension = mesh.getSpatialDimension();
   /// create an array with the nodal coordinates that need to be
   /// interpolated. The nodal coordinates of the enriched nodes need
   /// to be set to zero, because they represent the enrichment of the
   /// position field, and the enrichments for this field are all zero!
   /// There is no gap in the mesh!
   Array<Real> igfem_nodes(nodes_coordinates.getSize(), spatial_dimension);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
     shape_functions.extractValuesAtStandardNodes(nodes_coordinates, igfem_nodes,
                                                  ghost_type);
   }
 
   interpolateOnIntegrationPoints(igfem_nodes, quadrature_points_coordinates,
                                  filter_elements);
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_FE_ENGINE_TEMPLATE_TMPL_IGFEM_HH_ */
diff --git a/extra_packages/igfem/src/integrator_gauss_igfem.hh b/extra_packages/igfem/src/integrator_gauss_igfem.hh
index c32092989..24b95e9e0 100644
--- a/extra_packages/igfem/src/integrator_gauss_igfem.hh
+++ b/extra_packages/igfem/src/integrator_gauss_igfem.hh
@@ -1,123 +1,123 @@
 /**
  * @file   integrator_gauss_igfem.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Gauss integration facilities for IGFEM
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_INTEGRATOR_IGFEM_HH_
 #define AKANTU_INTEGRATOR_IGFEM_HH_
 
 /* -------------------------------------------------------------------------- */
 #include "integrator.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 template <class IOF> class IntegratorGauss<_ek_igfem, IOF> : public Integrator {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   IntegratorGauss(const Mesh & mesh, const ID & id = "integrator_gauss");
 
   virtual ~IntegratorGauss(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   inline void initIntegrator(const Array<Real> & nodes,
                              ElementType type,
                              GhostType ghost_type);
 
   /// precompute jacobians on elements of type "type"
   template <ElementType type>
   void precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
                                              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, UInt elem,
                                  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, GhostType ghost_type,
-                 const Array<UInt> & filter_elements) const;
+                 const Array<Int> & filter_elements) const;
 
   /// integrate one element scalar value on all elements of type "type"
   template <ElementType type>
   Real integrate(const Vector<Real> & in_f, UInt index,
                  GhostType ghost_type) const;
 
   /// integrate scalar field in_f
   template <ElementType type>
   Real integrate(const Array<Real> & in_f, GhostType ghost_type,
-                 const Array<UInt> & filter_elements) const;
+                 const Array<Int> & filter_elements) 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,
                                     GhostType ghost_type,
-                                    const Array<UInt> & filter_elements) const;
+                                    const Array<Int> & filter_elements) const;
   /// return a vector with quadrature points natural coordinates
   template <ElementType type>
   const Matrix<Real> & getIntegrationPoints(GhostType ghost_type) const;
 
   /// return the number of quadrature points for a given element type
   template <ElementType type>
   inline UInt
   getNbIntegrationPoints(GhostType ghost_type = _not_ghost) const;
 
   /// compute the vector of quadrature points natural coordinates
   template <ElementType type>
   void computeQuadraturePoints(GhostType ghost_type);
 
   /// check that the jacobians are not negative
   template <ElementType type>
   void checkJacobians(GhostType ghost_type) const;
 
 public:
   /// compute the jacobians on quad points for a given element
   template <ElementType type>
   void computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
                                             Vector<Real> & jacobians);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   inline void integrate(Real * f, Real * jac, Real * inte,
                         UInt nb_degree_of_freedom,
                         UInt nb_quadrature_points) const;
 
 private:
   ElementTypeMap<Matrix<Real>> quadrature_points;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "integrator_gauss_igfem_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /*AKANTU_INTEGRATOR_IGFEM_HH_ */
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
diff --git a/extra_packages/igfem/src/integrator_gauss_igfem_inline_impl.hh b/extra_packages/igfem/src/integrator_gauss_igfem_inline_impl.hh
index 376ccba79..8dd2e5583 100644
--- a/extra_packages/igfem/src/integrator_gauss_igfem_inline_impl.hh
+++ b/extra_packages/igfem/src/integrator_gauss_igfem_inline_impl.hh
@@ -1,451 +1,451 @@
 /**
  * @file   integrator_gauss_igfem.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Inline functions of gauss integrator for the case of IGFEM
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #include "fe_engine.hh"
 #if defined(AKANTU_DEBUG_TOOLS)
 #include "aka_debug_tools.hh"
 #endif
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 #define INIT_INTEGRATOR(type)                                                  \
   computeQuadraturePoints<type>(ghost_type);                                   \
   precomputeJacobiansOnQuadraturePoints<type>(nodes, ghost_type);              \
   checkJacobians<type>(ghost_type);
 
 template <class IOF>
 inline void
 IntegratorGauss<_ek_igfem, IOF>::initIntegrator(const Array<Real> & nodes,
                                                 ElementType type,
                                                 GhostType ghost_type) {
   AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(INIT_INTEGRATOR);
 }
 
 #undef INIT_INTEGRATOR
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline UInt IntegratorGauss<_ek_igfem, IOF>::getNbIntegrationPoints(
     GhostType) const {
   const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
   const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
   UInt nb_quad_points_sub_1 =
       GaussIntegrationElement<sub_type_1>::getNbQuadraturePoints();
   UInt nb_quad_points_sub_2 =
       GaussIntegrationElement<sub_type_2>::getNbQuadraturePoints();
   return (nb_quad_points_sub_1 + nb_quad_points_sub_2);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline void IntegratorGauss<_ek_igfem, IOF>::integrateOnElement(
     const Array<Real> & f, Real * intf, UInt nb_degree_of_freedom,
     const UInt elem, GhostType ghost_type) const {
 
   Array<Real> & jac_loc = jacobians(type, ghost_type);
 
   UInt nb_quadrature_points = getNbIntegrationPoints<type>();
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
                       "The vector f do not have the good number of component.");
 
   Real * f_val = f.storage() + elem * f.getNbComponent();
   Real * jac_val = jac_loc.storage() + elem * nb_quadrature_points;
 
   integrate(f_val, jac_val, intf, nb_degree_of_freedom, nb_quadrature_points);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline Real IntegratorGauss<_ek_igfem, IOF>::integrate(
     const Vector<Real> & in_f, UInt index, GhostType ghost_type) const {
   const Array<Real> & jac_loc = jacobians(type, ghost_type);
 
   UInt nb_quadrature_points = getNbIntegrationPoints<type>();
   AKANTU_DEBUG_ASSERT(in_f.size() == nb_quadrature_points,
                       "The vector f do not have nb_quadrature_points entries.");
 
   Real * jac_val = jac_loc.storage() + index * nb_quadrature_points;
   Real intf;
 
   integrate(in_f.storage(), jac_val, &intf, 1, nb_quadrature_points);
 
   return intf;
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 inline void
 IntegratorGauss<_ek_igfem, IOF>::integrate(Real * f, Real * jac, Real * inte,
                                            UInt nb_degree_of_freedom,
                                            UInt nb_quadrature_points) const {
   memset(inte, 0, nb_degree_of_freedom * sizeof(Real));
 
   Real * cjac = jac;
   for (UInt q = 0; q < nb_quadrature_points; ++q) {
     for (UInt dof = 0; dof < nb_degree_of_freedom; ++dof) {
       inte[dof] += *f * *cjac;
       ++f;
     }
     ++cjac;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline const Matrix<Real> &
 IntegratorGauss<_ek_igfem, IOF>::getIntegrationPoints(
     GhostType ghost_type) const {
   AKANTU_DEBUG_ASSERT(
       quadrature_points.exists(type, ghost_type),
       "Quadrature points for type "
           << quadrature_points.printType(type, ghost_type)
           << " have not been initialized."
           << " Did you use 'computeQuadraturePoints' function ?");
   return quadrature_points(type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline void IntegratorGauss<_ek_igfem, IOF>::computeQuadraturePoints(
     GhostType ghost_type) {
   /// typedef for the two subelement_types and the parent element type
   const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
   const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
 
   /// store the quadrature points on the two subelements
   Matrix<Real> & quads_sub_1 = quadrature_points(sub_type_1, ghost_type);
   Matrix<Real> & quads_sub_2 = quadrature_points(sub_type_2, ghost_type);
   quads_sub_1 = GaussIntegrationElement<sub_type_1>::getQuadraturePoints();
   quads_sub_2 = GaussIntegrationElement<sub_type_2>::getQuadraturePoints();
 
   /// store all quad points for the current type
   UInt nb_quad_points_sub_1 =
       GaussIntegrationElement<sub_type_1>::getNbQuadraturePoints();
   UInt nb_quad_points_sub_2 =
       GaussIntegrationElement<sub_type_2>::getNbQuadraturePoints();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   Matrix<Real> & quads = quadrature_points(type, ghost_type);
   quads = Matrix<Real>(spatial_dimension,
                        nb_quad_points_sub_1 + nb_quad_points_sub_2);
 
   Matrix<Real> quads_1(quads.storage(), quads.rows(), nb_quad_points_sub_1);
   quads_1 = quads_sub_1;
 
   Matrix<Real> quads_2(quads.storage() + quads.rows() * nb_quad_points_sub_1,
                        quads.rows(), nb_quad_points_sub_2);
 
   quads_2 = quads_sub_2;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline void
 IntegratorGauss<_ek_igfem, IOF>::computeJacobianOnQuadPointsByElement(
     const Matrix<Real> & node_coords, Vector<Real> & jacobians) {
 
   /// optimize: get the matrix from the ElementTypeMap
   Matrix<Real> quad = GaussIntegrationElement<type>::getQuadraturePoints();
   // jacobian
   ElementClass<type>::computeJacobian(quad, node_coords, jacobians);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 inline IntegratorGauss<_ek_igfem, IOF>::IntegratorGauss(
     const Mesh & mesh, const ID & id)
     : Integrator(mesh, id) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline void IntegratorGauss<_ek_igfem, IOF>::checkJacobians(
     GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
   /// typedef for the two subelement_types and the parent element type
   const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
   const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
   UInt nb_quad_points_sub_1 =
       GaussIntegrationElement<sub_type_1>::getNbQuadraturePoints();
   UInt nb_quad_points_sub_2 =
       GaussIntegrationElement<sub_type_2>::getNbQuadraturePoints();
   UInt nb_quadrature_points = nb_quad_points_sub_1 + nb_quad_points_sub_2;
 
   UInt nb_element;
 
   nb_element = mesh.getConnectivity(type, ghost_type).getSize();
 
   Real * jacobians_val = jacobians(type, ghost_type).storage();
 
   for (UInt i = 0; i < nb_element * nb_quadrature_points;
        ++i, ++jacobians_val) {
     if (*jacobians_val < 0)
       AKANTU_ERROR(
           "Negative jacobian computed,"
           << " possible problem in the element node ordering (Quadrature Point "
           << i % nb_quadrature_points << ":" << i / nb_quadrature_points << ":"
           << type << ":" << ghost_type << ")");
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline void
 IntegratorGauss<_ek_igfem, IOF>::precomputeJacobiansOnQuadraturePoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// typedef for the two subelement_types and the parent element type
   const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
   const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   /// get the number of nodes for the subelements and the parent element
   UInt nb_nodes_sub_1 =
       ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
   UInt nb_nodes_sub_2 =
       ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
   UInt nb_quadrature_points_sub_1 =
       GaussIntegrationElement<sub_type_1>::getNbQuadraturePoints();
   UInt nb_quadrature_points_sub_2 =
       GaussIntegrationElement<sub_type_2>::getNbQuadraturePoints();
   UInt nb_quadrature_points =
       nb_quadrature_points_sub_1 + nb_quadrature_points_sub_2;
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
 
   Array<Real> * jacobians_tmp;
   if (!jacobians.exists(type, ghost_type))
     jacobians_tmp = &jacobians.alloc(nb_element * nb_quadrature_points, 1, type,
                                      ghost_type);
   else {
     jacobians_tmp = &jacobians(type, ghost_type);
     jacobians_tmp->resize(nb_element * nb_quadrature_points);
   }
 
   Array<Real>::vector_iterator jacobians_it =
       jacobians_tmp->begin_reinterpret(nb_quadrature_points, nb_element);
 
   Vector<Real> weights_sub_1 =
       GaussIntegrationElement<sub_type_1>::getWeights();
   Vector<Real> weights_sub_2 =
       GaussIntegrationElement<sub_type_2>::getWeights();
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
 
   Array<Real>::const_matrix_iterator x_it =
       x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   //  Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
   for (UInt elem = 0; elem < nb_element; ++elem, ++jacobians_it, ++x_it) {
     const Matrix<Real> & X = *x_it;
 
     Matrix<Real> sub_1_coords(spatial_dimension, nb_nodes_sub_1);
     Matrix<Real> sub_2_coords(spatial_dimension, nb_nodes_sub_2);
 
     ElementClass<type>::getSubElementCoords(X, sub_1_coords, 0);
     ElementClass<type>::getSubElementCoords(X, sub_2_coords, 1);
 
     Vector<Real> & J = *jacobians_it;
     /// initialize vectors to store the jacobians for each subelement
     Vector<Real> J_sub_1(nb_quadrature_points_sub_1);
     Vector<Real> J_sub_2(nb_quadrature_points_sub_2);
     computeJacobianOnQuadPointsByElement<sub_type_1>(sub_1_coords, J_sub_1);
     computeJacobianOnQuadPointsByElement<sub_type_2>(sub_2_coords, J_sub_2);
     J_sub_1 *= weights_sub_1;
     J_sub_2 *= weights_sub_2;
 
     /// copy results into the jacobian vector for this element
     for (UInt i = 0; i < nb_quadrature_points_sub_1; ++i) {
       J(i) = J_sub_1(i);
     }
 
     for (UInt i = 0; i < nb_quadrature_points_sub_2; ++i) {
       J(i + nb_quadrature_points_sub_1) = J_sub_2(i);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline void IntegratorGauss<_ek_igfem, IOF>::integrate(
     const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    GhostType ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
                       "No jacobians for the type "
                           << jacobians.printType(type, ghost_type));
 
   const Matrix<Real> & quads = quadrature_points(type, ghost_type);
 
   UInt nb_points = quads.cols();
 
   const Array<Real> & jac_loc = jacobians(type, ghost_type);
 
   Array<Real>::const_matrix_iterator J_it;
   Array<Real>::matrix_iterator inte_it;
   Array<Real>::const_matrix_iterator f_it;
 
   UInt nb_element;
   Array<Real> * filtered_J = NULL;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.getSize();
     filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
     FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
                                   filter_elements);
     const Array<Real> & cfiltered_J = *filtered_J; // \todo temporary patch
     J_it = cfiltered_J.begin_reinterpret(nb_points, 1, nb_element);
   } else {
     nb_element = mesh.getNbElement(type, ghost_type);
     J_it = jac_loc.begin_reinterpret(nb_points, 1, nb_element);
   }
 
   intf.resize(nb_element);
 
   f_it = in_f.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element);
   inte_it = intf.begin_reinterpret(nb_degree_of_freedom, 1, nb_element);
 
   for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
     const Matrix<Real> & f = *f_it;
     const Matrix<Real> & J = *J_it;
     Matrix<Real> & inte_f = *inte_it;
 
     inte_f.mul<false, false>(f, J);
   }
 
   delete filtered_J;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline Real IntegratorGauss<_ek_igfem, IOF>::integrate(
     const Array<Real> & in_f, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
                       "No jacobians for the type "
                           << jacobians.printType(type, ghost_type));
 
   Array<Real> intfv(0, 1);
   integrate<type>(in_f, intfv, 1, ghost_type, filter_elements);
 
   UInt nb_values = intfv.getSize();
   if (nb_values == 0)
     return 0.;
 
   UInt nb_values_to_sum = nb_values >> 1;
 
   std::sort(intfv.begin(), intfv.end());
 
   // as long as the half is not empty
   while (nb_values_to_sum) {
     UInt remaining = (nb_values - 2 * nb_values_to_sum);
     if (remaining)
       intfv(nb_values - 2) += intfv(nb_values - 1);
 
     // sum to consecutive values and store the sum in the first half
     for (UInt i = 0; i < nb_values_to_sum; ++i) {
       intfv(i) = intfv(2 * i) + intfv(2 * i + 1);
     }
 
     nb_values = nb_values_to_sum;
     nb_values_to_sum >>= 1;
   }
 
   AKANTU_DEBUG_OUT();
   return intfv(0);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class IOF>
 template <ElementType type>
 inline void IntegratorGauss<_ek_igfem, IOF>::integrateOnIntegrationPoints(
     const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    GhostType ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
                       "No jacobians for the type "
                           << jacobians.printType(type, ghost_type));
 
   UInt nb_element;
   const Matrix<Real> & quads = quadrature_points(type, ghost_type);
 
   UInt nb_points = quads.cols();
 
   const Array<Real> & jac_loc = jacobians(type, ghost_type);
 
   Array<Real>::const_scalar_iterator J_it;
   Array<Real>::vector_iterator inte_it;
   Array<Real>::const_vector_iterator f_it;
 
   Array<Real> * filtered_J = NULL;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.getSize();
     filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
     FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
                                   filter_elements);
     J_it = filtered_J->begin();
   } else {
     nb_element = mesh.getNbElement(type, ghost_type);
     J_it = jac_loc.begin();
   }
 
   intf.resize(nb_element * nb_points);
 
   f_it = in_f.begin(nb_degree_of_freedom);
   inte_it = intf.begin(nb_degree_of_freedom);
 
   for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
     const Real & J = *J_it;
     const Vector<Real> & f = *f_it;
     Vector<Real> & inte_f = *inte_it;
 
     inte_f = f;
     inte_f *= J;
   }
 
   delete filtered_J;
 
   AKANTU_DEBUG_OUT();
 }
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_elastic.cc b/extra_packages/igfem/src/material_igfem/material_igfem_elastic.cc
index 33435cecb..085a2a94c 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_elastic.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_elastic.cc
@@ -1,241 +1,241 @@
 /**
  * @file   material_igfem_elastic.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Specializaton of material class for the igfem elastic material
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "material_igfem_elastic.hh"
 #include "material_elastic.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialIGFEMElastic<dim>::MaterialIGFEMElastic(SolidMechanicsModel & model,
                                                 const ID & id)
     : Material(model, id), Parent(model, id), lambda("lambda", *this),
       mu("mu", *this), kpa("kappa", *this) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialIGFEMElastic<dim>::initialize() {
+template <Int dim> void MaterialIGFEMElastic<dim>::initialize() {
   this->lambda.initialize(1);
   this->mu.initialize(1);
   this->kpa.initialize(1);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialIGFEMElastic<dim>::initMaterial() {
+template <Int dim> void MaterialIGFEMElastic<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   Parent::initMaterial();
 
   /// insert the sub_material names into the map
   this->sub_material_names[0] = this->name_sub_mat_1;
   this->sub_material_names[1] = this->name_sub_mat_2;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMElastic<spatial_dimension>::updateElasticInternals(
     const Array<Element> & element_list) {
 
   /// compute the Lamé constants for both sub-materials
   Vector<Real> lambda_per_sub_mat(this->nb_sub_materials);
   Vector<Real> mu_per_sub_mat(this->nb_sub_materials);
   Vector<Real> kpa_per_sub_mat(this->nb_sub_materials);
   for (UInt i = 0; i < this->nb_sub_materials; ++i) {
     ID mat_name = this->sub_material_names[i];
     const MaterialElastic<spatial_dimension> & mat =
         dynamic_cast<MaterialElastic<spatial_dimension> &>(
             this->model->getMaterial(mat_name));
     lambda_per_sub_mat(i) = mat.getLambda();
     mu_per_sub_mat(i) = mat.getMu();
     kpa_per_sub_mat(i) = mat.getKappa();
   }
 
   for (ghost_type_t::iterator g = ghost_type_t::begin();
        g != ghost_type_t::end(); ++g) {
     GhostType ghost_type = *g;
     /// loop over all types in the material
     typedef ElementTypeMapArray<UInt>::type_iterator iterator;
     iterator it = this->element_filter.firstType(spatial_dimension, ghost_type,
                                                  _ek_igfem);
     iterator last_type =
         this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
     /// loop over all types in the filter
     for (; it != last_type; ++it) {
       ElementType el_type = *it;
       if (el_type == _igfem_triangle_4)
         this->template setSubMaterial<_igfem_triangle_4>(element_list,
                                                          ghost_type);
       else if (el_type == _igfem_triangle_5)
         this->template setSubMaterial<_igfem_triangle_5>(element_list,
                                                          ghost_type);
       else
         AKANTU_ERROR("There is currently no other IGFEM type implemented");
 
       UInt nb_element = this->element_filter(el_type, ghost_type).getSize();
       UInt nb_quads = this->fem->getNbIntegrationPoints(el_type);
       /// get pointer to internals for given type
       Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
       Real * mu_ptr = this->mu(el_type, ghost_type).storage();
       Real * kpa_ptr = this->kpa(el_type, ghost_type).storage();
       UInt * sub_mat_ptr = this->sub_material(el_type, ghost_type).storage();
       for (UInt q = 0; q < nb_element * nb_quads;
            ++q, ++lambda_ptr, ++mu_ptr, ++kpa_ptr, ++sub_mat_ptr) {
         UInt index = *sub_mat_ptr;
         *lambda_ptr = lambda_per_sub_mat(index);
         *mu_ptr = mu_per_sub_mat(index);
         *kpa_ptr = kpa_per_sub_mat(index);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMElastic<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Parent::computeStress(el_type, ghost_type);
 
   if (!this->finite_deformation) {
     /// get pointer to internals
     Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
     Real * mu_ptr = this->mu(el_type, ghost_type).storage();
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
     this->computeStressOnQuad(grad_u, sigma, *lambda_ptr, *mu_ptr);
     ++lambda_ptr;
     ++mu_ptr;
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   } else {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMElastic<spatial_dimension>::computeTangentModuli(
     __attribute__((unused)) ElementType el_type,
     Array<Real> & tangent_matrix,
     __attribute__((unused)) GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// get pointer to internals
   Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
   Real * mu_ptr = this->mu(el_type, ghost_type).storage();
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
   this->computeTangentModuliOnQuad(tangent, *lambda_ptr, *mu_ptr);
   ++lambda_ptr;
   ++mu_ptr;
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMElastic<spatial_dimension>::computePotentialEnergy(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   // MaterialThermal<spatial_dimension>::computePotentialEnergy(el_type,
   // ghost_type);
 
   // if(ghost_type != _not_ghost) return;
   // Array<Real>::scalar_iterator epot = this->potential_energy(el_type,
   // ghost_type).begin();
 
   // if (!this->finite_deformation) {
   //   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   //   this->computePotentialEnergyOnQuad(grad_u, sigma, *epot);
   //   ++epot;
 
   //   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   // } else {
   //   Matrix<Real> E(spatial_dimension, spatial_dimension);
 
   //   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   //   this->template gradUToGreenStrain<spatial_dimension>(grad_u, E);
 
   //   this->computePotentialEnergyOnQuad(E, sigma, *epot);
   //   ++epot;
 
   //   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   // }
 
   AKANTU_DEBUG_TO_IMPLEMENT();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMElastic<spatial_dimension>::computePotentialEnergyByElement(
     ElementType type, UInt index, Vector<Real> & epot_on_quad_points) {
   // Array<Real>::matrix_iterator gradu_it =
   //   this->gradu(type).begin(spatial_dimension,
   //                            spatial_dimension);
   // Array<Real>::matrix_iterator gradu_end =
   //   this->gradu(type).begin(spatial_dimension,
   //                            spatial_dimension);
   // Array<Real>::matrix_iterator stress_it =
   //   this->stress(type).begin(spatial_dimension,
   //                            spatial_dimension);
 
   // if (this->finite_deformation)
   //   stress_it = this->piola_kirchhoff_2(type).begin(spatial_dimension,
   //                                                        spatial_dimension);
 
   // UInt nb_quadrature_points =
   // this->model->getFEEngine().getNbQuadraturePoints(type);
 
   // gradu_it  += index*nb_quadrature_points;
   // gradu_end += (index+1)*nb_quadrature_points;
   // stress_it  += index*nb_quadrature_points;
 
   // Real * epot_quad = epot_on_quad_points.storage();
 
   // Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
 
   // for(;gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
 
   //   if (this->finite_deformation)
   //     this->template gradUToGreenStrain<spatial_dimension>(*gradu_it,
   //     grad_u);
   //   else
   //     grad_u.copy(*gradu_it);
 
   //   this->computePotentialEnergyOnQuad(grad_u, *stress_it, *epot_quad);
   // }
   AKANTU_DEBUG_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMElastic<spatial_dimension>::onElementsAdded(
     const Array<Element> & element_list, const NewElementsEvent & event) {
 
   Parent::onElementsAdded(element_list, event);
   updateElasticInternals(element_list);
 };
 
 INSTANTIATE_MATERIAL(MaterialIGFEMElastic);
 
 } // namespace akantu
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_elastic.hh b/extra_packages/igfem/src/material_igfem/material_igfem_elastic.hh
index 2e1497b32..d3f275e21 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_elastic.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_elastic.hh
@@ -1,129 +1,129 @@
 /**
  * @file   element_class_igfem.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  *
  * @brief  Material isotropic elastic for IGFEM
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "material_igfem.hh"
 #include "plane_stress_toolbox.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_IGFEM_ELASTIC_HH_
 #define AKANTU_MATERIAL_IGFEM_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>
+template <Int spatial_dimension>
 class MaterialIGFEMElastic
     : public PlaneStressToolbox<spatial_dimension, MaterialIGFEM> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   typedef PlaneStressToolbox<spatial_dimension, MaterialIGFEM> Parent;
 
 public:
   MaterialIGFEMElastic(SolidMechanicsModel & model, const ID & id = "");
   MaterialIGFEMElastic(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
                        FEEngine & fe_engine, const ID & id = "");
 
   virtual ~MaterialIGFEMElastic() {}
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void initMaterial();
   /// constitutive law for all element of a type
   virtual void computeStress(ElementType el_type,
                              GhostType ghost_type = _not_ghost);
 
   /// compute the tangent stiffness matrix for an element type
   virtual void computeTangentModuli(ElementType el_type,
                                     Array<Real> & tangent_matrix,
                                     GhostType ghost_type = _not_ghost);
 
   /// compute the elastic potential energy
   virtual void computePotentialEnergy(ElementType el_type,
                                       GhostType ghost_type = _not_ghost);
 
   virtual void
   computePotentialEnergyByElement(ElementType type, UInt index,
                                   Vector<Real> & epot_on_quad_points);
 
   void updateElasticInternals(const Array<Element> & element_list);
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(const Matrix<Real> & grad_u,
                                   Matrix<Real> & sigma,
                                   __attribute__((unused)) const Real lambda,
                                   const Real mu) const;
 
   /// compute the tangent stiffness matrix for an element
   inline void computeTangentModuliOnQuad(Matrix<Real> & tangent,
                                          __attribute__((unused))
                                          const Real lambda,
                                          const Real mu) const;
 
   static inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
                                                   const Matrix<Real> & sigma,
                                                   Real & epot);
 
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler inherited members                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   virtual void onElementsAdded(const Array<Element> & element_list,
                                const NewElementsEvent & event);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// First Lamé coefficient
   IGFEMInternalField<Real> lambda;
 
   /// Second Lamé coefficient (shear modulus)
   IGFEMInternalField<Real> mu;
 
   /// Bulk modulus
   IGFEMInternalField<Real> kpa;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_igfem_elastic_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_IGFEM_ELASTIC_HH_ */
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_elastic_inline_impl.hh b/extra_packages/igfem/src/material_igfem/material_igfem_elastic_inline_impl.hh
index 54fe6cada..98500e68f 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_elastic_inline_impl.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_elastic_inline_impl.hh
@@ -1,91 +1,91 @@
 /**
  * @file   material_igfem_elastic_inline_impl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Implementation of the inline functions of the material igfem elastic
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialIGFEMElastic<spatial_dimension>::computeStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma, const Real lambda,
     const Real mu) const {
   Real trace = grad_u.trace(); // trace = (\nabla u)_{kk}
 
   // \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla
   // u_{ij} + \nabla u_{ji})
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       sigma(i, j) =
           (i == j) * lambda * trace + mu * (grad_u(i, j) + grad_u(j, i));
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void MaterialIGFEMElastic<1>::computeStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma, const Real lambda,
     const Real mu) const {
   sigma(0, 0) = 2 * mu * grad_u(0, 0);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialIGFEMElastic<spatial_dimension>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent, const Real lambda, const Real mu) const {
   UInt n = tangent.cols();
 
   // Real Ep = E/((1+nu)*(1-2*nu));
   Real Miiii = lambda + 2 * mu;
   Real Miijj = lambda;
   Real Mijij = mu;
 
   if (spatial_dimension == 1)
     tangent(0, 0) = 3 * mu;
   else
     tangent(0, 0) = Miiii;
 
   // test of dimension should by optimized out by the compiler due to the
   // template
   if (spatial_dimension >= 2) {
     tangent(1, 1) = Miiii;
     tangent(0, 1) = Miijj;
     tangent(1, 0) = Miijj;
 
     tangent(n - 1, n - 1) = Mijij;
   }
 
   if (spatial_dimension == 3) {
     tangent(2, 2) = Miiii;
     tangent(0, 2) = Miijj;
     tangent(1, 2) = Miijj;
     tangent(2, 0) = Miijj;
     tangent(2, 1) = Miijj;
 
     tangent(3, 3) = Mijij;
     tangent(4, 4) = Mijij;
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialIGFEMElastic<dim>::computePotentialEnergyOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & sigma, Real & epot) {
   AKANTU_DEBUG_TO_IMPLEMENT();
   ///  epot = .5 * sigma.doubleDot(grad_u);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void MaterialIGFEMElastic<1>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent, const Real lambda, const Real mu) const {
   tangent(0, 0) = 2 * mu;
 }
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.cc b/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.cc
index fbec0e9f9..34e564db6 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.cc
@@ -1,288 +1,288 @@
 /**
  * @file   material_igfem_iterative_stiffness_reduction.cc
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Thu Mar 10 08:37:43 2016
  *
  * @brief  Implementation of igfem material iterative stiffness reduction
  *
  *
  * 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 "material_igfem_iterative_stiffness_reduction.hh"
 #include <math.h>
 
 namespace akantu {
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 
 /* -------------------------------------------------------------------------- */
 MaterialIGFEMIterativeStiffnessReduction<spatial_dimension>::
     MaterialIGFEMIterativeStiffnessReduction(SolidMechanicsModel & model,
                                              const ID & id)
     : Material(model, id), MaterialIGFEMSawToothDamage<spatial_dimension>(model,
                                                                           id),
       eps_u("ultimate_strain", *this), reduction_step("damage_step", *this),
       D("tangent", *this), Gf(0.), crack_band_width(0.), max_reductions(0),
       reduction_constant(0.) {
   AKANTU_DEBUG_IN();
 
   this->eps_u.initialize(1);
   this->D.initialize(1);
   this->reduction_step.initialize(1);
 
   this->internals_to_transfer.push_back("ultimate_strain");
   this->internals_to_transfer.push_back("tangent");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialIGFEMIterativeStiffnessReduction<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   MaterialIGFEMSawToothDamage<dim>::initMaterial();
 
   /// get the parameters for the sub-material that can be damaged
   ID mat_name = this->sub_material_names[1];
   const Material & mat = this->model->getMaterial(mat_name);
   this->crack_band_width = mat.getParam<Real>("crack_band_width");
   this->max_reductions = mat.getParam<UInt>("max_reductions");
   this->reduction_constant = mat.getParam<Real>("reduction_constant");
   this->Gf = mat.getParam<Real>("Gf");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMIterativeStiffnessReduction<spatial_dimension>::
     computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                       ElementType el_type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// storage for the current stress
   Matrix<Real> sigma(spatial_dimension, spatial_dimension);
   /// Vector to store eigenvalues of current stress tensor
   Vector<Real> eigenvalues(spatial_dimension);
 
   /// iterators on the needed internal fields
   Array<Real>::const_scalar_iterator Sc_it =
       this->Sc(el_type, ghost_type).begin();
   Array<Real>::scalar_iterator dam_it =
       this->damage(el_type, ghost_type).begin();
   Array<Real>::scalar_iterator equivalent_stress_it =
       this->equivalent_stress(el_type, ghost_type).begin();
   Array<Real>::const_matrix_iterator grad_u_it =
       grad_u.begin(spatial_dimension, spatial_dimension);
   Array<Real>::const_matrix_iterator grad_u_end =
       grad_u.end(spatial_dimension, spatial_dimension);
   Real * mu_ptr = this->mu(el_type, ghost_type).storage();
   Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
 
   /// loop over all the quadrature points and compute the equivalent stress
   for (; grad_u_it != grad_u_end; ++grad_u_it) {
     /// compute the stress
     sigma.zero();
     MaterialIGFEMElastic<spatial_dimension>::computeStressOnQuad(
         *grad_u_it, sigma, *lambda_ptr, *mu_ptr);
     MaterialIGFEMSawToothDamage<
         spatial_dimension>::computeDamageAndStressOnQuad(sigma, *dam_it);
     /// compute eigenvalues
     sigma.eig(eigenvalues);
 
     /// find max eigenvalue and normalize by tensile strength
     *equivalent_stress_it =
         *(std::max_element(eigenvalues.storage(),
                            eigenvalues.storage() + spatial_dimension)) /
         (*Sc_it);
     ++Sc_it;
     ++equivalent_stress_it;
     ++dam_it;
     ++lambda_ptr;
     ++mu_ptr;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 UInt MaterialIGFEMIterativeStiffnessReduction<
     spatial_dimension>::updateDamage() {
   UInt nb_damaged_elements = 0;
 
   if (this->norm_max_equivalent_stress >= 1.) {
 
     AKANTU_DEBUG_IN();
 
     /// update the damage only on non-ghosts elements! Doesn't make sense to
     /// update on ghost.
     GhostType ghost_type = _not_ghost;
     ;
 
     Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(
         spatial_dimension, ghost_type, _ek_igfem);
     Mesh::type_iterator last_type =
         this->model->getFEEngine().getMesh().lastType(spatial_dimension,
                                                       ghost_type, _ek_igfem);
 
     /// get the Young's modulus of the damageable sub-material
     ID mat_name = this->sub_material_names[1];
 
     Real E = this->model->getMaterial(mat_name).template getParam<Real>("E");
 
     /// loop over all the elements
     for (; it != last_type; ++it) {
       ElementType el_type = *it;
 
       /// get iterators on the needed internal fields
       const Array<UInt> & sub_mat = this->sub_material(el_type, ghost_type);
       Array<UInt>::const_scalar_iterator sub_mat_it = sub_mat.begin();
       Array<Real>::const_scalar_iterator equivalent_stress_it =
           this->equivalent_stress(el_type, ghost_type).begin();
       Array<Real>::const_scalar_iterator equivalent_stress_end =
           this->equivalent_stress(el_type, ghost_type).end();
       Array<Real>::scalar_iterator dam_it =
           this->damage(el_type, ghost_type).begin();
       Array<UInt>::scalar_iterator reduction_it =
           this->reduction_step(el_type, ghost_type).begin();
       Array<Real>::const_scalar_iterator eps_u_it =
           this->eps_u(el_type, ghost_type).begin();
       Array<Real>::scalar_iterator Sc_it =
           this->Sc(el_type, ghost_type).begin();
       Array<Real>::const_scalar_iterator D_it =
           this->D(el_type, ghost_type).begin();
 
       /// loop over all the elements of the given type
       UInt nb_element = this->element_filter(el_type, ghost_type).getSize();
       UInt nb_quads = this->fem->getNbIntegrationPoints(el_type, ghost_type);
       bool damage_element = false;
       for (UInt e = 0; e < nb_element; ++e) {
         damage_element = false;
         /// check if damage occurs in the element
         for (UInt q = 0; q < nb_quads;
              ++q, ++reduction_it, ++sub_mat_it, ++equivalent_stress_it) {
           if (*equivalent_stress_it >= (1 - this->dam_tolerance) *
                                            this->norm_max_equivalent_stress &&
               *sub_mat_it != 0) {
             /// check if this element can still be damaged
             if (*reduction_it == this->max_reductions)
               continue;
             damage_element = true;
           }
         }
 
         if (damage_element) {
           /// damage the element
           nb_damaged_elements += 1;
           sub_mat_it -= nb_quads;
           reduction_it -= nb_quads;
           for (UInt q = 0; q < nb_quads; ++q) {
             if (*sub_mat_it) {
               /// increment the counter of stiffness reduction steps
               *reduction_it += 1;
               if (*reduction_it == this->max_reductions)
                 *dam_it = this->max_damage;
               else {
                 /// update the damage on this quad
                 *dam_it = 1. - (1. / std::pow(this->reduction_constant,
                                               *reduction_it));
                 /// update the stiffness on this quad
                 *Sc_it = (*eps_u_it) * (1. - (*dam_it)) * E * (*D_it) /
                          ((1. - (*dam_it)) * E + (*D_it));
               }
             }
             ++sub_mat_it;
             ++dam_it;
             ++reduction_it;
             ++eps_u_it;
             ++Sc_it;
             ++D_it;
           }
         } else {
           dam_it += nb_quads;
           eps_u_it += nb_quads;
           Sc_it += nb_quads;
           D_it += nb_quads;
         }
       }
     }
   }
   StaticCommunicator & comm =
       akantu::StaticCommunicator::getStaticCommunicator();
   comm.allReduce(&nb_damaged_elements, 1, _so_sum);
   AKANTU_DEBUG_OUT();
   return nb_damaged_elements;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMIterativeStiffnessReduction<
     spatial_dimension>::onElementsAdded(__attribute__((unused))
                                         const Array<Element> & element_list,
                                         __attribute__((unused))
                                         const NewElementsEvent & event) {
 
   MaterialIGFEMSawToothDamage<spatial_dimension>::onElementsAdded(element_list,
                                                                   event);
   /// set the correct damage iteration step (is UInt->cannot be interpolated)
   Real val = 0.;
   for (ghost_type_t::iterator g = ghost_type_t::begin();
        g != ghost_type_t::end(); ++g) {
     GhostType ghost_type = *g;
     /// loop over all types in the material
     typedef ElementTypeMapArray<UInt>::type_iterator iterator;
     iterator it = this->element_filter.firstType(spatial_dimension, ghost_type,
                                                  _ek_igfem);
     iterator last_type =
         this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
     /// loop over all types in the filter
     for (; it != last_type; ++it) {
       const ElementType el_type = *it;
       Array<Real>::scalar_iterator dam_it =
           this->damage(el_type, ghost_type).begin();
       Array<UInt>::scalar_iterator reduction_it =
           this->reduction_step(el_type, ghost_type).begin();
       UInt nb_element = this->element_filter(el_type, ghost_type).getSize();
       UInt nb_quads = this->fem->getNbIntegrationPoints(el_type);
       UInt * sub_mat_ptr = this->sub_material(el_type, ghost_type).storage();
       for (UInt q = 0; q < nb_element * nb_quads;
            ++q, ++sub_mat_ptr, ++dam_it, ++reduction_it) {
         if (*sub_mat_ptr) {
           if (Math::are_float_equal(*dam_it, this->max_damage))
             *reduction_it = this->max_reductions;
           else {
             for (UInt i = 0; i < this->max_reductions; ++i) {
               val = 1 - (1. / std::pow(this->reduction_constant, i));
               if (Math::are_float_equal(val, *dam_it))
                 *reduction_it = i;
             }
           }
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(MaterialIGFEMIterativeStiffnessReduction);
 
 } // namespace akantu
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.hh b/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.hh
index a72e4a6a4..1314fdb52 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_iterative_stiffness_reduction.hh
@@ -1,113 +1,113 @@
 /**
  * @file   material_igfem_iterative_stiffness_reduction.hh
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Wed Mar  9 19:44:22 2016
  *
  * @brief  Material for iterative stiffness reduction by contant factor
  *
  *
  * 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 "material_igfem_saw_tooth_damage.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_MATERIAL_IGFEM_ITERATIVE_STIFFNESS_REDUCTION_HH_
 #define AKANTU_MATERIAL_IGFEM_ITERATIVE_STIFFNESS_REDUCTION_HH_
 
 namespace akantu {
 
 /**
  * Material damage iterative
  *
  * parameters in the material files :
  *   - Gfx
  *   - h
  *   - Sc
  */
 /// Proposed by Rots and Invernizzi, 2004: Regularized sequentially linear
 // saw-tooth softening model (section 4.2)
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialIGFEMIterativeStiffnessReduction
     : public MaterialIGFEMSawToothDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialIGFEMIterativeStiffnessReduction(SolidMechanicsModel & model,
                                            const ID & id = "");
 
   virtual ~MaterialIGFEMIterativeStiffnessReduction(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// set the material parameters
   virtual void initMaterial();
 
   /// compute the equivalent stress on each Gauss point (i.e. the max prinicpal
   /// stress) and normalize it by the tensile stiffness
   virtual void
   computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                     ElementType el_type,
                                     GhostType ghost_type = _not_ghost);
 
   /// update internal field damage
   virtual UInt updateDamage();
 
   virtual void onElementsAdded(const Array<Element> & element_list,
                                const NewElementsEvent & event);
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the ultimate strain
   IGFEMInternalField<Real> eps_u;
 
   /// the reduction
   IGFEMInternalField<UInt> reduction_step;
 
   /// the tangent of the tensile stress-strain softening
   IGFEMInternalField<Real> D;
 
   /// fracture energy
   Real Gf;
 
   /// crack band width for normalization of fracture energy
   Real crack_band_width;
 
   /// the number of total reductions steps until complete failure
   UInt max_reductions;
 
   /// the reduction constant (denoated by a in the paper of rots)
   Real reduction_constant;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_IGFEM_ITERATIVE_STIFFNESS_REDUCTION_HH_ */
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.cc b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.cc
index e95cd3dd5..5d35bddf3 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.cc
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.cc
@@ -1,466 +1,466 @@
 /**
  * @file   material_igfem_saw_tooth_damage.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Implementation of the squentially linear saw-tooth damage model for
  * IGFEM elements
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "material_igfem_saw_tooth_damage.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialIGFEMSawToothDamage<dim>::MaterialIGFEMSawToothDamage(
     SolidMechanicsModel & model, const ID & id)
     : Material(model, id), Parent(model, id), Sc("Sc", *this),
       equivalent_stress("equivalent_stress", *this),
       norm_max_equivalent_stress(0) {
   AKANTU_DEBUG_IN();
 
   this->Sc.initialize(1);
   this->equivalent_stress.initialize(1);
   this->damage.setElementKind(_ek_igfem);
   this->damage.setFEEngine(*(this->fem));
 
   this->internals_to_transfer.push_back("damage");
   this->internals_to_transfer.push_back("Sc");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialIGFEMSawToothDamage<dim>::initMaterial() {
+template <Int dim> void MaterialIGFEMSawToothDamage<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   Parent::initMaterial();
 
   /// get the parameters for the sub-material that can be damaged
   ID mat_name = this->sub_material_names[1];
   const Material & mat = this->model->getMaterial(mat_name);
   this->prescribed_dam = mat.getParam<Real>("prescribed_dam");
   this->dam_threshold = mat.getParam<Real>("dam_threshold");
   this->dam_tolerance = mat.getParam<Real>("dam_tolerance");
   this->max_damage = mat.getParam<Real>("max_damage");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMSawToothDamage<spatial_dimension>::
     computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                       ElementType el_type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// Vector to store eigenvalues of current stress tensor
   Vector<Real> eigenvalues(spatial_dimension);
 
   Array<Real>::const_iterator<Real> Sc_it = Sc(el_type, ghost_type).begin();
   Array<Real>::iterator<Real> equivalent_stress_it =
       equivalent_stress(el_type, ghost_type).begin();
 
   Array<Real>::const_matrix_iterator grad_u_it =
       grad_u.begin(spatial_dimension, spatial_dimension);
   Array<Real>::const_matrix_iterator grad_u_end =
       grad_u.end(spatial_dimension, spatial_dimension);
   /// get pointer to internals
   Real * lambda_ptr = this->lambda(el_type, ghost_type).storage();
   Real * mu_ptr = this->mu(el_type, ghost_type).storage();
   Real * dam = this->damage(el_type, ghost_type).storage();
   Matrix<Real> sigma(spatial_dimension, spatial_dimension);
   for (; grad_u_it != grad_u_end; ++grad_u_it) {
     MaterialIGFEMElastic<spatial_dimension>::computeStressOnQuad(
         *grad_u_it, sigma, *lambda_ptr, *mu_ptr);
     computeDamageAndStressOnQuad(sigma, *dam);
 
     /// compute eigenvalues
     sigma.eig(eigenvalues);
     /// find max eigenvalue and normalize by tensile strength
     *equivalent_stress_it =
         *(std::max_element(eigenvalues.storage(),
                            eigenvalues.storage() + spatial_dimension)) /
         *(Sc_it);
     ++Sc_it;
     ++equivalent_stress_it;
     ++dam;
     ++lambda_ptr;
     ++mu_ptr;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMSawToothDamage<spatial_dimension>::computeAllStresses(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// reset normalized maximum equivalent stress
   if (ghost_type == _not_ghost)
     norm_max_equivalent_stress = 0;
 
   Parent::computeAllStresses(ghost_type);
 
   /// find global Gauss point with highest stress
   StaticCommunicator & comm =
       akantu::StaticCommunicator::getStaticCommunicator();
   comm.allReduce(&norm_max_equivalent_stress, 1, _so_max);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMSawToothDamage<spatial_dimension>::
     findMaxNormalizedEquivalentStress(ElementType el_type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if (ghost_type == _not_ghost) {
 
     const Array<Real> & e_stress = equivalent_stress(el_type);
     Array<Real>::const_iterator<Real> equivalent_stress_it = e_stress.begin();
     Array<Real>::const_iterator<Real> equivalent_stress_end = e_stress.end();
     Array<Real> & dam = this->damage(el_type);
     Array<Real>::iterator<Real> dam_it = dam.begin();
     Array<UInt> & sub_mat = this->sub_material(el_type);
     Array<UInt>::iterator<UInt> sub_mat_it = sub_mat.begin();
 
     for (; equivalent_stress_it != equivalent_stress_end;
          ++equivalent_stress_it, ++dam_it, ++sub_mat_it) {
       /// check if max equivalent stress for this element type is greater than
       /// the current norm_max_eq_stress and if the element is not already fully
       /// damaged
       if ((*equivalent_stress_it > norm_max_equivalent_stress &&
            *dam_it < max_damage) &&
           *sub_mat_it != 0) {
         norm_max_equivalent_stress = *equivalent_stress_it;
       }
     }
   }
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMSawToothDamage<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Parent::computeStress(el_type, ghost_type);
 
   Real * dam = this->damage(el_type, ghost_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   computeDamageAndStressOnQuad(sigma, *dam);
   ++dam;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   computeNormalizedEquivalentStress(this->gradu(el_type, ghost_type), el_type,
                                     ghost_type);
   norm_max_equivalent_stress = 0;
   findMaxNormalizedEquivalentStress(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 UInt MaterialIGFEMSawToothDamage<spatial_dimension>::updateDamage() {
   UInt nb_damaged_elements = 0;
   AKANTU_DEBUG_ASSERT(prescribed_dam > 0.,
                       "Your prescribed damage must be greater than zero");
 
   if (norm_max_equivalent_stress >= 1.) {
 
     AKANTU_DEBUG_IN();
     GhostType ghost_type = _not_ghost;
     ;
 
     Mesh::type_iterator it = this->model->getMesh().firstType(
         spatial_dimension, ghost_type, _ek_igfem);
     Mesh::type_iterator last_type = this->model->getMesh().lastType(
         spatial_dimension, ghost_type, _ek_igfem);
 
     for (; it != last_type; ++it) {
       ElementType el_type = *it;
       Array<UInt> & sub_mat = this->sub_material(el_type);
       Array<UInt>::iterator<UInt> sub_mat_it = sub_mat.begin();
       const Array<Real> & e_stress = equivalent_stress(el_type);
       Array<Real>::const_iterator<Real> equivalent_stress_it = e_stress.begin();
       Array<Real>::const_iterator<Real> equivalent_stress_end = e_stress.end();
       Array<Real> & dam = this->damage(el_type);
       Array<Real>::iterator<Real> dam_it = dam.begin();
 
       /// loop over all the elements of the given type
       UInt nb_element = this->element_filter(el_type, ghost_type).getSize();
       UInt nb_quads = this->fem->getNbIntegrationPoints(el_type, ghost_type);
       bool damage_element = false;
       for (UInt e = 0; e < nb_element; ++e) {
         damage_element = false;
         /// check if damage occurs in the element
         for (UInt q = 0; q < nb_quads; ++q) {
           if (*equivalent_stress_it >=
                   (1 - dam_tolerance) * norm_max_equivalent_stress &&
               *sub_mat_it != 0) {
             damage_element = true;
           }
           ++sub_mat_it;
           ++equivalent_stress_it;
         }
 
         if (damage_element) {
           nb_damaged_elements += 1;
           /// damage the element
           sub_mat_it -= nb_quads;
           for (UInt q = 0; q < nb_quads; ++q) {
             if (*sub_mat_it) {
               if (*dam_it < dam_threshold)
                 *dam_it += prescribed_dam;
               else
                 *dam_it = max_damage;
             }
             ++sub_mat_it;
             ++dam_it;
           }
         } else {
           dam_it += nb_quads;
         }
       }
     }
   }
 
   StaticCommunicator & comm =
       akantu::StaticCommunicator::getStaticCommunicator();
   comm.allReduce(&nb_damaged_elements, 1, _so_sum);
   AKANTU_DEBUG_OUT();
   return nb_damaged_elements;
 }
 /* -------------------------------------------------------------------------- */
 // template<UInt spatial_dimension>
 // void
 // MaterialIGFEMSawToothDamage<spatial_dimension>::updateEnergiesAfterDamage(ElementType
 // el_type, GhostType ghost_type) {
 //   MaterialDamage<spatial_dimension>::updateEnergies(el_type, ghost_type);
 // }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialIGFEMSawToothDamage<spatial_dimension>::onElementsAdded(
     __attribute__((unused)) const Array<Element> & element_list,
     __attribute__((unused)) const NewElementsEvent & event) {
 
   /// update elastic constants
   MaterialIGFEMElastic<spatial_dimension>::onElementsAdded(element_list, event);
   IGFEMInternalField<Real> quadrature_points_coordinates(
       "quadrature_points_coordinates", *this);
   quadrature_points_coordinates.initialize(spatial_dimension);
   this->computeQuadraturePointsCoordinates(quadrature_points_coordinates,
                                            _not_ghost);
   this->computeQuadraturePointsCoordinates(quadrature_points_coordinates,
                                            _ghost);
 
   Array<Element>::const_iterator<Element> el_begin = element_list.begin();
   Array<Element>::const_iterator<Element> el_end = element_list.end();
   Element el;
   el.kind = _ek_igfem;
   /// loop over all the elements in the filter
   for (ghost_type_t::iterator g = ghost_type_t::begin();
        g != ghost_type_t::end(); ++g) {
     GhostType ghost_type = *g;
     /// loop over all types in the material
     typedef ElementTypeMapArray<UInt>::type_iterator iterator;
     iterator it = this->element_filter.firstType(spatial_dimension, ghost_type,
                                                  _ek_igfem);
     iterator last_type =
         this->element_filter.lastType(spatial_dimension, ghost_type, _ek_igfem);
     for (; it != last_type; ++it) {
       /// store the elements added to this material
       std::vector<Element> new_elements;
       Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
       UInt nb_element = elem_filter.getSize();
       UInt nb_quads =
           quadrature_points_coordinates.getFEEngine().getNbIntegrationPoints(
               *it, ghost_type);
       Array<Real> added_quads(0, spatial_dimension);
       const Array<Real> & quads =
           quadrature_points_coordinates(*it, ghost_type);
       Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
       el.type = *it;
       el.ghost_type = ghost_type;
 
       for (UInt e = 0; e < nb_element; ++e) {
         /// global number of element
         el.element = elem_filter(e);
         if (std::find(el_begin, el_end, el) != el_end) {
           new_elements.push_back(el);
           for (UInt q = 0; q < nb_quads; ++q) {
             added_quads.push_back(*quad);
             ++quad;
           }
         } else
           quad += nb_quads;
       }
 
       /// get the extrapolated values
       for (UInt i = 0; i < this->internals_to_transfer.size(); ++i) {
         if (!new_elements.size())
           continue;
         const ID name = this->getID() + ":" + this->internals_to_transfer[i];
         Array<Real> & internal =
             (*(this->internal_vectors_real[name]))(*it, ghost_type);
         UInt nb_component = internal.getNbComponent();
         /// Array<Real>::vector_iterator internal_it =
         /// internal.begin(nb_component);
         Array<Real> extrapolated_internal_values(new_elements.size() * nb_quads,
                                                  nb_component);
         this->model->transferInternalValues(this->internals_to_transfer[i],
                                             new_elements, added_quads,
                                             extrapolated_internal_values);
 
         UInt * sub_mat_ptr = this->sub_material(*it, ghost_type).storage();
         Array<Real>::const_vector_iterator extrapolated_it =
             extrapolated_internal_values.begin(nb_component);
         Array<Real>::vector_iterator internal_it = internal.begin(nb_component);
         /// copy back the results
         for (UInt j = 0; j < new_elements.size(); ++j) {
           Element element_local = this->convertToLocalElement(new_elements[j]);
           for (UInt q = 0; q < nb_quads; ++q, ++extrapolated_it) {
             if (sub_mat_ptr[element_local.element * nb_quads + q])
               internal_it[element_local.element * nb_quads + q] =
                   *extrapolated_it;
           }
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 // template<UInt spatial_dimension>
 // void
 // MaterialIGFEMSawToothDamage<spatial_dimension>::transferInternals(Material &
 // old_mat,
 // 								       std::vector<ElementPair> & element_pairs)
 // {
 
 // Element new_el_global;
 // Element new_el_local;
 // Element old_el_global;
 // Element old_el_local;
 
 // /// get the fe-engine of the old material
 // FEEngine & fem_old_mat = old_mat.getFEEngine();
 // for (UInt e = 0; e < element_pairs.size(); ++e) {
 //   new_el_global = element_pairs[e].first;
 //   old_el_global = element_pairs[e].second;
 //   /// get the number of the elements in their materials
 //   old_el_local = old_el_global;
 //   Array<UInt> & mat_local_numbering =
 //   this->model->getMaterialLocalNumbering(old_el_global.type,
 //   old_el_global.ghost_type);
 //   old_el_local.element = mat_local_numbering(old_el_global.element);
 //   new_el_local = this->convertToLocalElement(new_el_global);
 //   UInt nb_old_quads = fem_old_mat.getNbIntegrationPoints(old_el_global.type,
 //   old_el_global.ghost_type);
 //   UInt nb_new_quads = this->fem->getNbIntegrationPoints(new_el_global.type,
 //   new_el_global.ghost_type);
 
 //   if (old_mat.isInternal("damage", Mesh::getKind(old_el_global.type))
 // 	&& old_mat.isInternal("Sc", Mesh::getKind(old_el_global.type)) ) {
 
 //     UInt quad;
 //     Vector<Real> el_old_damage(nb_old_quads);
 //     Vector<Real> el_old_Sc(nb_old_quads);
 //     Vector<Real> el_new_damage(nb_new_quads);
 //     Vector<Real> el_new_Sc(nb_new_quads);
 //     const Array<Real> & old_Sc = old_mat.getArray("Sc", old_el_global.type,
 //     old_el_global.ghost_type);
 //     const Array<Real> & old_damage = old_mat.getArray("damage",
 //     old_el_global.type, old_el_global.ghost_type);
 //     Array<Real> & new_Sc = this->Sc(new_el_global.type,
 //     new_el_global.ghost_type);
 //     Array<Real> & new_damage = this->damage(new_el_global.type,
 //     new_el_global.ghost_type);
 
 //     for (UInt q = 0; q < nb_old_quads; ++q) {
 // 	quad = old_el_local.element * nb_old_quads + q;
 // 	el_old_damage(q) = old_damage(quad);
 // 	el_old_Sc(q) = old_Sc(quad);
 //     }
 
 //     this->interpolateInternal(new_el_global, old_el_global, el_new_damage,
 //     el_old_damage, nb_new_quads, nb_old_quads);
 //     this->interpolateInternal(new_el_global, old_el_global, el_new_Sc,
 //     el_old_Sc, nb_new_quads, nb_old_quads);
 
 //     for (UInt q = 0; q < nb_new_quads; ++q) {
 // 	quad = new_el_local.element * nb_new_quads + q;
 // 	if (this->sub_material(new_el_global.type,new_el_global.ghost_type)(quad)) {
 // 	  new_damage(quad) = el_new_damage(q);
 // 	  new_Sc(quad) = el_new_damage(q);
 // 	}
 //     }
 //   }
 
 //   else
 //     AKANTU_DEBUG_ASSERT((!old_mat.isInternal("damage",
 //     Mesh::getKind(old_el_global.type))
 // 			   && !old_mat.isInternal("Sc", Mesh::getKind(old_el_global.type))
 // ),
 // 			  "old material has damage or Sc but not both!!!!");
 // }
 // }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(MaterialIGFEMSawToothDamage);
 
 } // namespace akantu
 
 /*     /// get the material index in the model from this current material
     UInt this_mat_idx =  this->model->getMaterialIndex(this->name);
 
     /// number of elements in this event
     UInt nb_new_elements = element_list.getSize();
 
     // const Array<Element> & old_elements = igfem_event->getOldElementsList();
 
     // std::map<UInt, std::vector<ElementPair> > elements_by_old_mat;
 
     /// store the old elements sorted by their material
     for (UInt e = 0; e < nb_new_elements; ++e) {
       const Element new_el = element_list(e);
       const Array<UInt> & mat_idx =
    this->model->getMaterialByElement(new_el.type, new_el.ghost_type);
       if ( mat_idx(new_el.element) != this_mat_idx )
     continue; /// new element is not part of this material: nothing to be done
       /// get the corresponding old element and store new and old one as pair
       const Element old_el = old_elements(e);
       ElementPair el_pair(new_el, old_el);
       const Array<UInt> & old_mat_idx =
    this->model->getMaterialByElement(old_el.type, old_el.ghost_type);
       UInt mat_old_idx = old_mat_idx(old_el.element);
       elements_by_old_mat[mat_old_idx].push_back(el_pair);
     }
 
 
     /// loop over all the element pairs in the map
     for (std::map<UInt, std::vector<ElementPair> >::iterator map_it =
    elements_by_old_mat.begin();
      map_it != elements_by_old_mat.end(); ++map_it) {
       /// get the vector of old and new element pairs
       std::vector<ElementPair > & element_pairs = map_it->second;
       Material & old_mat = this->model->getMaterial(map_it->first);
       this->transferInternals(old_mat, element_pairs);
     }
 */
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.hh b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.hh
index 04ecc8063..9a5762bbb 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage.hh
@@ -1,138 +1,138 @@
 /**
  * @file   material_igfem_saw_tooth_damage.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  Linear saw-tooth softening material model for IGFEM elements
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_damage.hh"
 #include "material_igfem_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_IGFEM_SAW_TOOTH_DAMAGE_HH_
 #define AKANTU_MATERIAL_IGFEM_SAW_TOOTH_DAMAGE_HH_
 
 namespace akantu {
 
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialIGFEMSawToothDamage
     : public MaterialDamage<spatial_dimension, MaterialIGFEMElastic> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   typedef MaterialDamage<spatial_dimension, MaterialIGFEMElastic> Parent;
 
 public:
   typedef std::pair<Element, Element> ElementPair;
   MaterialIGFEMSawToothDamage(SolidMechanicsModel & model, const ID & id = "");
   MaterialIGFEMSawToothDamage(SolidMechanicsModel & model, UInt dim,
                               const Mesh & mesh, FEEngine & fe_engine,
                               const ID & id = "");
 
   virtual ~MaterialIGFEMSawToothDamage() {}
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void initMaterial();
 
   ///  virtual void updateInternalParameters();
 
   virtual void computeAllStresses(GhostType ghost_type = _not_ghost);
 
   /// update internal field damage
   virtual UInt updateDamage();
 
   UInt updateDamage(UInt quad_index, const Real eq_stress,
                     ElementType el_type, GhostType ghost_type);
 
   /// update energies after damage has been updated
   //  virtual void updateEnergiesAfterDamage(ElementType el_type, GhostType
   //  ghost_typ);
 
   virtual void onBeginningSolveStep(const AnalysisMethod & method){};
 
   virtual void onEndSolveStep(const AnalysisMethod & method){};
 
 protected:
   /// constitutive law for all element of a type
   virtual void computeStress(ElementType el_type,
                              GhostType ghost_type = _not_ghost);
 
   /// compute the equivalent stress on each Gauss point (i.e. the max prinicpal
   /// stress) and normalize it by the tensile strength
   virtual void
   computeNormalizedEquivalentStress(const Array<Real> & grad_u,
                                     ElementType el_type,
                                     GhostType ghost_type = _not_ghost);
 
   /// find max normalized equivalent stress
   void findMaxNormalizedEquivalentStress(ElementType el_type,
                                          GhostType ghost_type = _not_ghost);
 
   inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam);
 
 protected:
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler inherited members                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   virtual void onElementsAdded(const Array<Element> & element_list,
                                const NewElementsEvent & event);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get max normalized equivalent stress
   AKANTU_GET_MACRO(NormMaxEquivalentStress, norm_max_equivalent_stress, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// resistance to damage
   IGFEMInternalField<Real> Sc;
 
   /// internal field to store equivalent stress on each Gauss point
   IGFEMInternalField<Real> equivalent_stress;
 
   /// damage increment
   Real prescribed_dam;
 
   /// maximum equivalent stress
   Real norm_max_equivalent_stress;
 
   /// deviation from max stress at which Gauss point will still get damaged
   Real dam_tolerance;
 
   /// define damage threshold at which damage will be set to 1
   Real dam_threshold;
 
   /// maximum damage value
   Real max_damage;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_igfem_saw_tooth_damage_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_IGFEM_SAW_TOOTH_DAMAGE_HH_ */
diff --git a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage_inline_impl.hh b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage_inline_impl.hh
index 6cacd607f..45d8c6bac 100644
--- a/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage_inline_impl.hh
+++ b/extra_packages/igfem/src/material_igfem/material_igfem_saw_tooth_damage_inline_impl.hh
@@ -1,66 +1,66 @@
 /**
  * @file   material_igfem_saw_tooth_damage_inline_impl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief Implementation of inline functions of the squentially linear
  * saw-tooth damage model for IGFEM elements
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void
 MaterialIGFEMSawToothDamage<spatial_dimension>::computeDamageAndStressOnQuad(
     Matrix<Real> & sigma, Real & dam) {
   sigma *= 1 - dam;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 UInt MaterialIGFEMSawToothDamage<spatial_dimension>::updateDamage(
     UInt quad_index, const Real eq_stress, ElementType el_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_ASSERT(prescribed_dam > 0.,
                       "Your prescribed damage must be greater than zero");
 
   Array<Real> & dam = this->damage(el_type, ghost_type);
   Real & dam_on_quad = dam(quad_index);
 
   /// check if damage occurs
   if (equivalent_stress(el_type, ghost_type)(quad_index) >=
       (1 - dam_tolerance) * norm_max_equivalent_stress) {
     /// damage the entire sub-element -> get the element index
     UInt el_index =
         quad_index / this->element_filter(el_type, ghost_type).getSize();
     UInt nb_quads = this->fem->getNbIntegrationPoints(el_type, ghost_type);
     UInt start_idx = el_index * nb_quads;
     Array<UInt> & sub_mat = this->sub_material(el_type, ghost_type);
     UInt damaged_quads = 0;
     if (dam_on_quad < dam_threshold) {
       for (UInt q = 0; q < nb_quads; ++q, ++start_idx) {
         if (sub_mat(start_idx)) {
           dam(start_idx) += prescribed_dam;
           damaged_quads += 1;
         }
       }
     } else {
       for (UInt q = 0; q < nb_quads; ++q, ++start_idx) {
         if (sub_mat(start_idx)) {
           dam(start_idx) += max_damage;
           damaged_quads += 1;
         }
       }
     }
     return damaged_quads;
   }
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
diff --git a/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel.hh b/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel.hh
index 7604a0118..10a101e6e 100644
--- a/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel.hh
+++ b/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel.hh
@@ -1,220 +1,220 @@
 /**
  * @file mesh_igfem_spherical_growing_gel.hh
  *
  * @author Clement Roux-Langlois <clement.roux@epfl.ch>
  *
  * @date creation: Mon Jul 13 2015
  *
  * @brief Computation of mesh intersection with sphere(s) and growing of these
  *        spheres. This class handle the intersectors templated for every
  * element
  *        types.
  *
  *
  * Copyright (©) 2010-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 0
 #ifndef AKANTU_MESH_IGFEM_SPHERICAL_GROWING_GEL_HH_
 #define AKANTU_MESH_IGFEM_SPHERICAL_GROWING_GEL_HH_
 
 #include "aka_common.hh"
 #include "mesh_sphere_intersector.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* classes for new igfem elements mesh events */
 /* -------------------------------------------------------------------------- */
 
 class NewIGFEMElementsEvent : public NewElementsEvent {
 public:
   AKANTU_GET_MACRO_NOT_CONST(OldElementsList, old_elements, Array<Element> &);
   AKANTU_GET_MACRO(OldElementsList, old_elements, const Array<Element> &);
 
 protected:
   Array<Element> old_elements;
 };
 
 class NewIGFEMNodesEvent : public NewNodesEvent {
 public:
   void setNewNodePerElem(const Array<UInt> & new_node_per_elem) {
     this->new_node_per_elem = &new_node_per_elem;
   }
   void setType(ElementType new_type) { type = new_type; }
   void setGhostType(GhostType new_type) { ghost_type = new_type; }
   AKANTU_GET_MACRO(NewNodePerElem, *new_node_per_elem, const Array<UInt> &);
   AKANTU_GET_MACRO(ElementType, type, ElementType);
   AKANTU_GET_MACRO(GhostType, ghost_type, GhostType);
 
 protected:
   ElementType type;
   GhostType ghost_type;
   const Array<UInt> * new_node_per_elem;
 };
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> class MeshIgfemSphericalGrowingGel {
+template <Int dim> class MeshIgfemSphericalGrowingGel {
 // definition of the element list
 #define ELEMENT_LIST (_triangle_3)(_igfem_triangle_4)(_igfem_triangle_5)
 
 // Solution 1
 /* #define INTERSECTOR_DEFINITION(type)			\
    MeshSphereIntersector<2, type> intersector##type(mesh);*/
 
 // Solution 2
 #define INSTANTIATOR(_type)                                                    \
   intersectors(_type, ghost_type) =                                            \
       new MeshSphereIntersector<dim, _type>(this->mesh)
 
   /* --------------------------------------------------------------------------
    */
   /* Constructor/Destructor */
   /* --------------------------------------------------------------------------
    */
 
 public:
   /// Construct from mesh
   MeshIgfemSphericalGrowingGel(Mesh & mesh);
 
   /// Destructor
   ~MeshIgfemSphericalGrowingGel() {
     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(dim, ghost_type, _ek_not_defined);
       Mesh::type_iterator end = mesh.lastType(dim, ghost_type, _ek_not_defined);
 
       for (; it != end; ++it) {
         delete intersectors(*it, ghost_type);
       }
     }
   }
 
   /* --------------------------------------------------------------------------
    */
   /* Methods */
   /* --------------------------------------------------------------------------
    */
 public:
   void init();
 
   /// Remove the additionnal nodes
   void removeAdditionalNodes();
 
   /// Compute the intersection points between the mesh and the query list for
   /// all element types and send the NewNodeEvent
   void computeMeshQueryListIntersectionPoint(
       const std::list<SK::Sphere_3> & query_list);
 
   /// increase sphere radius and build the new intersection points between the
   /// mesh and the query list for all element types and send the NewNodeEvent
   void computeMeshQueryListIntersectionPoint(
       const std::list<SK::Sphere_3> & query_list, Real inf_fact) {
     std::list<SK::Sphere_3>::const_iterator query_it = query_list.begin(),
                                             query_end = query_list.end();
     std::list<SK::Sphere_3> sphere_list;
     for (; query_it != query_end; ++query_it) {
       SK::Sphere_3 sphere(query_it->center(),
                           query_it->squared_radius() * inf_fact * inf_fact);
       sphere_list.push_back(sphere);
     }
     computeMeshQueryListIntersectionPoint(sphere_list);
   }
 
   /// Build the IGFEM mesh from intersection points
   void buildIGFEMMesh();
 
   /// Build the IGFEM mesh from spheres
   void buildIGFEMMeshFromSpheres(const std::list<SK::Sphere_3> & query_list) {
     computeMeshQueryListIntersectionPoint(query_list);
     buildIGFEMMesh();
   }
 
   /// Build the IGFEM mesh from spheres with increase factor
   void buildIGFEMMeshFromSpheres(const std::list<SK::Sphere_3> & query_list,
                                  Real inf_fact) {
     computeMeshQueryListIntersectionPoint(query_list, inf_fact);
     buildIGFEMMesh();
   }
 
   /// set the distributed synchronizer
   void setDistributedSynchronizer(DistributedSynchronizer * dist) {
     synchronizer = dist;
     buildSegmentConnectivityToNodeType();
   }
 
   /// update node type
   void updateNodeType(const Array<UInt> & nodes_list,
                       const Array<UInt> & new_node_per_elem, ElementType type,
                       GhostType ghost_type);
 
 protected:
   /// Build the unordered_map needed to assign the node type to new nodes in
   /// parallel
   void buildSegmentConnectivityToNodeType();
 
   /* --------------------------------------------------------------------------
    */
   /* Accessors */
   /* --------------------------------------------------------------------------
    */
 public:
   AKANTU_GET_MACRO(NbStandardNodes, nb_nodes_fem, UInt);
   AKANTU_GET_MACRO(NbEnrichedNodes, nb_enriched_nodes, UInt);
 
   /* --------------------------------------------------------------------------
    */
   /* Class Members */
   /* --------------------------------------------------------------------------
    */
 protected:
   /// Mesh used to construct the primitives
   Mesh & mesh;
 
   /// number of fem nodes in the initial mesh
   UInt nb_nodes_fem;
 
   /// number of enriched nodes before intersection
   UInt nb_enriched_nodes;
 
   // Solution 2
   /// map of the elements types in the mesh and the corresponding intersectors
   ElementTypeMap<MeshAbstractIntersector<SK::Sphere_3> *> intersectors;
 
   /// Map linking pairs of nodes to a node type. The pairs of nodes
   /// contain the connectivity of the primitive segments that are
   /// intersected.
   unordered_map<std::pair<UInt, UInt>, Int>::type segment_conn_to_node_type;
 
   /// Pointer to the distributed synchronizer of the model
   DistributedSynchronizer * synchronizer;
 };
 
 } // namespace akantu
 
 #include "mesh_igfem_spherical_growing_gel_tmpl.hh"
 
 #endif // AKANTU_MESH_IGFEM_SPHERICAL_GROWING_GEL_HH_
 
 //#endif //
diff --git a/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel_tmpl.hh b/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel_tmpl.hh
index 7dc5c855e..d9e9ce065 100644
--- a/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel_tmpl.hh
+++ b/extra_packages/igfem/src/mesh_igfem_spherical_growing_gel_tmpl.hh
@@ -1,531 +1,531 @@
 /**
  * @file   mesh_igfem_spherical_growing_gel.cc
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  * @date   Mon Sep 21 12:42:11 2015
  *
  * @brief  Implementation of the functions of MeshIgfemSphericalGrowingGel
  *
  *
  * 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_utils.hh"
 #include <algorithm>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MeshIgfemSphericalGrowingGel<dim>::MeshIgfemSphericalGrowingGel(Mesh & mesh)
     : mesh(mesh), nb_nodes_fem(mesh.getNbNodes()), nb_enriched_nodes(0),
       synchronizer(NULL) {}
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MeshIgfemSphericalGrowingGel<dim>::init() {
+template <Int dim> void MeshIgfemSphericalGrowingGel<dim>::init() {
   nb_nodes_fem = mesh.getNbNodes();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
 
     Mesh::type_iterator tit = mesh.firstType(dim, ghost_type);
     Mesh::type_iterator tend = mesh.lastType(dim, ghost_type);
     for (; tit != tend;
          ++tit) { // loop to add corresponding IGFEM element types
       if (*tit == _triangle_3) {
         mesh.addConnectivityType(_igfem_triangle_4, ghost_type);
         mesh.addConnectivityType(_igfem_triangle_5, ghost_type);
       } else
         AKANTU_ERROR("Not ready for mesh type " << *tit);
     }
 
     tit = mesh.firstType(dim, ghost_type, _ek_not_defined);
     tend = mesh.lastType(dim, ghost_type, _ek_not_defined);
     for (; tit != tend; ++tit) {
       AKANTU_BOOST_LIST_SWITCH(INSTANTIATOR, ELEMENT_LIST, *tit);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MeshIgfemSphericalGrowingGel<dim>::computeMeshQueryListIntersectionPoint(
     const std::list<SK::Sphere_3> & query_list) {
   /// store number of currently enriched nodes
   this->nb_enriched_nodes = mesh.getNbNodes() - nb_nodes_fem;
   UInt nb_old_nodes = mesh.getNbNodes();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
 
     Mesh::type_iterator iit = mesh.firstType(dim, ghost_type, _ek_not_defined);
     Mesh::type_iterator iend = mesh.lastType(dim, ghost_type, _ek_not_defined);
     for (; iit != iend; ++iit) {
       MeshAbstractIntersector<SK::Sphere_3> & intersector =
           *intersectors(*iit, ghost_type);
       intersector.constructData(ghost_type);
       intersector.computeMeshQueryListIntersectionPoint(query_list,
                                                         nb_old_nodes);
       const Array<Real> intersection_points_current_type =
           *(intersector.getIntersectionPoints());
       const Array<UInt> & new_node_per_elem = intersector.getNewNodePerElem();
 
       /// Send the new node event
       UInt new_points = intersection_points_current_type.getSize();
       StaticCommunicator::getStaticCommunicator().allReduce(&new_points, 1,
                                                             _so_sum);
 
       if (new_points > 0) {
         Array<Real> & nodes = this->mesh.getNodes();
         UInt nb_node = nodes.getSize();
 
         Array<Real>::const_vector_iterator intersec_p_it =
             intersection_points_current_type.begin(dim);
 
         NewIGFEMNodesEvent new_nodes_event;
         for (UInt in = 0; in < intersection_points_current_type.getSize();
              ++in, ++intersec_p_it) {
           nodes.push_back(*intersec_p_it);
           new_nodes_event.getList().push_back(nb_node + in);
         }
         new_nodes_event.setNewNodePerElem(new_node_per_elem);
         new_nodes_event.setType(*iit);
         new_nodes_event.setGhostType(ghost_type);
         this->mesh.sendEvent(new_nodes_event);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MeshIgfemSphericalGrowingGel<dim>::removeAdditionalNodes() {
   AKANTU_DEBUG_IN();
 
   UInt total_nodes = this->mesh.getNbNodes();
   UInt nb_new_enriched_nodes =
       total_nodes - this->nb_enriched_nodes - this->nb_nodes_fem;
   UInt old_total_nodes = this->nb_nodes_fem + this->nb_enriched_nodes;
 
   UInt total_new_nodes = nb_new_enriched_nodes;
   StaticCommunicator::getStaticCommunicator().allReduce(&total_new_nodes, 1,
                                                         _so_sum);
   if (total_new_nodes == 0)
     return;
 
   RemovedNodesEvent remove_nodes(this->mesh);
   Array<UInt> & nodes_removed = remove_nodes.getList();
   Array<UInt> & new_numbering = remove_nodes.getNewNumbering();
 
   for (UInt nnod = 0; nnod < this->nb_nodes_fem; ++nnod) {
     new_numbering(nnod) = nnod;
   }
 
   for (UInt nnod = nb_nodes_fem; nnod < old_total_nodes; ++nnod) {
     new_numbering(nnod) = UInt(-1);
     nodes_removed.push_back(nnod);
   }
 
   for (UInt nnod = 0; nnod < nb_new_enriched_nodes; ++nnod) {
     new_numbering(nnod + old_total_nodes) = this->nb_nodes_fem + nnod;
   }
 
   if (nb_new_enriched_nodes > 0) {
     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;
         Array<UInt> & connectivity_array =
             mesh.getConnectivity(type, ghost_type);
         UInt nb_nodes_per_element = connectivity_array.getNbComponent();
 
         Array<UInt>::vector_iterator conn_it =
             connectivity_array.begin(nb_nodes_per_element);
         Array<UInt>::vector_iterator conn_end =
             connectivity_array.end(nb_nodes_per_element);
 
         for (; conn_it != conn_end; ++conn_it) {
           for (UInt n = 0; n < nb_nodes_per_element; ++n) {
             (*conn_it)(n) = new_numbering((*conn_it)(n));
           }
         }
       }
     }
   }
 
   this->mesh.sendEvent(remove_nodes);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MeshIgfemSphericalGrowingGel<dim>::buildIGFEMMesh() {
+template <Int dim> void MeshIgfemSphericalGrowingGel<dim>::buildIGFEMMesh() {
   AKANTU_DEBUG_IN();
 
   NewIGFEMElementsEvent new_elements_event;
   UInt total_new_elements = 0;
   Array<Element> & new_elements_list = new_elements_event.getList();
   Array<Element> & old_elements_list = new_elements_event.getOldElementsList();
   RemovedElementsEvent removed_elements_event(this->mesh);
   ChangedElementsEvent changed_elements_event(this->mesh);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
 
     mesh.initElementTypeMapArray(removed_elements_event.getNewNumbering(), 1,
                                  dim, ghost_type, false, _ek_not_defined);
     mesh.initElementTypeMapArray(changed_elements_event.getNewNumbering(), 1,
                                  dim, ghost_type, false, _ek_not_defined);
 
     /// loop over all types in the mesh for a given ghost type
     Mesh::type_iterator iit = mesh.firstType(dim, ghost_type, _ek_not_defined);
     Mesh::type_iterator iend = mesh.lastType(dim, ghost_type, _ek_not_defined);
     for (; iit != iend; ++iit) {
       ElementType type = *iit;
 
       MeshAbstractIntersector<SK::Sphere_3> & intersector =
           *intersectors(type, ghost_type);
       const Array<UInt> & new_node_per_elem = intersector.getNewNodePerElem();
 
       UInt n_new_el = 0;
       Array<UInt> & connectivity = this->mesh.getConnectivity(type, ghost_type);
 
       /// get the connectivities of all types that that may transform
       Array<UInt> & connec_igfem_tri_4 =
           this->mesh.getConnectivity(_igfem_triangle_4, ghost_type);
       Array<UInt> & connec_igfem_tri_5 =
           this->mesh.getConnectivity(_igfem_triangle_5, ghost_type);
       Array<UInt> & connec_tri_3 =
           this->mesh.getConnectivity(_triangle_3, ghost_type);
 
       /// create elements to store the newly generated elements
       Element el_tri_3(_triangle_3, 0, ghost_type, _ek_regular);
       Element el_igfem_tri_4(_igfem_triangle_4, 0, ghost_type, _ek_igfem);
       Element el_igfem_tri5(_igfem_triangle_5, 0, ghost_type, _ek_igfem);
 
       Array<UInt> & new_numbering =
           removed_elements_event.getNewNumbering(type, ghost_type);
       new_numbering.resize(connectivity.getSize());
       /// container for element to be removed
       Element old_element(type, 0, ghost_type, Mesh::getKind(type));
 
       for (UInt nel = 0; nel != new_node_per_elem.getSize(); ++nel) {
         /// a former IGFEM triangle is transformed into a regular triangle
         if ((type != _triangle_3) && (new_node_per_elem(nel, 0) == 0)) {
 
           Vector<UInt> connec_new_elem(3);
           connec_new_elem(0) = connectivity(nel, 0);
           connec_new_elem(1) = connectivity(nel, 1);
           connec_new_elem(2) = connectivity(nel, 2);
           /// add the new element in the mesh
           UInt nb_triangles_3 = connec_tri_3.getSize();
           connec_tri_3.push_back(connec_new_elem);
           el_tri_3.element = nb_triangles_3;
           new_elements_list.push_back(el_tri_3);
           /// the number of the old element in the mesh
           old_element.element = nel;
           old_elements_list.push_back(old_element);
           new_numbering(nel) = UInt(-1);
           ++n_new_el;
         }
 
         /// element is enriched
         else if (new_node_per_elem(nel, 0) != 0) {
           switch (new_node_per_elem(nel, 0)) {
           /// new element is of type igfem_triangle_4
           case 1: {
             Vector<UInt> connec_new_elem(4);
             switch (new_node_per_elem(nel, 2)) {
             case 0:
               connec_new_elem(0) = connectivity(nel, 2);
               connec_new_elem(1) = connectivity(nel, 0);
               connec_new_elem(2) = connectivity(nel, 1);
               break;
             case 1:
               connec_new_elem(0) = connectivity(nel, 0);
               connec_new_elem(1) = connectivity(nel, 1);
               connec_new_elem(2) = connectivity(nel, 2);
               break;
             case 2:
               connec_new_elem(0) = connectivity(nel, 1);
               connec_new_elem(1) = connectivity(nel, 2);
               connec_new_elem(2) = connectivity(nel, 0);
               break;
             default:
               AKANTU_ERROR("A triangle has only 3 segments not "
                            << new_node_per_elem(nel, 2));
               break;
             }
             connec_new_elem(3) = new_node_per_elem(nel, 1);
             UInt nb_igfem_triangles_4 = connec_igfem_tri_4.getSize();
             connec_igfem_tri_4.push_back(connec_new_elem);
             el_igfem_tri_4.element = nb_igfem_triangles_4;
             new_elements_list.push_back(el_igfem_tri_4);
             break;
           }
           /// new element is of type igfem_triangle_5
           case 2: {
             Vector<UInt> connec_new_elem(5);
             if ((new_node_per_elem(nel, 2) == 0) &&
                 (new_node_per_elem(nel, 4) == 1)) {
               connec_new_elem(0) = connectivity(nel, 1);
               connec_new_elem(1) = connectivity(nel, 2);
               connec_new_elem(2) = connectivity(nel, 0);
               connec_new_elem(3) = new_node_per_elem(nel, 3);
               connec_new_elem(4) = new_node_per_elem(nel, 1);
             } else if ((new_node_per_elem(nel, 2) == 0) &&
                        (new_node_per_elem(nel, 4) == 2)) {
               connec_new_elem(0) = connectivity(nel, 0);
               connec_new_elem(1) = connectivity(nel, 1);
               connec_new_elem(2) = connectivity(nel, 2);
               connec_new_elem(3) = new_node_per_elem(nel, 1);
               connec_new_elem(4) = new_node_per_elem(nel, 3);
             } else if ((new_node_per_elem(nel, 2) == 1) &&
                        (new_node_per_elem(nel, 4) == 2)) {
               connec_new_elem(0) = connectivity(nel, 2);
               connec_new_elem(1) = connectivity(nel, 0);
               connec_new_elem(2) = connectivity(nel, 1);
               connec_new_elem(3) = new_node_per_elem(nel, 3);
               connec_new_elem(4) = new_node_per_elem(nel, 1);
             } else if ((new_node_per_elem(nel, 2) == 1) &&
                        (new_node_per_elem(nel, 4) == 0)) {
               connec_new_elem(0) = connectivity(nel, 1);
               connec_new_elem(1) = connectivity(nel, 2);
               connec_new_elem(2) = connectivity(nel, 0);
               connec_new_elem(3) = new_node_per_elem(nel, 1);
               connec_new_elem(4) = new_node_per_elem(nel, 3);
             } else if ((new_node_per_elem(nel, 2) == 2) &&
                        (new_node_per_elem(nel, 4) == 0)) {
               connec_new_elem(0) = connectivity(nel, 0);
               connec_new_elem(1) = connectivity(nel, 1);
               connec_new_elem(2) = connectivity(nel, 2);
               connec_new_elem(3) = new_node_per_elem(nel, 3);
               connec_new_elem(4) = new_node_per_elem(nel, 1);
             } else if ((new_node_per_elem(nel, 2) == 2) &&
                        (new_node_per_elem(nel, 4) == 1)) {
               connec_new_elem(0) = connectivity(nel, 2);
               connec_new_elem(1) = connectivity(nel, 0);
               connec_new_elem(2) = connectivity(nel, 1);
               connec_new_elem(3) = new_node_per_elem(nel, 1);
               connec_new_elem(4) = new_node_per_elem(nel, 3);
             } else
               AKANTU_ERROR("A triangle has only 3 segments (0 to 2) not "
                            << new_node_per_elem(nel, 2) << "and"
                            << new_node_per_elem(nel, 4));
 
             UInt nb_igfem_triangles_5 = connec_igfem_tri_5.getSize();
             connec_igfem_tri_5.push_back(connec_new_elem);
             el_igfem_tri5.element = nb_igfem_triangles_5;
             new_elements_list.push_back(el_igfem_tri5);
             break;
           }
           default:
             AKANTU_ERROR("IGFEM cannot add " << new_node_per_elem(nel, 0)
                                              << " nodes to triangles");
             break;
           }
           old_element.element = nel;
           old_elements_list.push_back(old_element);
           new_numbering(nel) = UInt(-1);
           ++n_new_el;
         }
       }
       total_new_elements += n_new_el;
     }
   }
 
   /// update new numbering
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
     /// loop over all types in the mesh for a given ghost type
     Mesh::type_iterator iit = mesh.firstType(dim, ghost_type, _ek_not_defined);
     Mesh::type_iterator iend = mesh.lastType(dim, ghost_type, _ek_not_defined);
     for (; iit != iend; ++iit) {
       ElementType type = *iit;
       Array<UInt> & new_numbering =
           removed_elements_event.getNewNumbering(type, ghost_type);
       UInt el_index = 0;
       UInt nb_element = this->mesh.getNbElement(type, ghost_type);
       new_numbering.resize(nb_element);
       for (UInt e = 0; e < nb_element; ++e) {
         if (new_numbering(e) != UInt(-1)) {
           new_numbering(e) = el_index;
           ++el_index;
         }
       }
       changed_elements_event.getNewNumbering(type, ghost_type)
           .copy(new_numbering);
     }
   }
 
   StaticCommunicator::getStaticCommunicator().allReduce(&total_new_elements, 1,
                                                         _so_sum);
 
   if (total_new_elements > 0) {
     changed_elements_event.getListOld().copy(
         new_elements_event.getOldElementsList());
     changed_elements_event.getListNew().copy(new_elements_event.getList());
     this->mesh.sendEvent(changed_elements_event);
 
     this->mesh.sendEvent(new_elements_event);
 
     Array<Element> & removed_list = removed_elements_event.getList();
     removed_list.copy(new_elements_event.getOldElementsList());
     this->mesh.sendEvent(removed_elements_event);
   }
 
   removeAdditionalNodes();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MeshIgfemSphericalGrowingGel<dim>::buildSegmentConnectivityToNodeType() {
   Mesh mesh_facets(mesh.initMeshFacets());
   MeshUtils::buildSegmentToNodeType(mesh, mesh_facets, synchronizer);
 
   // only the ghost elements are considered
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     GhostType ghost_type = (GhostType)g;
 
     Mesh::type_iterator it = mesh_facets.firstType(1, ghost_type);
     Mesh::type_iterator end = mesh_facets.lastType(1, ghost_type);
     for (; it != end; ++it) {
       ElementType type = *it;
 
       const Array<Int> & segment_to_nodetype =
           mesh_facets.getData<Int>("segment_to_nodetype", type, ghost_type);
 
       const Array<UInt> & segment_connectivity =
           mesh_facets.getConnectivity(type, ghost_type);
 
       // looping over all the segments
       Array<UInt>::const_vector_iterator conn_it =
           segment_connectivity.begin(segment_connectivity.getNbComponent());
       Array<UInt>::const_vector_iterator conn_end =
           segment_connectivity.end(segment_connectivity.getNbComponent());
       UInt seg_index = 0;
 
       UInt n[2];
       for (; conn_it != conn_end; ++conn_it, ++seg_index) {
         Int seg_type = segment_to_nodetype(seg_index);
         n[0] = (*conn_it)(0);
         n[1] = (*conn_it)(1);
 
         if ((mesh.isMasterNode(n[0]) || mesh.isSlaveNode(n[0])) &&
             (mesh.isMasterNode(n[1]) || mesh.isSlaveNode(n[1]))) {
           std::sort(n, n + 2);
           segment_conn_to_node_type[std::make_pair(n[0], n[1])] = seg_type;
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MeshIgfemSphericalGrowingGel<dim>::updateNodeType(
     const Array<UInt> & nodes_list, const Array<UInt> & new_node_per_elem,
     ElementType type, GhostType ghost_type) {
   Array<Int> & nodes_type = mesh.getNodesType();
   UInt old_nodes = nodes_type.getSize();
   UInt new_nodes = nodes_list.getSize();
 
   // exit this function if the simulation in run in serial
   if (old_nodes == 0 || new_nodes == 0)
     return;
 
   nodes_type.resize(old_nodes + new_nodes);
   Array<bool> checked_node(new_nodes, 1, false);
 
   UInt nb_prim_by_el = 0;
   if ((type == _triangle_3) || (type == _igfem_triangle_4) ||
       (type == _igfem_triangle_5)) {
     nb_prim_by_el = 3;
   } else {
     AKANTU_ERROR("Not ready for mesh type " << type);
   }
 
   // determine the node type for the local, master and slave nodes
   const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
   unordered_map<std::pair<UInt, UInt>, Int>::type::iterator seg_type_it;
   unordered_map<std::pair<UInt, UInt>, Int>::type::iterator seg_type_end =
       segment_conn_to_node_type.end();
 
   for (UInt el = 0; el < new_node_per_elem.getSize(); ++el) {
     UInt nb_nodes = new_node_per_elem(el, 0);
 
     for (UInt n = 0; n < nb_nodes; ++n) {
       UInt node_index = new_node_per_elem(el, 2 * n + 1);
       if (node_index < old_nodes || checked_node(node_index - old_nodes))
         continue;
 
       // get the elemental connectivity of the segment associated to the node
       UInt segment_index = new_node_per_elem(el, 2 * n + 2);
 
       UInt extreme_nodes[2];
       extreme_nodes[0] = segment_index;
       extreme_nodes[1] = segment_index + 1;
       if (extreme_nodes[1] == nb_prim_by_el)
         extreme_nodes[1] = 0;
 
       // get the connectivity of the segment
       extreme_nodes[0] = connectivity(el, extreme_nodes[0]);
       extreme_nodes[1] = connectivity(el, extreme_nodes[1]);
 
       // if one extreme nodes is pure ghost, then also the new node is pure
       // ghost
       if (mesh.isPureGhostNode(extreme_nodes[0]) ||
           mesh.isPureGhostNode(extreme_nodes[1]))
         nodes_type(node_index) = -3;
       // if on of the two extreme nodes is local, then also the new node is
       // local
       else if (mesh.isLocalNode(extreme_nodes[0]) ||
                mesh.isLocalNode(extreme_nodes[1]))
         nodes_type(node_index) = -1;
 
       // otherwise use the value stored in the map
       else {
         std::sort(extreme_nodes, extreme_nodes + 2);
 
         seg_type_it = segment_conn_to_node_type.find(
             std::make_pair(extreme_nodes[0], extreme_nodes[1]));
 
         AKANTU_DEBUG_ASSERT(seg_type_it != seg_type_end, "Segment not found");
 
         nodes_type(node_index) = seg_type_it->second;
       }
 
       checked_node(node_index - old_nodes) = true;
     }
   }
 
   AKANTU_DEBUG_ASSERT(std::accumulate(checked_node.begin(), checked_node.end(),
                                       0) == Int(checked_node.getSize()),
                       "Not all new nodes were assigned a node type");
 }
 
 } // namespace akantu
diff --git a/extra_packages/igfem/src/shape_igfem.hh b/extra_packages/igfem/src/shape_igfem.hh
index 537f6b401..b5210437e 100644
--- a/extra_packages/igfem/src/shape_igfem.hh
+++ b/extra_packages/igfem/src/shape_igfem.hh
@@ -1,199 +1,199 @@
 /**
  * @file   shape_igfem.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  shape functions for interface-enriched generalized FEM
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "shape_functions.hh"
 
 #ifndef AKANTU_SHAPE_IGFEM_HH_
 #define AKANTU_SHAPE_IGFEM_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <> class ShapeLagrange<_ek_igfem> : public ShapeFunctions {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ShapeLagrange(const Mesh & mesh, const ID & id = "shape_igfem");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   inline void initShapeFunctions(const Array<Real> & nodes,
                                  const Matrix<Real> & integration_points,
                                  const Matrix<Real> & integration_points_1,
                                  const Matrix<Real> & integration_points_2,
                                  ElementType type,
                                  GhostType ghost_type);
 
   inline void
   interpolateEnrichmentsAllTypes(const Array<Real> & src, Array<Real> & dst,
                                  ElementType type,
                                  GhostType ghost_type) const;
 
   template <ElementType type>
   inline void precomputeShapesOnEnrichedNodes(const Array<Real> & nodes,
                                               GhostType ghost_type);
 
   template <ElementType type>
   void interpolateAtEnrichedNodes(const Array<Real> & src, Array<Real> & dst,
                                   GhostType ghost_type) const;
 
   /// 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>
   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;
+      const Array<Int> & 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,
                    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;
+      const Array<Int> & 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 in parent element from real coords provided an element
   template <ElementType type>
   void inverseMap(const Vector<Real> & real_coords, UInt element,
                   Vector<Real> & natural_coords,
                   GhostType ghost_type = _not_ghost) const;
 
   /// find natural coords in sub-element from real coords provided an element
   template <ElementType type>
   void inverseMap(const Vector<Real> & real_coords, UInt element,
                   Vector<Real> & natural_coords, UInt sub_element,
                   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,
                 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, 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,
                                GhostType ghost_type) const;
 
   /// interpolate a field on a given physical point
   template <ElementType type>
   void interpolateOnPhysicalPoint(const Vector<Real> & real_coords, UInt elem,
                                   const Array<Real> & field,
                                   Vector<Real> & interpolated,
                                   GhostType ghost_type) const;
 
   /// function to extract values at standard nodes and zero-out enriched values
   /// of a nodal field
   void extractValuesAtStandardNodes(const Array<Real> & nodal_values,
                                     Array<Real> & extracted_values,
                                     GhostType ghost_type) const;
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) 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;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get a the shapes vector
   inline const Array<Real> &
   getShapes(ElementType el_type,
             GhostType ghost_type = _not_ghost) const;
 
   /// get a the shapes derivatives vector
   inline const Array<Real> &
   getShapesDerivatives(ElementType el_type,
                        GhostType ghost_type = _not_ghost) const;
 
   /// get a the shapes vector
   inline const Array<Real> &
   getShapesAtEnrichedNodes(ElementType el_type,
                            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;
 
   /// additional integration points for the IGFEM formulation
   ElementTypeMapArray<Real> igfem_integration_points;
 
   /// values of shape functions for all elements on the enriched nodes
   ElementTypeMapArray<Real, InterpolationType> shapes_at_enrichments;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "shape_igfem_inline_impl.hh"
 /// standard output stream operator
 // template <class ShapeFunction>
 // inline std::ostream & operator <<(std::ostream & stream, const
 // ShapeIGFEM<ShapeFunction> & _this)
 // {
 //   _this.printself(stream);
 //   return stream;
 // }
 
 #endif /* AKANTU_SHAPE_IGFEM_HH_ */
diff --git a/extra_packages/igfem/src/shape_igfem_inline_impl.hh b/extra_packages/igfem/src/shape_igfem_inline_impl.hh
index e72aaba33..54a176dd9 100644
--- a/extra_packages/igfem/src/shape_igfem_inline_impl.hh
+++ b/extra_packages/igfem/src/shape_igfem_inline_impl.hh
@@ -1,733 +1,733 @@
 /**
  * @file   shape_igfem_inline_impl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  *
  * @brief  ShapeIGFEM inline implementation
  *
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_SHAPE_IGFEM_INLINE_IMPL_HH_
 #define AKANTU_SHAPE_IGFEM_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Real> &
 ShapeLagrange<_ek_igfem>::getShapes(ElementType el_type,
                                     GhostType ghost_type) const {
   return shapes(FEEngine::getInterpolationType(el_type), ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Real> & ShapeLagrange<_ek_igfem>::getShapesDerivatives(
     ElementType el_type, GhostType ghost_type) const {
   return shapes_derivatives(FEEngine::getInterpolationType(el_type),
                             ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 #define INIT_SHAPE_FUNCTIONS(type)                                             \
   setIntegrationPointsByType<type>(integration_points, ghost_type);            \
   setIntegrationPointsByType<ElementClassProperty<type>::sub_element_type_1>(  \
       integration_points_1, ghost_type);                                       \
   setIntegrationPointsByType<ElementClassProperty<type>::sub_element_type_2>(  \
       integration_points_2, ghost_type);                                       \
   precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type);                \
   if (ElementClass<type>::getNaturalSpaceDimension() ==                        \
       mesh.getSpatialDimension())                                              \
     precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);    \
   precomputeShapesOnEnrichedNodes<type>(nodes, ghost_type);
 
 inline void ShapeLagrange<_ek_igfem>::initShapeFunctions(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     const Matrix<Real> & integration_points_1,
     const Matrix<Real> & integration_points_2, ElementType type,
     GhostType ghost_type) {
 
   AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
 }
 #undef INIT_SHAPE_FUNCTIONS
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 inline void ShapeLagrange<_ek_igfem>::computeShapeDerivativesOnCPointsByElement(
     const Matrix<Real> & node_coords, const Matrix<Real> & natural_coords,
     Tensor3<Real> & shapesd) const {
   AKANTU_DEBUG_IN();
 
   // compute dnds
   Tensor3<Real> dnds(node_coords.rows(), node_coords.cols(),
                      natural_coords.cols());
   ElementClass<type>::computeDNDS(natural_coords, dnds);
   // compute dxds
   Tensor3<Real> J(node_coords.rows(), natural_coords.rows(),
                   natural_coords.cols());
   ElementClass<type>::computeJMat(dnds, node_coords, J);
 
   // compute shape derivatives
   ElementClass<type>::computeShapeDerivatives(J, dnds, shapesd);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::inverseMap(const Vector<Real> & real_coords,
                                           UInt elem,
                                           Vector<Real> & natural_coords,
                                           UInt sub_element,
                                           GhostType ghost_type) const {
 
   AKANTU_DEBUG_IN();
   /// typedef for the two subelement_types and the parent element type
   const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
   const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
   Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
 
   mesh.extractNodalValuesFromElement(mesh.getNodes(), nodes_coord.storage(),
                                      elem_val + elem * nb_nodes_per_element,
                                      nb_nodes_per_element, spatial_dimension);
 
   if (!sub_element) {
     UInt nb_nodes_sub_el =
         ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
     Matrix<Real> sub_el_coords(spatial_dimension, nb_nodes_sub_el);
     ElementClass<type>::getSubElementCoords(nodes_coord, sub_el_coords,
                                             sub_element);
     ElementClass<sub_type_1>::inverseMap(real_coords, sub_el_coords,
                                          natural_coords);
   }
 
   else {
     UInt nb_nodes_sub_el =
         ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
     Matrix<Real> sub_el_coords(spatial_dimension, nb_nodes_sub_el);
     ElementClass<type>::getSubElementCoords(nodes_coord, sub_el_coords,
                                             sub_element);
     ElementClass<sub_type_2>::inverseMap(real_coords, sub_el_coords,
                                          natural_coords);
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::inverseMap(const Vector<Real> & real_coords,
                                           UInt elem,
                                           Vector<Real> & natural_coords,
                                           GhostType ghost_type) const {
 
   /// map point into parent reference domain
   AKANTU_DEBUG_IN();
 
   const ElementType parent_type =
       ElementClassProperty<type>::parent_element_type;
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
   Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
 
   mesh.extractNodalValuesFromElement(mesh.getNodes(), nodes_coord.storage(),
                                      elem_val + elem * nb_nodes_per_element,
                                      nb_nodes_per_element, spatial_dimension);
 
   UInt nb_nodes_parent_el =
       ElementClass<parent_type>::getNbNodesPerInterpolationElement();
   Matrix<Real> parent_coords(spatial_dimension, nb_nodes_parent_el);
   ElementClass<type>::getParentCoords(nodes_coord, parent_coords);
   ElementClass<parent_type>::inverseMap(real_coords, parent_coords,
                                         natural_coords);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 bool ShapeLagrange<_ek_igfem>::contains(const Vector<Real> & real_coords,
                                         UInt elem,
                                         GhostType ghost_type) const {
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   Vector<Real> natural_coords(spatial_dimension);
 
   inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
   return ElementClass<type>::contains(natural_coords);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::interpolate(const Vector<Real> & real_coords,
                                            UInt elem,
                                            const Matrix<Real> & nodal_values,
                                            Vector<Real> & interpolated,
                                            GhostType ghost_type) const {
   UInt nb_shapes = ElementClass<type>::getShapeSize();
   Vector<Real> shapes(nb_shapes);
   computeShapes<type>(real_coords, elem, shapes, ghost_type);
   ElementClass<type>::interpolate(nodal_values, shapes, interpolated);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::computeShapes(
     const Vector<Real> & real_coords, UInt elem, Vector<Real> & shapes,
     GhostType ghost_type) const {
 
   AKANTU_DEBUG_IN();
   /// typedef for the two subelement_types and the parent element type
   const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
   const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
   const ElementType parent_type =
       ElementClassProperty<type>::parent_element_type;
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   /// parent contribution
   /// get the size of the parent shapes
   UInt size_of_parent_shapes = ElementClass<parent_type>::getShapeSize();
   Vector<Real> parent_shapes(size_of_parent_shapes);
 
   /// compute parent shapes -> map shapes in the physical domain of the parent
   Vector<Real> natural_coords(spatial_dimension);
   Real tol = Math::getTolerance();
   Math::setTolerance(1e-14);
   inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
   ElementClass<parent_type>::computeShapes(natural_coords, parent_shapes);
   natural_coords.zero();
 
   /// sub-element contribution
   /// check which sub-element contains the physical point
   /// check if point is in sub-element 1
   inverseMap<type>(real_coords, elem, natural_coords, 0, ghost_type);
   if (ElementClass<sub_type_1>::contains(natural_coords)) {
     UInt size_of_sub_shapes = ElementClass<sub_type_1>::getShapeSize();
     Vector<Real> sub_shapes(size_of_sub_shapes);
     ElementClass<sub_type_1>::computeShapes(natural_coords, sub_shapes);
     /// assemble shape functions
     ElementClass<type>::assembleShapes(parent_shapes, sub_shapes, shapes, 0);
   } else {
     natural_coords.zero();
     inverseMap<type>(real_coords, elem, natural_coords, 1, ghost_type);
 
     AKANTU_DEBUG_ASSERT(ElementClass<sub_type_2>::contains(natural_coords),
                         "Physical point not contained in any element");
 
     UInt size_of_sub_shapes = ElementClass<sub_type_2>::getShapeSize();
     Vector<Real> sub_shapes(size_of_sub_shapes);
     ElementClass<sub_type_2>::computeShapes(natural_coords, sub_shapes);
     /// assemble shape functions
     ElementClass<type>::assembleShapes(parent_shapes, sub_shapes, shapes, 1);
   }
 
   Math::setTolerance(tol);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::computeShapeDerivatives(
     const Matrix<Real> & real_coords, UInt elem, Tensor3<Real> & shapesd,
     GhostType ghost_type) const {
 
   AKANTU_DEBUG_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::precomputeShapesOnIntegrationPoints(
     __attribute__((unused)) const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
 
   /// typedef for the two subelement_types and the parent element type
   const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
   const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
   const ElementType parent_type =
       ElementClassProperty<type>::parent_element_type;
 
   /// get the spatial dimension for the given element type
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
   /// get the integration points for the subelements
   Matrix<Real> & natural_coords_sub_1 =
       integration_points(sub_type_1, ghost_type);
   Matrix<Real> & natural_coords_sub_2 =
       integration_points(sub_type_2, ghost_type);
 
   /// store the number of quadrature points on each subelement and the toal
   /// number
   UInt nb_points_sub_1 = natural_coords_sub_1.cols();
   UInt nb_points_sub_2 = natural_coords_sub_2.cols();
   UInt nb_total_points = nb_points_sub_1 + nb_points_sub_2;
 
   // get the integration points for the parent element
   UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
   Array<Real> & natural_coords_parent = igfem_integration_points.alloc(
       nb_element * nb_total_points, spatial_dimension, type, ghost_type);
   Array<Real>::matrix_iterator natural_coords_parent_it =
       natural_coords_parent.begin_reinterpret(spatial_dimension,
                                               nb_total_points, nb_element);
 
   /// get the size of the shapes
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
   UInt size_of_parent_shapes = ElementClass<parent_type>::getShapeSize();
   UInt size_of_sub_1_shapes = ElementClass<sub_type_1>::getShapeSize();
   UInt size_of_sub_2_shapes = ElementClass<sub_type_2>::getShapeSize();
 
   /// initialize the matrices to store the shape functions of the subelements
   /// and the parent
   Matrix<Real> sub_1_shapes(size_of_sub_1_shapes, nb_points_sub_1);
   Matrix<Real> sub_2_shapes(size_of_sub_2_shapes, nb_points_sub_2);
   Matrix<Real> parent_1_shapes(size_of_parent_shapes, nb_points_sub_1);
   Matrix<Real> parent_2_shapes(size_of_parent_shapes, nb_points_sub_2);
   /// compute the shape functions of the subelements
   ElementClass<sub_type_1>::computeShapes(natural_coords_sub_1, sub_1_shapes);
   ElementClass<sub_type_2>::computeShapes(natural_coords_sub_2, sub_2_shapes);
 
   /// get the nodal coordinates per element
   UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
   Array<Real>::matrix_iterator x_it =
       x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   /// allocate the shapes for the given element type
   Array<Real> & shapes_tmp = shapes.alloc(nb_element * nb_total_points,
                                           size_of_shapes, itp_type, ghost_type);
 
   Array<Real>::matrix_iterator shapes_it = shapes_tmp.begin_reinterpret(
       ElementClass<type>::getNbNodesPerInterpolationElement(), nb_total_points,
       nb_element);
 
   Matrix<Real> physical_points_1(spatial_dimension, nb_points_sub_1);
   Matrix<Real> physical_points_2(spatial_dimension, nb_points_sub_2);
   Matrix<Real> parent_natural_coords_1(spatial_dimension, nb_points_sub_1);
   Matrix<Real> parent_natural_coords_2(spatial_dimension, nb_points_sub_2);
 
   /// intialize the matrices for the parent and subelement coordinates
   UInt nb_nodes_parent_el =
       ElementClass<parent_type>::getNbNodesPerInterpolationElement();
   UInt nb_nodes_sub_el_1 =
       ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
   UInt nb_nodes_sub_el_2 =
       ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
   Matrix<Real> parent_coords(spatial_dimension, nb_nodes_parent_el);
   Matrix<Real> sub_el_1_coords(spatial_dimension, nb_nodes_sub_el_1);
   Matrix<Real> sub_el_2_coords(spatial_dimension, nb_nodes_sub_el_2);
 
   /// loop over all elements of the given type and compute the shape functions
   Vector<Real> all_shapes(size_of_shapes);
 
   for (UInt elem = 0; elem < nb_element;
        ++elem, ++shapes_it, ++x_it, ++natural_coords_parent_it) {
     Matrix<Real> & N = *shapes_it;
     const Matrix<Real> & X = *x_it;
     Matrix<Real> & nc_parent = *natural_coords_parent_it;
 
     /// map the sub element integration points into the parent reference domain
     ElementClass<type>::mapFromSubRefToParentRef(
         X, sub_el_1_coords, parent_coords, sub_1_shapes, physical_points_1,
         parent_natural_coords_1, 0);
     ElementClass<type>::mapFromSubRefToParentRef(
         X, sub_el_2_coords, parent_coords, sub_2_shapes, physical_points_2,
         parent_natural_coords_2, 1);
 
     /// compute the parent shape functions on all integration points
     ElementClass<sub_type_1>::computeShapes(parent_natural_coords_1,
                                             parent_1_shapes);
     ElementClass<sub_type_1>::computeShapes(parent_natural_coords_2,
                                             parent_2_shapes);
 
     /// copy the results into the shape functions iterator and natural coords
     /// iterator
     for (UInt i = 0; i < nb_points_sub_1; ++i) {
       ElementClass<type>::assembleShapes(parent_1_shapes(i), sub_1_shapes(i),
                                          all_shapes, 0);
       N(i) = all_shapes;
       nc_parent(i) = parent_natural_coords_1(i);
     }
     for (UInt i = 0; i < nb_points_sub_2; ++i) {
       ElementClass<type>::assembleShapes(parent_2_shapes(i), sub_2_shapes(i),
                                          all_shapes, 1);
       N(i + nb_points_sub_1) = all_shapes;
 
       /// N(i + nb_points_sub_2) = all_shapes;
       nc_parent(i + nb_points_sub_1) = parent_natural_coords_2(i);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::precomputeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// typedef for the two subelement_types and the parent element type
   const ElementType sub_type_1 = ElementClassProperty<type>::sub_element_type_1;
   const ElementType sub_type_2 = ElementClassProperty<type>::sub_element_type_2;
   const ElementType parent_type =
       ElementClassProperty<type>::parent_element_type;
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   /// get the integration points for the subelements
   Matrix<Real> & natural_coords_sub_1 =
       integration_points(sub_type_1, ghost_type);
   Matrix<Real> & natural_coords_sub_2 =
       integration_points(sub_type_2, ghost_type);
   /// store the number of quadrature points on each subelement and the toal
   /// number
   UInt nb_points_sub_1 = natural_coords_sub_1.cols();
   UInt nb_points_sub_2 = natural_coords_sub_2.cols();
   UInt nb_points_total = nb_points_sub_1 + nb_points_sub_2;
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
 
   /// intialize the matrices for the parent and subelement coordinates
   UInt nb_nodes_parent_el =
       ElementClass<parent_type>::getNbNodesPerInterpolationElement();
   UInt nb_nodes_sub_el_1 =
       ElementClass<sub_type_1>::getNbNodesPerInterpolationElement();
   UInt nb_nodes_sub_el_2 =
       ElementClass<sub_type_2>::getNbNodesPerInterpolationElement();
   Matrix<Real> parent_coords(spatial_dimension, nb_nodes_parent_el);
   Matrix<Real> sub_el_1_coords(spatial_dimension, nb_nodes_sub_el_1);
   Matrix<Real> sub_el_2_coords(spatial_dimension, nb_nodes_sub_el_2);
 
   UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
   Array<Real> & shapes_derivatives_tmp = shapes_derivatives.alloc(
       nb_element * nb_points_total, size_of_shapesd, itp_type, ghost_type);
 
   /// get an iterator to the coordiantes of the elements
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
 
   Real * shapesd_val = shapes_derivatives_tmp.storage();
   Array<Real>::matrix_iterator x_it =
       x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   /// get an iterator to the integration points of the parent element
   Array<Real> & natural_coords_parent =
       igfem_integration_points(type, ghost_type);
   Array<Real>::matrix_iterator natural_coords_parent_it =
       natural_coords_parent.begin_reinterpret(spatial_dimension,
                                               nb_points_total, nb_element);
 
   Tensor3<Real> B_sub_1(spatial_dimension, nb_nodes_sub_el_1, nb_points_sub_1);
   Tensor3<Real> B_sub_2(spatial_dimension, nb_nodes_sub_el_2, nb_points_sub_2);
   Tensor3<Real> B_parent(spatial_dimension, nb_nodes_parent_el,
                          nb_points_total);
   /// assemble the shape derivatives
   Matrix<Real> all_shapes(spatial_dimension, nb_nodes_per_element);
   for (UInt elem = 0; elem < nb_element;
        ++elem, ++x_it, ++natural_coords_parent_it) {
     Matrix<Real> & X = *x_it;
     Matrix<Real> & nc_parent = *natural_coords_parent_it;
 
     Tensor3<Real> B(shapesd_val, spatial_dimension, nb_nodes_per_element,
                     nb_points_total);
 
     /// get the coordinates of the two sub elements and the parent element
     ElementClass<type>::getSubElementCoords(X, sub_el_1_coords, 0);
     ElementClass<type>::getSubElementCoords(X, sub_el_2_coords, 1);
     ElementClass<type>::getParentCoords(X, parent_coords);
 
     /// compute the subelements' shape derivatives and the parent shape
     /// derivatives
     computeShapeDerivativesOnCPointsByElement<sub_type_1>(
         sub_el_1_coords, natural_coords_sub_1, B_sub_1);
     computeShapeDerivativesOnCPointsByElement<sub_type_2>(
         sub_el_2_coords, natural_coords_sub_2, B_sub_2);
     computeShapeDerivativesOnCPointsByElement<parent_type>(parent_coords,
                                                            nc_parent, B_parent);
 
     for (UInt i = 0; i < nb_points_sub_1; ++i) {
       ElementClass<type>::assembleShapeDerivatives(B_parent(i), B_sub_1(i),
                                                    all_shapes, 0);
       B(i) = all_shapes;
     }
 
     for (UInt i = 0; i < nb_points_sub_2; ++i) {
       ElementClass<type>::assembleShapeDerivatives(B_parent(i), B_sub_2(i),
                                                    all_shapes, 1);
       B(i + nb_points_sub_1) = all_shapes;
     }
 
     shapesd_val += size_of_shapesd * nb_points_total;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::interpolateOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    GhostType ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   AKANTU_DEBUG_ASSERT(shapes.exists(itp_type, ghost_type),
                       "No shapes for the type "
                           << shapes.printType(itp_type, ghost_type));
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   this->interpolateElementalFieldOnIntegrationPoints<type>(
       u_el, out_uq, ghost_type, shapes(itp_type, ghost_type), filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::gradientOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_nablauq,
     UInt nb_degree_of_freedom, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   AKANTU_DEBUG_ASSERT(
       shapes_derivatives.exists(itp_type, ghost_type),
       "No shapes derivatives for the type "
           << shapes_derivatives.printType(itp_type, ghost_type));
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   this->gradientElementalFieldOnIntegrationPoints<type>(
       u_el, out_nablauq, ghost_type, shapes_derivatives(itp_type, ghost_type),
       filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::fieldTimesShapes(
     const Array<Real> & field, Array<Real> & field_times_shapes,
     GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
   field_times_shapes.resize(field.getSize());
 
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   UInt nb_degree_of_freedom = field.getNbComponent();
 
   const Array<Real> & shape = shapes(itp_type, ghost_type);
 
   Array<Real>::const_matrix_iterator field_it =
       field.begin(nb_degree_of_freedom, 1);
   Array<Real>::const_matrix_iterator shapes_it = shape.begin(1, size_of_shapes);
 
   Array<Real>::matrix_iterator it =
       field_times_shapes.begin(nb_degree_of_freedom, size_of_shapes);
   Array<Real>::matrix_iterator end =
       field_times_shapes.end(nb_degree_of_freedom, size_of_shapes);
 
   for (; it != end; ++it, ++field_it, ++shapes_it) {
     it->mul<false, false>(*field_it, *shapes_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::interpolateOnPhysicalPoint(
     const Vector<Real> & real_coords, UInt elem, const Array<Real> & field,
     Vector<Real> & interpolated, GhostType ghost_type) const {
 
   AKANTU_DEBUG_IN();
   Vector<Real> shapes(ElementClass<type>::getShapeSize());
   computeShapes<type>(real_coords, elem, shapes, ghost_type);
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
   Matrix<Real> nodes_val(spatial_dimension, nb_nodes_per_element);
   mesh.extractNodalValuesFromElement(field, nodes_val.storage(),
                                      elem_val + elem * nb_nodes_per_element,
                                      nb_nodes_per_element, spatial_dimension);
 
   ElementClass<type>::interpolate(nodes_val, shapes, interpolated);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::precomputeShapesOnEnrichedNodes(
     __attribute__((unused)) const Array<Real> & nodes,
     GhostType ghost_type) {
 
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
 
   const ElementType parent_type =
       ElementClassProperty<type>::parent_element_type;
   const ElementType sub_type = ElementClassProperty<type>::sub_element_type_1;
 
   /// get the spatial dimension for the given element type
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
 
   // get the integration points for the parent element
   UInt nb_element = mesh.getConnectivity(type, ghost_type).getSize();
 
   /// get the size of the shapes
   UInt nb_enriched_nodes = ElementClass<type>::getNbEnrichments();
   UInt nb_parent_nodes =
       ElementClass<parent_type>::getNbNodesPerInterpolationElement();
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
   UInt size_of_parent_shapes = ElementClass<parent_type>::getShapeSize();
   UInt size_of_sub_shapes = ElementClass<sub_type>::getShapeSize();
 
   Vector<Real> parent_shapes(size_of_parent_shapes);
   Vector<Real> sub_shapes(size_of_sub_shapes);
 
   Vector<Real> shapes(size_of_shapes);
 
   /// get the nodal coordinates per element
   UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
   Array<Real>::matrix_iterator x_it =
       x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   /// allocate the shapes for the given element type
   Array<Real> & shapes_tmp = shapes_at_enrichments.alloc(
       nb_element * nb_enriched_nodes, size_of_shapes, itp_type, ghost_type);
 
   Array<Real>::matrix_iterator shapes_it = shapes_tmp.begin_reinterpret(
       ElementClass<type>::getNbNodesPerInterpolationElement(),
       nb_enriched_nodes, nb_element);
 
   Vector<Real> real_coords(spatial_dimension);
   Vector<Real> natural_coords(spatial_dimension);
   Matrix<Real> parent_coords(spatial_dimension, nb_parent_nodes);
   UInt * sub_element_enrichments =
       ElementClass<type>::getSubElementEnrichments();
 
   /// loop over all elements
   for (UInt elem = 0; elem < nb_element; ++elem, ++shapes_it, ++x_it) {
     Matrix<Real> & N = *shapes_it;
     const Matrix<Real> & X = *x_it;
     for (UInt i = 0; i < nb_enriched_nodes; ++i) {
       /// get the parent element coordinates
       ElementClass<type>::getParentCoords(X, parent_coords);
       /// get the physical coords of the enriched node
       real_coords = X(nb_parent_nodes + i);
       /// map the physical point into the parent ref domain
       ElementClass<parent_type>::inverseMap(real_coords, parent_coords,
                                             natural_coords);
       /// compute the parent shape functions
       ElementClass<parent_type>::computeShapes(natural_coords, parent_shapes);
       /// Sub-element contribution
       sub_shapes.zero();
       sub_shapes(sub_element_enrichments[i]) = 1.;
       ElementClass<type>::assembleShapes(parent_shapes, sub_shapes, shapes, 0);
       N(i) = shapes;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_igfem>::interpolateAtEnrichedNodes(
     const Array<Real> & src, Array<Real> & dst,
     GhostType ghost_type) const {
 
   AKANTU_DEBUG_IN();
 
   const ElementType parent_type =
       ElementClassProperty<type>::parent_element_type;
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   UInt nb_parent_nodes =
       ElementClass<parent_type>::getNbNodesPerInterpolationElement();
   UInt nb_enrichments = ElementClass<type>::getNbEnrichments();
   UInt * elem_val = mesh.getConnectivity(type, ghost_type).storage();
   UInt spatial_dimension = mesh.getSpatialDimension();
   Matrix<Real> nodes_val(spatial_dimension, nb_nodes_per_element);
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
 
   const Array<Real> & shapes = shapes_at_enrichments(itp_type, ghost_type);
   Array<Real>::const_matrix_iterator shapes_it = shapes.begin_reinterpret(
       nb_nodes_per_element, nb_enrichments, nb_element);
   Array<Real>::vector_iterator dst_vect = dst.begin(spatial_dimension);
 
   Vector<Real> interpolated(spatial_dimension);
   for (UInt e = 0; e < nb_element; ++e, ++shapes_it) {
     const Matrix<Real> & el_shapes = *shapes_it;
     mesh.extractNodalValuesFromElement(src, nodes_val.storage(),
                                        elem_val + e * nb_nodes_per_element,
                                        nb_nodes_per_element, spatial_dimension);
     ;
     for (UInt i = 0; i < nb_enrichments; ++i) {
       ElementClass<type>::interpolate(nodes_val, el_shapes(i), interpolated);
       UInt enr_node_idx =
           elem_val[e * nb_nodes_per_element + nb_parent_nodes + i];
       dst_vect[enr_node_idx] = interpolated;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 #define COMPUTE_ENRICHED_VALUES(type)                                          \
   interpolateAtEnrichedNodes<type>(src, dst, ghost_type);
 
 inline void ShapeLagrange<_ek_igfem>::interpolateEnrichmentsAllTypes(
     const Array<Real> & src, Array<Real> & dst, ElementType type,
     GhostType ghost_type) const {
 
   AKANTU_BOOST_IGFEM_ELEMENT_SWITCH(COMPUTE_ENRICHED_VALUES);
 }
 #undef COMPUTE_ENRICHED_VALUES
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* AKANTU_SHAPE_IGFEM_INLINE_IMPL_HH_ */
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction.cc
index 033063cdf..2961aafd5 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction.cc
@@ -1,411 +1,411 @@
 /**
  * @file   test_material_igfem_iterative_strength_reduction.cc
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Thu Nov 26 12:20:15 2015
  *
  * @brief  test the material iterative stiffness reduction
  *
  *
  * 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 "material_damage_iterative.hh"
 #include "material_igfem_saw_tooth_damage.hh"
 #include "solid_mechanics_model_igfem.hh"
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 /// function declaration
 bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model,
                       bool igfem_analysis);
 
 class TestMaterialSelector : public MaterialSelector {
 public:
   TestMaterialSelector(SolidMechanicsModelIGFEM & model)
       : MaterialSelector(), model(model),
         spatial_dimension(model.getSpatialDimension()) {}
 
   UInt operator()(const Element & element) {
     if (Mesh::getKind(element.type) == _ek_igfem)
       return 2;
     else {
       /// regular elements
       const Mesh & mesh = model.getMesh();
       Vector<Real> barycenter(this->spatial_dimension);
       mesh.getBarycenter(element, barycenter);
       /// check if element belongs to ASR gel
       if (model.isInside(barycenter))
         return 1;
     }
     return 0;
   }
 
 protected:
   SolidMechanicsModelIGFEM & model;
   UInt spatial_dimension;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Main                                                                       */
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
 
   Math::setTolerance(1e-13);
   debug::setDebugLevel(dblWarning);
 
   initialize("material_stiffness_reduction.dat", argc, argv);
 
   bool igfem_analysis;
   std::string action(argv[1]);
   if (action == "igfem") {
     igfem_analysis = true;
   } else if (action == "standard_fem") {
     igfem_analysis = false;
   } else {
     std::cerr << "invalid option" << std::endl;
   }
 
   const UInt spatial_dimension = 2;
   StaticCommunicator & comm =
       akantu::StaticCommunicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   /// read the mesh and partion it
   Mesh mesh(spatial_dimension);
   akantu::MeshPartition * partition = NULL;
 
   if (prank == 0) {
 
     if (igfem_analysis)
       mesh.read("igfem_mesh.msh");
     else
       mesh.read("regular_mesh.msh");
 
     /// partition the mesh
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
 
     partition->partitionate(psize);
   }
 
   /// model creation
   SolidMechanicsModelIGFEM model(mesh);
   model.initParallel(partition);
   delete partition;
 
   Math::setTolerance(1.e-14);
   /// intialize the geometry and set the material selector
   std::list<SK::Sphere_3> inclusions_list;
   model.registerGeometryObject(inclusions_list, "inclusion");
   Real val = 1000000000;
   Real radius_squared = val * val;
   Vector<Real> center(spatial_dimension);
   center(0) = 0;
   center(1) = val;
   SK::Sphere_3 sphere(SK::Point_3(center(0), center(1), 0.), radius_squared);
   inclusions_list.push_back(sphere);
   TestMaterialSelector * mat_selector = new TestMaterialSelector(model);
   model.setMaterialSelector(*mat_selector);
 
   /// initialization of the model
   model.initFull();
 
   /// create the interface
   if (igfem_analysis)
     model.update("inclusion");
 
   /// boundary conditions
   mesh.computeBoundingBox();
   const Vector<Real> & lowerBounds = mesh.getLowerBounds();
   const Vector<Real> & upperBounds = mesh.getUpperBounds();
   Real bottom = lowerBounds(1);
   Real top = upperBounds(1);
   Real left = lowerBounds(0);
   Real eps = std::abs((top - bottom) * 1e-6);
   const Array<Real> & pos = mesh.getNodes();
   Array<bool> & boun = model.getBlockedDOFs();
   Array<Real> & disp = model.getDisplacement();
   for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
     if (std::abs(pos(n, 1) - bottom) < eps) {
       boun(n, 1) = true;
       disp(n, 1) = 0.;
     }
     if (std::abs(pos(n, 1) - top) < eps) {
       boun(n, 1) = true;
       disp(n, 1) = 1.e-3;
     }
     if (std::abs(pos(n, 0) - left) < eps) {
       boun(n, 0) = true;
       disp(n, 0) = 0.;
     }
   }
 
   /// add fields that should be dumped
   model.setBaseName("regular");
   model.addDumpField("material_index");
   model.addDumpFieldVector("displacement");
   ;
   model.addDumpField("stress");
   model.addDumpField("blocked_dofs");
   model.addDumpField("residual");
   model.addDumpField("grad_u");
   model.addDumpField("damage");
   model.addDumpField("partitions");
   model.addDumpField("Sc");
   model.addDumpField("force");
   model.addDumpField("equivalent_stress");
   model.addDumpField("ultimate_strain");
   model.setBaseNameToDumper("igfem elements", "igfem elements");
   model.addDumpFieldToDumper("igfem elements", "material_index");
   model.addDumpFieldVectorToDumper("igfem elements", "displacement");
   ;
   model.addDumpFieldToDumper("igfem elements", "stress");
   model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
   model.addDumpFieldToDumper("igfem elements", "residual");
   model.addDumpFieldToDumper("igfem elements", "grad_u");
   model.addDumpFieldToDumper("igfem elements", "damage");
   model.addDumpFieldToDumper("igfem elements", "partitions");
   model.addDumpFieldToDumper("igfem elements", "Sc");
   model.addDumpFieldToDumper("igfem elements", "force");
   model.addDumpFieldToDumper("igfem elements", "equivalent_stress");
   model.addDumpFieldToDumper("igfem elements", "ultimate_strain");
 
   model.dump();
   model.dump("igfem elements");
 
   /// get a reference to the damage materials
   MaterialDamageIterative<spatial_dimension> & material =
       dynamic_cast<MaterialDamageIterative<spatial_dimension> &>(
           model.getMaterial(0));
   MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material =
       dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> &>(
           model.getMaterial(2));
 
   Real error;
   bool converged = false;
   UInt nb_damaged_elements = 0;
   Real max_eq_stress_regular = 0;
   Real max_eq_stress_igfem = 0;
 
   /// solve the system
   // counter for the damage steps
   UInt s = 0;
   do {
     converged =
         model.solveStep<_scm_newton_raphson_tangent_modified,
                         SolveConvergenceCriteria::_increment>(1e-12, error, 2);
 
     if (converged == false) {
       std::cout << "The error is: " << error << std::endl;
       AKANTU_DEBUG_ASSERT(converged, "Did not converge");
     }
 
     /// compute damage
     max_eq_stress_regular = material.getNormMaxEquivalentStress();
     max_eq_stress_igfem = igfem_material.getNormMaxEquivalentStress();
     if (max_eq_stress_regular > max_eq_stress_igfem)
       nb_damaged_elements = material.updateDamage();
     else if (max_eq_stress_regular == max_eq_stress_igfem) {
       nb_damaged_elements = material.updateDamage();
       nb_damaged_elements += igfem_material.updateDamage();
     } else
       nb_damaged_elements = igfem_material.updateDamage();
 
     model.dump();
     model.dump("igfem elements");
 
     /// check the current damage state
     if (!checkDamageState(s, model, igfem_analysis)) {
       std::cout << "error in the damage compuation" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
 
     s++;
   } while (nb_damaged_elements);
 
   std::cout << action << " passed!!" << std::endl;
   finalize();
 
   return EXIT_SUCCESS;
 }
 
 /* -------------------------------------------------------------------------- */
 bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model,
                       bool igfem_analysis) {
 
   bool test_result = true;
   const UInt spatial_dimension = model.getSpatialDimension();
   const Mesh & mesh = model.getMesh();
 
   if (!igfem_analysis) {
     const ElementType element_type = _triangle_3;
     /// prepare output: compute barycenters for elements that can be damaged
-    const Array<UInt> & element_filter =
+    const Array<Int> & element_filter =
         model.getMaterial(0).getElementFilter(element_type, _not_ghost);
     Array<Real> barycenters(element_filter.getSize(), spatial_dimension);
     Array<Real>::vector_iterator bary_it = barycenters.begin(spatial_dimension);
     for (UInt e = 0; e < element_filter.getSize(); ++e, ++bary_it) {
       UInt global_el_idx = element_filter(e);
       mesh.getBarycenter(global_el_idx, element_type, bary_it->storage(),
                          _not_ghost);
     }
 
     const Array<Real> & damage = model.getMaterial(0).getInternal<Real>(
         "damage")(element_type, _not_ghost);
     const Array<Real> & Sc =
         model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
 
     std::ostringstream file_name;
     file_name << "step_" << std::setfill('0') << std::setw(3) << step << ".txt";
 
     std::ofstream file_output;
     file_output.open(file_name.str());
     file_output << std::setprecision(14);
 
     for (UInt e = 0; e < barycenters.getSize(); ++e)
       file_output << barycenters(e, 0) << " " << barycenters(e, 1) << " "
                   << damage(e) << " " << Sc(e) << std::endl;
 
   }
 
   else {
 
     /// read data
     Real default_tolerance = Math::getTolerance();
     Math::setTolerance(1.e-10);
     std::stringstream results_file;
     results_file << "step_" << std::setfill('0') << std::setw(3) << step
                  << ".txt";
     std::ifstream damage_input;
     damage_input.open(results_file.str().c_str());
 
     Array<Real> damage_result(0, 1);
     Array<Real> Sc_result(0, 1);
     Array<Real> bary_regular(0, spatial_dimension);
     Vector<Real> bary(spatial_dimension);
     Real dam = 0.;
     Real strength = 0;
 
     while (damage_input.good()) {
       damage_input >> bary(0) >> bary(1) >> dam >> strength;
       bary_regular.push_back(bary);
       damage_result.push_back(dam);
       Sc_result.push_back(strength);
     }
 
     /// compare the results
     Array<Real>::const_vector_iterator bary_it;
 
     Array<Real>::const_vector_iterator bary_begin =
         bary_regular.begin(spatial_dimension);
     Array<Real>::const_vector_iterator bary_end =
         bary_regular.end(spatial_dimension);
     /// compare the regular elements
     ElementType element_type = _triangle_3;
-    const Array<UInt> & element_filter =
+    const Array<Int> & element_filter =
         model.getMaterial(0).getElementFilter(element_type, _not_ghost);
     const Array<Real> & damage_regular_el =
         model.getMaterial(0).getInternal<Real>("damage")(element_type,
                                                          _not_ghost);
     const Array<Real> & Sc_regular_el =
         model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
 
     for (UInt e = 0; e < element_filter.getSize(); ++e) {
       UInt global_el_idx = element_filter(e);
       mesh.getBarycenter(global_el_idx, element_type, bary.storage(),
                          _not_ghost);
       /// find element
       for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
         UInt matched_dim = 0;
         while (
             matched_dim < spatial_dimension &&
             Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
           ++matched_dim;
         if (matched_dim == spatial_dimension)
           break;
       }
       if (bary_it == bary_end) {
         std::cout << "Element barycenter not found!" << std::endl;
         return false;
       }
 
       UInt matched_el = bary_it - bary_begin;
 
       if (std::abs(damage_result(matched_el) - damage_regular_el(e)) > 1.e-12 ||
           std::abs(Sc_result(matched_el) - Sc_regular_el(e)) > 1.e-4) {
         test_result = false;
         break;
       }
     }
     /// compare the IGFEM elements
     UInt nb_sub_elements = 2;
     element_type = _igfem_triangle_4;
-    const Array<UInt> & element_filter_igfem =
+    const Array<Int> & element_filter_igfem =
         model.getMaterial(2).getElementFilter(element_type, _not_ghost);
     const Array<Real> & damage_regular_el_igfem =
         model.getMaterial(2).getInternal<Real>("damage")(element_type,
                                                          _not_ghost);
     const Array<Real> & Sc_regular_el_igfem =
         model.getMaterial(2).getInternal<Real>("Sc")(element_type, _not_ghost);
     UInt * sub_el_ptr =
         model.getMaterial(2)
             .getInternal<UInt>("sub_material")(element_type, _not_ghost)
             .storage();
 
     for (UInt e = 0; e < element_filter_igfem.getSize(); ++e) {
       UInt global_el_idx = element_filter_igfem(e);
       for (UInt s = 0; s < nb_sub_elements; ++s, ++sub_el_ptr) {
         if (*sub_el_ptr)
           model.getSubElementBarycenter(global_el_idx, s, element_type, bary,
                                         _not_ghost);
         else
           continue;
         /// find element
         for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
           UInt matched_dim = 0;
           while (
               matched_dim < spatial_dimension &&
               Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
             ++matched_dim;
           if (matched_dim == spatial_dimension)
             break;
         }
         if (bary_it == bary_end) {
           std::cout << "Element barycenter not found!" << std::endl;
           return false;
         }
 
         UInt matched_el = bary_it - bary_begin;
 
         if (std::abs(damage_result(matched_el) -
                      damage_regular_el_igfem(e * nb_sub_elements + s)) >
                 1.e-12 ||
             std::abs(Sc_result(matched_el) -
                      Sc_regular_el_igfem(e * nb_sub_elements + s)) > 1.e-4) {
           test_result = false;
           break;
         }
       }
     }
 
     Math::setTolerance(default_tolerance);
   }
   return test_result;
 }
diff --git a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_parallel.cc b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_parallel.cc
index 365259bce..3040da93a 100644
--- a/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_parallel.cc
+++ b/extra_packages/igfem/test/test_solid_mechanics_model_igfem/test_material_igfem_iterative_stiffness_reduction_parallel.cc
@@ -1,436 +1,436 @@
 /**
  * @file   test_material_igfem_iterative_stiffness_reduction_parallel.cc
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Thu Nov 26 12:20:15 2015
  *
  * @brief test the material iterative stiffness reduction in parallel
  *
  *
  * 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 "material_igfem_saw_tooth_damage.hh"
 #include "material_iterative_stiffness_reduction.hh"
 #include "solid_mechanics_model_igfem.hh"
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 /// function declaration
 bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model);
 
 class TestMaterialSelector : public MaterialSelector {
 public:
   TestMaterialSelector(SolidMechanicsModelIGFEM & model)
       : MaterialSelector(), model(model),
         spatial_dimension(model.getSpatialDimension()) {}
 
   UInt operator()(const Element & element) {
     if (Mesh::getKind(element.type) == _ek_igfem)
       return 2;
     else {
       /// regular elements
       const Mesh & mesh = model.getMesh();
       Vector<Real> barycenter(this->spatial_dimension);
       mesh.getBarycenter(element, barycenter);
       /// check if element belongs to ASR gel
       if (model.isInside(barycenter))
         return 1;
     }
     return 0;
   }
 
 protected:
   SolidMechanicsModelIGFEM & model;
   UInt spatial_dimension;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Main                                                                       */
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
 
   Math::setTolerance(1e-13);
   debug::setDebugLevel(dblWarning);
 
   initialize("material_stiffness_reduction_2.dat", argc, argv);
 
   const UInt spatial_dimension = 2;
   StaticCommunicator & comm =
       akantu::StaticCommunicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   /// read the mesh and partion it
   Mesh mesh(spatial_dimension);
   akantu::MeshPartition * partition = NULL;
 
   if (prank == 0) {
 
     mesh.read("test_damage_transfer.msh");
 
     /// partition the mesh
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
 
     partition->partitionate(psize);
   }
 
   /// model creation
   SolidMechanicsModelIGFEM model(mesh);
   model.initParallel(partition);
   delete partition;
 
   Math::setTolerance(1.e-14);
   /// intialize the geometry and set the material selector
   std::list<SK::Sphere_3> inclusions_list;
   model.registerGeometryObject(inclusions_list, "inclusion");
   Real radius = 0.125;
   ;
   Vector<Real> center(spatial_dimension);
   center(0) = 0.;
   center(1) = 0.;
   SK::Sphere_3 sphere(SK::Point_3(center(0), center(1), 0.), radius * radius);
   inclusions_list.push_back(sphere);
   TestMaterialSelector * mat_selector = new TestMaterialSelector(model);
   model.setMaterialSelector(*mat_selector);
 
   /// initialization of the model
   model.initFull();
 
   /// boundary conditions
   mesh.computeBoundingBox();
   const Vector<Real> & lowerBounds = mesh.getLowerBounds();
   const Vector<Real> & upperBounds = mesh.getUpperBounds();
   Real bottom = lowerBounds(1);
   Real top = upperBounds(1);
   Real left = lowerBounds(0);
   Real eps = std::abs((top - bottom) * 1e-6);
   const Array<Real> & pos = mesh.getNodes();
   Array<bool> & boun = model.getBlockedDOFs();
   Array<Real> & disp = model.getDisplacement();
   for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
     if (std::abs(pos(n, 1) - bottom) < eps) {
       boun(n, 1) = true;
       disp(n, 1) = 0.;
     }
     if (std::abs(pos(n, 1) - top) < eps) {
       boun(n, 1) = true;
       disp(n, 1) = 1.e-3;
     }
     if (std::abs(pos(n, 0) - left) < eps) {
       boun(n, 0) = true;
       disp(n, 0) = 0.;
     }
   }
 
   /// add fields that should be dumped
   model.setBaseName("regular");
   model.addDumpField("material_index");
   model.addDumpFieldVector("displacement");
   ;
   model.addDumpField("stress");
   model.addDumpField("blocked_dofs");
   model.addDumpField("residual");
   model.addDumpField("grad_u");
   model.addDumpField("damage");
   model.addDumpField("partitions");
   model.addDumpField("Sc");
   model.addDumpField("force");
   model.addDumpField("equivalent_stress");
   model.addDumpField("ultimate_strain");
   model.setBaseNameToDumper("igfem elements", "igfem elements");
   model.addDumpFieldToDumper("igfem elements", "material_index");
   model.addDumpFieldVectorToDumper("igfem elements", "displacement");
   ;
   model.addDumpFieldToDumper("igfem elements", "stress");
   model.addDumpFieldToDumper("igfem elements", "blocked_dofs");
   model.addDumpFieldToDumper("igfem elements", "residual");
   model.addDumpFieldToDumper("igfem elements", "grad_u");
   model.addDumpFieldToDumper("igfem elements", "damage");
   model.addDumpFieldToDumper("igfem elements", "partitions");
   model.addDumpFieldToDumper("igfem elements", "Sc");
   model.addDumpFieldToDumper("igfem elements", "force");
   model.addDumpFieldToDumper("igfem elements", "equivalent_stress");
   model.addDumpFieldToDumper("igfem elements", "ultimate_strain");
 
   model.dump();
   model.dump("igfem elements");
 
   /// create the interface
   model.update("inclusion");
 
   /// get a reference to the damage materials
   MaterialIterativeStiffnessReduction<spatial_dimension> & material =
       dynamic_cast<MaterialIterativeStiffnessReduction<spatial_dimension> &>(
           model.getMaterial(0));
   MaterialIGFEMSawToothDamage<spatial_dimension> & igfem_material =
       dynamic_cast<MaterialIGFEMSawToothDamage<spatial_dimension> &>(
           model.getMaterial(2));
 
   Real error;
   bool converged = false;
   UInt nb_damaged_elements = 0;
   Real max_eq_stress_regular = 0;
   Real max_eq_stress_igfem = 0;
 
   /// solve the system
   UInt s = 0;
   do {
     converged =
         model.solveStep<_scm_newton_raphson_tangent_modified,
                         SolveConvergenceCriteria::_increment>(1e-12, error, 2);
 
     if (converged == false) {
       std::cout << "The error is: " << error << std::endl;
       AKANTU_DEBUG_ASSERT(converged, "Did not converge");
     }
 
     /// compute damage
     max_eq_stress_regular = material.getNormMaxEquivalentStress();
     max_eq_stress_igfem = igfem_material.getNormMaxEquivalentStress();
     if (max_eq_stress_regular > max_eq_stress_igfem)
       nb_damaged_elements = material.updateDamage();
     else if (max_eq_stress_regular == max_eq_stress_igfem) {
       nb_damaged_elements = material.updateDamage();
       nb_damaged_elements += igfem_material.updateDamage();
     } else
       nb_damaged_elements = igfem_material.updateDamage();
     model.dump();
     model.dump("igfem elements");
     /// check the current damage state
     if (!checkDamageState(s, model)) {
       std::cout << "error in the damage compuation" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
     s++;
   } while (nb_damaged_elements);
 
   finalize();
 
   return EXIT_SUCCESS;
 }
 
 /* -------------------------------------------------------------------------- */
 bool checkDamageState(UInt step, const SolidMechanicsModelIGFEM & model) {
 
   bool test_result = true;
   const UInt spatial_dimension = model.getSpatialDimension();
   const Mesh & mesh = model.getMesh();
 
   StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
 
   if (psize == 1) {
     const ElementType element_type = _triangle_3;
     /// prepare output: compute barycenters for elements that can be damaged
-    const Array<UInt> & element_filter =
+    const Array<Int> & element_filter =
         model.getMaterial(0).getElementFilter(element_type, _not_ghost);
     Array<Real> barycenters(element_filter.getSize(), spatial_dimension);
     Array<Real>::vector_iterator bary_it = barycenters.begin(spatial_dimension);
     for (UInt e = 0; e < element_filter.getSize(); ++e, ++bary_it) {
       UInt global_el_idx = element_filter(e);
       mesh.getBarycenter(global_el_idx, element_type, bary_it->storage(),
                          _not_ghost);
     }
 
     const Array<Real> & damage = model.getMaterial(0).getInternal<Real>(
         "damage")(element_type, _not_ghost);
     const Array<Real> & Sc =
         model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
 
     std::ostringstream file_name;
     file_name << "step_" << std::setfill('0') << std::setw(3) << step << ".txt";
 
     std::ofstream file_output;
     file_output.open(file_name.str());
     file_output << std::setprecision(14);
 
     for (UInt e = 0; e < barycenters.getSize(); ++e)
       file_output << barycenters(e, 0) << " " << barycenters(e, 1) << " "
                   << damage(e) << " " << Sc(e) << std::endl;
 
     /// igfem elements
     const ElementType element_type_igfem = _igfem_triangle_5;
     /// prepare output: compute barycenters for elements that can be damaged
     UInt nb_igfem_elements = mesh.getNbElement(_igfem_triangle_5, _not_ghost);
     UInt nb_sub_elements = 2;
     Array<Real> barycenters_igfem(nb_sub_elements * nb_igfem_elements,
                                   spatial_dimension);
     bary_it = barycenters_igfem.begin(spatial_dimension);
     for (UInt e = 0; e < nb_igfem_elements; ++e) {
       /// note global index is local index because there is only one igfem
       /// material
       for (UInt s = 0; s < nb_sub_elements; ++s, ++bary_it)
         model.getSubElementBarycenter(e, s, element_type_igfem, *bary_it,
                                       _not_ghost);
     }
 
     const Array<Real> & damage_igfem = model.getMaterial(2).getInternal<Real>(
         "damage")(element_type_igfem, _not_ghost);
     Array<Real>::const_scalar_iterator dam_it = damage_igfem.begin();
     const Array<Real> & Sc_igfem = model.getMaterial(2).getInternal<Real>("Sc")(
         element_type_igfem, _not_ghost);
     Array<Real>::const_scalar_iterator Sc_it = Sc_igfem.begin();
 
     for (UInt e = 0; e < nb_igfem_elements; ++e) {
       for (UInt s = 0; s < nb_sub_elements; ++s)
         if (IGFEMHelper::getSubElementType(element_type_igfem, s) ==
             _triangle_3) {
           file_output << barycenters_igfem(e * nb_sub_elements + s, 0) << " "
                       << barycenters_igfem(e * nb_sub_elements + s, 1) << " "
                       << *dam_it << " " << *Sc_it << std::endl;
           ++dam_it;
           ++Sc_it;
         } else if (IGFEMHelper::getSubElementType(element_type_igfem, s) ==
                    _quadrangle_4) {
           file_output << barycenters_igfem(e * nb_sub_elements + s, 0) << " "
                       << barycenters_igfem(e * nb_sub_elements + s, 1) << " "
                       << *dam_it << " " << *Sc_it << std::endl;
           dam_it += 4;
           Sc_it += 4;
         }
     }
   }
 
   else {
 
     /// read data
     Real default_tolerance = Math::getTolerance();
     Math::setTolerance(1.e-10);
     std::stringstream results_file;
     results_file << "step_" << std::setfill('0') << std::setw(3) << step
                  << ".txt";
     std::ifstream damage_input;
     damage_input.open(results_file.str().c_str());
 
     Array<Real> damage_result(0, 1);
     Array<Real> Sc_result(0, 1);
     Array<Real> bary_regular(0, spatial_dimension);
     Vector<Real> bary(spatial_dimension);
     Real dam = 0.;
     Real strength = 0;
 
     while (damage_input.good()) {
       damage_input >> bary(0) >> bary(1) >> dam >> strength;
       bary_regular.push_back(bary);
       damage_result.push_back(dam);
       Sc_result.push_back(strength);
     }
 
     /// compare the results
     Array<Real>::const_vector_iterator bary_it;
 
     Array<Real>::const_vector_iterator bary_begin =
         bary_regular.begin(spatial_dimension);
     Array<Real>::const_vector_iterator bary_end =
         bary_regular.end(spatial_dimension);
     /// compare the regular elements
     ElementType element_type = _triangle_3;
-    const Array<UInt> & element_filter =
+    const Array<Int> & element_filter =
         model.getMaterial(0).getElementFilter(element_type, _not_ghost);
     const Array<Real> & damage_regular_el =
         model.getMaterial(0).getInternal<Real>("damage")(element_type,
                                                          _not_ghost);
     const Array<Real> & Sc_regular_el =
         model.getMaterial(0).getInternal<Real>("Sc")(element_type, _not_ghost);
 
     for (UInt e = 0; e < element_filter.getSize(); ++e) {
       UInt global_el_idx = element_filter(e);
       mesh.getBarycenter(global_el_idx, element_type, bary.storage(),
                          _not_ghost);
       /// find element
       for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
         UInt matched_dim = 0;
         while (
             matched_dim < spatial_dimension &&
             Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
           ++matched_dim;
         if (matched_dim == spatial_dimension)
           break;
       }
       if (bary_it == bary_end) {
         std::cout << "Element barycenter not found!" << std::endl;
         return false;
       }
 
       UInt matched_el = bary_it - bary_begin;
 
       if (std::abs(damage_result(matched_el) - damage_regular_el(e)) > 1.e-12 ||
           std::abs(Sc_result(matched_el) - Sc_regular_el(e)) > 1.e-4) {
         test_result = false;
         break;
       }
     }
     /// compare the IGFEM elements
     UInt nb_sub_elements = 2;
     element_type = _igfem_triangle_5;
-    const Array<UInt> & element_filter_igfem =
+    const Array<Int> & element_filter_igfem =
         model.getMaterial(2).getElementFilter(element_type, _not_ghost);
     const Array<Real> & damage_regular_el_igfem =
         model.getMaterial(2).getInternal<Real>("damage")(element_type,
                                                          _not_ghost);
     Array<Real>::const_scalar_iterator dam_igfem_it =
         damage_regular_el_igfem.begin();
     const Array<Real> & Sc_regular_el_igfem =
         model.getMaterial(2).getInternal<Real>("Sc")(element_type, _not_ghost);
     Array<Real>::const_scalar_iterator Sc_igfem_it =
         Sc_regular_el_igfem.begin();
 
     for (UInt e = 0; e < element_filter_igfem.getSize(); ++e) {
       UInt global_el_idx = element_filter_igfem(e);
       for (UInt s = 0; s < nb_sub_elements; ++s) {
         model.getSubElementBarycenter(global_el_idx, s, element_type, bary,
                                       _not_ghost);
         /// find element
         for (bary_it = bary_begin; bary_it != bary_end; ++bary_it) {
           UInt matched_dim = 0;
           while (
               matched_dim < spatial_dimension &&
               Math::are_float_equal(bary(matched_dim), (*bary_it)(matched_dim)))
             ++matched_dim;
           if (matched_dim == spatial_dimension)
             break;
         }
         if (bary_it == bary_end) {
           std::cout << "Sub-element barycenter not found!" << std::endl;
           return false;
         }
 
         UInt matched_el = bary_it - bary_begin;
 
         if (std::abs(damage_result(matched_el) - *dam_igfem_it) > 1.e-12 ||
             std::abs(Sc_result(matched_el) - *Sc_igfem_it) > 1.e-4) {
           test_result = false;
           break;
         }
         if (IGFEMHelper::getSubElementType(element_type, s) == _triangle_3) {
           ++Sc_igfem_it;
           ++dam_igfem_it;
         } else if (IGFEMHelper::getSubElementType(element_type, s) ==
                    _quadrangle_4) {
           Sc_igfem_it += 4;
           dam_igfem_it += 4;
         }
       }
     }
 
     Math::setTolerance(default_tolerance);
   }
   return test_result;
 }
diff --git a/python/py_fe_engine.cc b/python/py_fe_engine.cc
index c17e05a49..f150ad780 100644
--- a/python/py_fe_engine.cc
+++ b/python/py_fe_engine.cc
@@ -1,155 +1,145 @@
 /**
  * @file   py_fe_engine.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 27 2019
  * @date last modification: Sat Dec 12 2020
  *
  * @brief  pybind11 interface to FEEngine
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "py_aka_array.hh"
 #include "py_aka_common.hh"
 /* -------------------------------------------------------------------------- */
 #include <element.hh>
 #include <fe_engine.hh>
 #include <integration_point.hh>
 /* -------------------------------------------------------------------------- */
 #include <pybind11/functional.h>
 #include <pybind11/pybind11.h>
 #include <pybind11/stl.h>
 /* -------------------------------------------------------------------------- */
 namespace py = pybind11;
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 void register_fe_engine(py::module & mod) {
   py::class_<Element>(mod, "Element")
       .def(py::init([](ElementType type, UInt id) {
         return new Element{type, id, _not_ghost};
       }))
       .def(py::init([](ElementType type, UInt id, GhostType ghost_type) {
         return new Element{type, id, ghost_type};
       }))
       .def("__lt__",
            [](Element & self, const Element & other) { return (self < other); })
       .def("__repr__", [](Element & self) { return std::to_string(self); });
 
   mod.attr("ElementNull") = ElementNull;
 
   py::class_<FEEngine>(mod, "FEEngine")
       .def(
           "getNbIntegrationPoints",
-          [](FEEngine & fem, const ElementType & type,
-             const GhostType & ghost_type) {
+          [](FEEngine & fem, ElementType type,
+             GhostType ghost_type) {
             return fem.getNbIntegrationPoints(type, ghost_type);
           },
           py::arg("type"), py::arg("ghost_type") = _not_ghost)
       .def(
           "gradientOnIntegrationPoints",
           [](FEEngine & fem, const Array<Real> & u, Array<Real> & nablauq,
-             UInt nb_degree_of_freedom, ElementType type, GhostType ghost_type,
-             const Array<UInt> * filter_elements) {
-            if (filter_elements == nullptr) {
-              // This is due to the ArrayProxy that looses the
-              // empty_filter information
-              filter_elements = &empty_filter;
-            }
+             const UInt nb_degree_of_freedom, ElementType type,
+             GhostType ghost_type,
+             const Array<Int> & filter_elements) {
             fem.gradientOnIntegrationPoints(u, nablauq, nb_degree_of_freedom,
-                                            type, ghost_type, *filter_elements);
+                                            type, ghost_type, filter_elements);
           },
           py::arg("u"), py::arg("nablauq"), py::arg("nb_degree_of_freedom"),
           py::arg("type"), py::arg("ghost_type") = _not_ghost,
-          py::arg("filter_elements") = nullptr)
+          py::arg("filter_elements") = empty_filter)
       .def(
           "interpolateOnIntegrationPoints",
           [](FEEngine & self, const Array<Real> & u, Array<Real> & uq,
-             UInt nb_degree_of_freedom, ElementType type, GhostType ghost_type,
-             const Array<UInt> * filter_elements) {
-            if (filter_elements == nullptr) {
-              // This is due to the ArrayProxy that looses the
-              // empty_filter information
-              filter_elements = &empty_filter;
-            }
-
-            self.interpolateOnIntegrationPoints(u, uq, nb_degree_of_freedom,
-                                                type, ghost_type,
-                                                *filter_elements);
+             UInt nb_degree_of_freedom, ElementType type,
+             GhostType ghost_type,
+             const Array<Int> & filter_elements) {
+            self.interpolateOnIntegrationPoints(
+                u, uq, nb_degree_of_freedom, type, ghost_type, filter_elements);
           },
           py::arg("u"), py::arg("uq"), py::arg("nb_degree_of_freedom"),
           py::arg("type"), py::arg("ghost_type") = _not_ghost,
-          py::arg("filter_elements") = nullptr)
+          py::arg("filter_elements") = empty_filter)
       .def(
           "interpolateOnIntegrationPoints",
           [](FEEngine & self, const Array<Real> & u,
              ElementTypeMapArray<Real> & uq,
              const ElementTypeMapArray<UInt> * filter_elements) {
             self.interpolateOnIntegrationPoints(u, uq, filter_elements);
           },
           py::arg("u"), py::arg("uq"), py::arg("filter_elements") = nullptr)
       .def(
           "computeIntegrationPointsCoordinates",
           [](FEEngine & self, ElementTypeMapArray<Real> & coordinates,
              const ElementTypeMapArray<UInt> * filter_elements)
               -> decltype(auto) {
             return self.computeIntegrationPointsCoordinates(coordinates,
                                                             filter_elements);
           },
           py::arg("coordinates"), py::arg("filter_elements") = nullptr)
       .def(
           "assembleFieldLumped",
           [](FEEngine & fem,
              const std::function<void(Matrix<Real> &, const Element &)> &
                  field_funct,
              const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
              ElementType type, GhostType ghost_type) {
             fem.assembleFieldLumped(field_funct, matrix_id, dof_id, dof_manager,
                                     type, ghost_type);
           },
           py::arg("field_funct"), py::arg("matrix_id"), py::arg("dof_id"),
           py::arg("dof_manager"), py::arg("type"),
           py::arg("ghost_type") = _not_ghost)
       .def(
           "assembleFieldMatrix",
           [](FEEngine & fem,
              const std::function<void(Matrix<Real> &, const Element &)> &
                  field_funct,
              const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
              ElementType type, GhostType ghost_type = _not_ghost) {
             fem.assembleFieldMatrix(field_funct, matrix_id, dof_id, dof_manager,
                                     type, ghost_type);
           },
           py::arg("field_funct"), py::arg("matrix_id"), py::arg("dof_id"),
           py::arg("dof_manager"), py::arg("type"),
           py::arg("ghost_type") = _not_ghost)
       .def("getElementInradius", [](FEEngine & self, const Element & element) {
         return self.getElementInradius(element);
       });
 
   py::class_<IntegrationPoint>(mod, "IntegrationPoint");
 }
 } // namespace akantu
diff --git a/src/common/aka_array.cc b/src/common/aka_array.cc
index 98a7cf9fb..8493be058 100644
--- a/src/common/aka_array.cc
+++ b/src/common/aka_array.cc
@@ -1,98 +1,98 @@
 /**
  * @file   aka_array.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  Implementation of akantu::Array
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 <memory>
 #include <utility>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_common.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Functions ArrayBase                                                       */
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
-template <> UInt Array<Real>::find(const Real & elem) const {
+template <> Idx Array<Real>::find(const Real & elem) const {
   AKANTU_DEBUG_IN();
 
   Real epsilon = std::numeric_limits<Real>::epsilon();
   auto it = std::find_if(begin(), end(), [&elem, &epsilon](auto && a) {
     return std::abs(a - elem) <= epsilon;
   });
 
   AKANTU_DEBUG_OUT();
   return (it != end()) ? end() - it : UInt(-1);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 Array<ElementType> &
 Array<ElementType>::operator*=(const ElementType &/*alpha*/) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <>
 Array<ElementType> &
 Array<ElementType>::operator-=(const Array<ElementType> & /*vect*/) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <>
 Array<ElementType> &
 Array<ElementType>::operator+=(const Array<ElementType> & /*vect*/) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <> Array<char> & Array<char>::operator*=(const char & /*alpha*/) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <>
 Array<char> & Array<char>::operator-=(const Array<char> & /*vect*/) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 template <>
 Array<char> & Array<char>::operator+=(const Array<char> & /*vect*/) {
   AKANTU_TO_IMPLEMENT();
   return *this;
 }
 
 } // namespace akantu
diff --git a/src/common/aka_array.hh b/src/common/aka_array.hh
index 3b94a7d22..72c0f8ea4 100644
--- a/src/common/aka_array.hh
+++ b/src/common/aka_array.hh
@@ -1,417 +1,420 @@
 /**
  * @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: Sun Nov 22 2020
  *
  * @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-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 #include "aka_view_iterators.hh"
 /* -------------------------------------------------------------------------- */
 #include <typeinfo>
 #include <vector>
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_ARRAY_HH_
 #define AKANTU_ARRAY_HH_
 
 namespace akantu {
 
 /// class that afford to store vectors in static memory
 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
 class ArrayBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   explicit ArrayBase(const ID & id = "") : id(id) {}
   ArrayBase(const ArrayBase & other, const ID & id = "") {
     this->id = (id.empty()) ? other.id : id;
   }
 
   ArrayBase(ArrayBase && other) = default;
   ArrayBase & operator=(const ArrayBase & other) = default;
   ArrayBase & operator=(ArrayBase && other) noexcept = default;
 
   virtual ~ArrayBase() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the amount of space allocated in bytes
-  virtual UInt getMemorySize() const = 0;
+  virtual Int getMemorySize() const = 0;
 
   // changed empty to match std::vector empty
   inline bool empty() const __attribute__((warn_unused_result)) {
     return size_ == 0;
   }
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors */
   /* ------------------------------------------------------------------------ */
 public:
   /// Get the Size of the Array
-  UInt size() const { return size_; }
+  decltype(auto) size() const { return size_; }
   /// Get the number of components
-  AKANTU_GET_MACRO(NbComponent, nb_component, UInt);
+  decltype(auto) getNbComponent() const { return nb_component; }
   /// Get the name of th array
-  AKANTU_GET_MACRO(ID, id, const ID &);
+  AKANTU_GET_MACRO_AUTO(ID, 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 used
-  UInt size_{0};
+  Int size_{0};
 
   /// number of components
-  UInt nb_component{1};
+  Int nb_component{1};
 };
 
 /* -------------------------------------------------------------------------- */
 /* Memory handling layer                                                      */
 /* -------------------------------------------------------------------------- */
 enum class ArrayAllocationType {
   _default,
   _pod,
 };
 
 template <typename T>
 struct ArrayAllocationTrait
     : public std::conditional_t<
           std::is_scalar<T>::value,
           std::integral_constant<ArrayAllocationType,
                                  ArrayAllocationType::_pod>,
           std::integral_constant<ArrayAllocationType,
                                  ArrayAllocationType::_default>> {};
 
 /* -------------------------------------------------------------------------- */
 template <typename T,
           ArrayAllocationType allocation_trait = ArrayAllocationTrait<T>::value>
 class ArrayDataLayer : public ArrayBase {
 public:
   using value_type = T;
   using size_type = typename ArrayBase::size_type;
   using reference = value_type &;
   using pointer_type = value_type *;
   using const_reference = const value_type &;
 
 public:
   ~ArrayDataLayer() override = default;
 
   /// Allocation of a new vector
-  explicit ArrayDataLayer(UInt size = 0, UInt nb_component = 1,
+  explicit ArrayDataLayer(Int size = 0, Int nb_component = 1,
                           const ID & id = "");
 
   /// Allocation of a new vector with a default value
-  ArrayDataLayer(UInt size, UInt nb_component, const_reference value,
+  ArrayDataLayer(Int size, Int nb_component, const_reference value,
                  const ID & id = "");
 
   /// Copy constructor (deep copy)
   ArrayDataLayer(const ArrayDataLayer & vect, const ID & id = "");
 
   /// Copy constructor (deep copy)
   explicit ArrayDataLayer(const std::vector<value_type> & vect);
 
   // copy operator
   ArrayDataLayer & operator=(const ArrayDataLayer & other);
 
   // move constructor
   ArrayDataLayer(ArrayDataLayer && other) noexcept = default;
 
   // move assign
   ArrayDataLayer & operator=(ArrayDataLayer && other) noexcept = default;
 
 protected:
   // deallocate the memory
   virtual void deallocate() {}
 
   // allocate the memory
-  virtual void allocate(UInt size, UInt nb_component);
+  virtual void allocate(Int size, Int nb_component);
 
   // allocate and initialize the memory
-  virtual void allocate(UInt size, UInt nb_component, const T & value);
+  virtual void allocate(Int size, Int nb_component, const T & value);
 
 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<aka::is_tensor<C<T>>::value>>
-  inline void push_back(const C<T> & new_elem);
+  template <typename Derived>
+  inline void push_back(const Eigen::MatrixBase<Derived> & new_elem);
 
   /// changes the allocated size but not the size, if new_size = 0, the size is
   /// set to min(current_size and reserve size)
-  virtual void reserve(UInt size, UInt new_size = UInt(-1));
+  virtual void reserve(Int size, Int new_size = Int(-1));
 
   /// change the size of the Array
-  virtual void resize(UInt size);
+  virtual void resize(Int size);
 
   /// change the size of the Array and initialize the values
-  virtual void resize(UInt size, const T & val);
+  virtual void resize(Int size, const T & val);
 
   /// get the amount of space allocated in bytes
-  inline UInt getMemorySize() const override;
+  inline Int getMemorySize() const override;
 
   /// Get the real size allocated in memory
-  inline UInt getAllocatedSize() const;
+  inline Int getAllocatedSize() const;
 
   /// give the address of the memory allocated for this vector
   [[deprecated("use data instead to be stl compatible")]] T * storage() const {
     return values;
   };
 
   T * data() const { return values; };
 
 protected:
   /// allocation type agnostic  data access
   T * values{nullptr};
 
   /// data storage
   std::vector<T> data_storage;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Actual Array                                                               */
 /* -------------------------------------------------------------------------- */
 template <typename T, bool is_scal> class Array : public ArrayDataLayer<T> {
 private:
   using parent = ArrayDataLayer<T>;
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using value_type = typename parent::value_type;
   using size_type = typename parent::size_type;
   using reference = typename parent::reference;
   using pointer_type = typename parent::pointer_type;
   using const_reference = typename parent::const_reference;
   using array_type = Array<T>;
 
   ~Array() override;
 
   Array() : Array(0){};
 
   /// Allocation of a new vector
-  explicit Array(UInt size, UInt nb_component = 1, const ID & id = "");
+  explicit Array(Int size, Int nb_component = 1, const ID & id = "");
 
   /// Allocation of a new vector with a default value
-  explicit Array(UInt size, UInt nb_component, const_reference value,
+  explicit Array(Int size, Int nb_component, const_reference value,
                  const ID & id = "");
 
   /// Copy constructor
   Array(const Array & vect, const ID & id = "");
 
   /// Copy constructor (deep copy)
   explicit Array(const std::vector<T> & vect);
 
   // copy operator
   Array & operator=(const Array & other);
 
   // move constructor
   Array(Array && other) noexcept = default;
 
   // move assign
   Array & operator=(Array && other) noexcept = default;
 
   /* ------------------------------------------------------------------------ */
   /* Iterator                                                                 */
   /* ------------------------------------------------------------------------ */
   /// iterator for Array of nb_component = 1
   using scalar_iterator = view_iterator<T>;
   /// const_iterator for Array of nb_component = 1
   using const_scalar_iterator = const_view_iterator<T>;
 
   /// iterator returning Vectors of size n  on entries of Array with
   /// nb_component = n
   using vector_iterator = view_iterator<VectorProxy<T>>;
   /// const_iterator returning Vectors of n size on entries of Array with
   /// nb_component = n
   using const_vector_iterator = const_view_iterator<VectorProxy<const T>>;
 
   /// iterator returning Matrices of size (m, n) on entries of Array with
   /// nb_component = m*n
   using matrix_iterator = view_iterator<MatrixProxy<T>>;
   /// const iterator returning Matrices of size (m, n) on entries of Array with
   /// nb_component = m*n
-  using const_matrix_iterator = const_view_iterator<MatrixProxy<T>>;
+  using const_matrix_iterator = const_view_iterator<MatrixProxy<const T>>;
 
   /// iterator returning Tensor3 of size (m, n, k) on entries of Array with
   /// nb_component = m*n*k
   using tensor3_iterator = view_iterator<Tensor3Proxy<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_view_iterator<Tensor3Proxy<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 auto begin(Ns &&... n);
+  template <typename... Ns> inline auto end(Ns &&... n);
+  template <typename... Ns> inline auto begin(Ns &&... n) const;
+  template <typename... Ns> inline auto end(Ns &&... n) const;
 
   template <typename... Ns>
-  inline decltype(auto) begin_reinterpret(Ns &&... n) const;
+  [[deprecated("use make_view instead")]] inline auto
+  begin_reinterpret(Ns &&... n);
+  template <typename... Ns>
+  [[deprecated("use make_view instead")]] inline auto
+  end_reinterpret(Ns &&... n);
+  template <typename... Ns>
+  [[deprecated("use make_view instead")]] inline auto
+  begin_reinterpret(Ns &&... n) const;
   template <typename... Ns>
-  inline decltype(auto) end_reinterpret(Ns &&... n) const;
+  [[deprecated("use make_view instead")]] inline auto
+  end_reinterpret(Ns &&... n) const;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// search elem in the vector, return  the position of the first occurrence or
   /// -1 if not found
-  UInt find(const_reference elem) const;
+  Idx find(const_reference elem) const;
 
   /// @see Array::find(const_reference elem) const
   //  UInt find(T elem[]) const;
 
   /// append a value to the end of the Array
   inline void push_back(const_reference value) { parent::push_back(value); }
 
   /// append a Vector or a Matrix
   template <typename Derived>
   inline void push_back(const Eigen::MatrixBase<Derived> & new_elem) {
     parent::push_back(new_elem);
   }
 
   /// append the content of the iterator at the end of the Array
   template <typename Ret> inline void push_back(const view_iterator<Ret> & it) {
     push_back(*it);
   }
 
   /// erase the value at position i
-  inline void erase(UInt i);
+  inline void erase(Idx i);
   /// ask Nico, clarify
   template <typename R> inline auto erase(const view_iterator<R> & it);
 
   /// @see Array::find(const_reference elem) const
   template <template <typename> class C,
             typename = std::enable_if_t<aka::is_tensor<C<T>>::value>>
-  inline UInt find(const C<T> & elem);
+  inline Idx find(const C<T> & elem);
 
   /// 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(this->values, this->size_ * this->nb_component, t);
   }
 
   /// set the array to T{}
   inline void zero() { this->set({}); }
 
   /// resize the array to 0
   inline void clear() { this->resize(0); }
 
   /// 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<aka::is_tensor<C<T>>::value>>
   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);
 
   /// function to print the containt of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /* ------------------------------------------------------------------------ */
   /* 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);
+  inline reference operator()(Idx i, Idx 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;
+  inline const_reference operator()(Idx i, Idx j = 0) const;
 
   /// return a reference to the ith component of the 1D array
-  inline reference operator[](UInt i);
+  inline reference operator[](Idx i);
   /// return a const reference to the ith component of the 1D array
-  inline const_reference operator[](UInt i) const;
+  inline const_reference operator[](Idx i) const;
 };
 
 /* -------------------------------------------------------------------------- */
 /* 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"
 
 #endif /* AKANTU_ARRAY_HH_ */
diff --git a/src/common/aka_array_tmpl.hh b/src/common/aka_array_tmpl.hh
index d5d76b804..a0f2de1a9 100644
--- a/src/common/aka_array_tmpl.hh
+++ b/src/common/aka_array_tmpl.hh
@@ -1,1028 +1,1041 @@
 /**
  * @file   aka_array_tmpl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
  * @date last modification: Fri Feb 26 2021
  *
  * @brief  Inline functions of the classes Array<T> and ArrayBase
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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" // NOLINT
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_AKA_ARRAY_TMPL_HH_
 #define AKANTU_AKA_ARRAY_TMPL_HH_
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 namespace debug {
   struct ArrayException : public Exception {};
 } // namespace debug
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
-ArrayDataLayer<T, allocation_trait>::ArrayDataLayer(UInt size,
-                                                    UInt nb_component,
+ArrayDataLayer<T, allocation_trait>::ArrayDataLayer(Int size, Int nb_component,
                                                     const ID & id)
     : ArrayBase(id) {
   allocate(size, nb_component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
-ArrayDataLayer<T, allocation_trait>::ArrayDataLayer(UInt size,
-                                                    UInt nb_component,
+ArrayDataLayer<T, allocation_trait>::ArrayDataLayer(Int size, Int nb_component,
                                                     const_reference value,
                                                     const ID & id)
     : ArrayBase(id) {
   allocate(size, nb_component, value);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
 ArrayDataLayer<T, allocation_trait>::ArrayDataLayer(const ArrayDataLayer & vect,
                                                     const ID & id)
     : ArrayBase(vect, id) {
   this->data_storage = vect.data_storage;
   this->size_ = vect.size_;
   this->nb_component = vect.nb_component;
   this->values = this->data_storage.data();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
 ArrayDataLayer<T, allocation_trait>::ArrayDataLayer(
     const std::vector<value_type> & vect) {
   this->data_storage = vect;
   this->size_ = vect.size();
   this->nb_component = 1;
   this->values = this->data_storage.data();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
 ArrayDataLayer<T, allocation_trait> &
 ArrayDataLayer<T, allocation_trait>::operator=(const ArrayDataLayer & other) {
   if (this != &other) {
     this->data_storage = other.data_storage;
     this->nb_component = other.nb_component;
     this->size_ = other.size_;
     this->values = this->data_storage.data();
   }
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
 void ArrayDataLayer<T, allocation_trait>::allocate(UInt new_size,
                                                    UInt nb_component) {
   this->nb_component = nb_component;
   this->resize(new_size);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
-void ArrayDataLayer<T, allocation_trait>::allocate(UInt new_size,
-                                                   UInt nb_component,
+void ArrayDataLayer<T, allocation_trait>::allocate(Int new_size,
+                                                   Int nb_component,
                                                    const T & val) {
   this->nb_component = nb_component;
   this->resize(new_size, val);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
-void ArrayDataLayer<T, allocation_trait>::resize(UInt new_size) {
+void ArrayDataLayer<T, allocation_trait>::resize(Int new_size) {
   this->data_storage.resize(new_size * this->nb_component);
   this->values = this->data_storage.data();
   this->size_ = new_size;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
-void ArrayDataLayer<T, allocation_trait>::resize(UInt new_size,
+void ArrayDataLayer<T, allocation_trait>::resize(Int new_size,
                                                  const T & value) {
   this->data_storage.resize(new_size * this->nb_component, value);
   this->values = this->data_storage.data();
   this->size_ = new_size;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
-void ArrayDataLayer<T, allocation_trait>::reserve(UInt size, UInt new_size) {
-  if (new_size != UInt(-1)) {
+void ArrayDataLayer<T, allocation_trait>::reserve(Int size, Int new_size) {
+  if (new_size != -1) {
     this->data_storage.resize(new_size * this->nb_component);
   }
 
   this->data_storage.reserve(size * this->nb_component);
   this->values = this->data_storage.data();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * 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 <typename T, ArrayAllocationType allocation_trait>
 inline void ArrayDataLayer<T, allocation_trait>::push_back(const T & value) {
   this->data_storage.push_back(value);
   this->values = this->data_storage.data();
   this->size_ += 1;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * append a matrix or a vector to the array
  * @param new_elem a reference to a Matrix<T> or Vector<T> */
 template <typename T, ArrayAllocationType allocation_trait>
-template <template <typename> class C, typename>
-inline void
-ArrayDataLayer<T, allocation_trait>::push_back(const C<T> & new_elem) {
+template <typename Derived>
+inline void ArrayDataLayer<T, allocation_trait>::push_back(
+    const Eigen::MatrixBase<Derived> & 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 << ").");
-  for (UInt i = 0; i < new_elem.size(); ++i) {
-    this->data_storage.push_back(new_elem[i]);
+  for (Idx i = 0; i < new_elem.size(); ++i) {
+    this->data_storage.push_back(new_elem.data()[i]);
   }
   this->values = this->data_storage.data();
   this->size_ += 1;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
-inline UInt ArrayDataLayer<T, allocation_trait>::getAllocatedSize() const {
+inline Int ArrayDataLayer<T, allocation_trait>::getAllocatedSize() const {
   return this->data_storage.capacity() / this->nb_component;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, ArrayAllocationType allocation_trait>
-inline UInt ArrayDataLayer<T, allocation_trait>::getMemorySize() const {
+inline Int ArrayDataLayer<T, allocation_trait>::getMemorySize() const {
   return this->data_storage.capacity() * sizeof(T);
 }
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 class ArrayDataLayer<T, ArrayAllocationType::_pod> : public ArrayBase {
 public:
   using value_type = T;
   using reference = value_type &;
   using pointer_type = value_type *;
   using const_reference = const value_type &;
 
 public:
   ~ArrayDataLayer() override { deallocate(); }
 
   /// Allocation of a new vector
-  ArrayDataLayer(UInt size = 0, UInt nb_component = 1, const ID & id = "")
+  ArrayDataLayer(Int size = 0, Int nb_component = 1, const ID & id = "")
       : ArrayBase(id) {
     allocate(size, nb_component);
   }
 
   /// Allocation of a new vector with a default value
-  ArrayDataLayer(UInt size, UInt nb_component, const_reference value,
+  ArrayDataLayer(Int size, Int nb_component, const_reference value,
                  const ID & id = "")
       : ArrayBase(id) {
     allocate(size, nb_component, value);
   }
 
   /// Copy constructor (deep copy)
   ArrayDataLayer(const ArrayDataLayer & vect, const ID & id = "")
       : ArrayBase(vect, id) {
     allocate(vect.size(), vect.getNbComponent());
     std::copy_n(vect.data(), this->size_ * this->nb_component, values);
   }
 
   /// Copy constructor (deep copy)
   explicit ArrayDataLayer(const std::vector<value_type> & vect) {
     allocate(vect.size(), 1);
     std::copy_n(vect.data(), this->size_ * this->nb_component, values);
   }
 
   // copy operator
   inline ArrayDataLayer & operator=(const ArrayDataLayer & other) {
     if (this != &other) {
       allocate(other.size(), other.getNbComponent());
       std::copy_n(other.data(), this->size_ * this->nb_component, values);
     }
     return *this;
   }
 
   // move constructor
   inline ArrayDataLayer(ArrayDataLayer && other) noexcept = default;
 
   // move assign
   inline ArrayDataLayer & operator=(ArrayDataLayer && other) noexcept = default;
 
 protected:
   // deallocate the memory
   virtual void deallocate() {
     // NOLINTNEXTLINE(cppcoreguidelines-owning-memory,
     // cppcoreguidelines-no-malloc)
     free(this->values);
   }
 
   // allocate the memory
-  virtual inline void allocate(UInt size, UInt nb_component) {
+  virtual inline void allocate(Int size, Int nb_component) {
     if (size != 0) { // malloc can return a non NULL pointer in case size is 0
       this->values = static_cast<T *>(                   // NOLINT
           std::malloc(nb_component * size * sizeof(T))); // NOLINT
     }
 
     if (this->values == nullptr and size != 0) {
       throw std::bad_alloc();
     }
     this->nb_component = nb_component;
     this->allocated_size = this->size_ = size;
   }
 
   // allocate and initialize the memory
-  virtual inline void allocate(UInt size, UInt nb_component, const T & value) {
+  virtual inline void allocate(Int size, Int nb_component, const T & value) {
     allocate(size, nb_component);
     std::fill_n(values, size * nb_component, value);
   }
 
 public:
   /// append a tuple of size nb_component containing value
   inline void push_back(const_reference value) {
     resize(this->size_ + 1, value);
   }
 
   /// append a Vector or a Matrix
-  template <template <typename> class C,
-            typename = std::enable_if_t<aka::is_tensor<C<T>>::value>>
-  inline void push_back(const C<T> & new_elem) {
+  template <typename Derived>
+  inline void push_back(const Eigen::MatrixBase<Derived> & 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 << ").");
     this->resize(this->size_ + 1);
     std::copy_n(new_elem.data(), new_elem.size(),
                 values + this->nb_component * (this->size_ - 1));
   }
 
   /// changes the allocated size but not the size
-  virtual void reserve(UInt size, UInt new_size = UInt(-1)) {
-    UInt tmp_size = this->size_;
-    if (new_size != UInt(-1)) {
+  virtual void reserve(Int size, Int new_size = Int(-1)) {
+    auto tmp_size = this->size_;
+    if (new_size != Int(-1))
       tmp_size = new_size;
     }
     this->resize(size);
     this->size_ = std::min(this->size_, tmp_size);
   }
 
   /// change the size of the Array
-  virtual void resize(UInt size) {
+  virtual void resize(Int size) {
     if (size * this->nb_component == 0) {
       free(values); // NOLINT: cppcoreguidelines-no-malloc
       values = nullptr;
       this->allocated_size = 0;
     } else {
       if (this->values == nullptr) {
         this->allocate(size, this->nb_component);
         return;
       }
 
       Int diff = size - allocated_size;
-      UInt size_to_allocate = (std::abs(diff) > AKANTU_MIN_ALLOCATION)
-                                  ? size
-                                  : (diff > 0)
-                                        ? allocated_size + AKANTU_MIN_ALLOCATION
-                                        : allocated_size;
+      Int size_to_allocate = (std::abs(diff) > AKANTU_MIN_ALLOCATION)
+                                 ? size
+                                 : (diff > 0)
+                                       ? allocated_size + AKANTU_MIN_ALLOCATION
+                                       : allocated_size;
 
       if (size_to_allocate ==
           allocated_size) { // otherwhy the reserve + push_back might fail...
         this->size_ = size;
         return;
       }
 
       auto * tmp_ptr = reinterpret_cast<T *>( // NOLINT
           realloc(this->values,
                   size_to_allocate * this->nb_component * sizeof(T)));
 
       if (tmp_ptr == nullptr) {
         throw std::bad_alloc();
       }
 
       this->values = tmp_ptr;
       this->allocated_size = size_to_allocate;
     }
 
     this->size_ = size;
   }
 
   /// change the size of the Array and initialize the values
-  virtual void resize(UInt size, const T & val) {
-    UInt tmp_size = this->size_;
+  virtual void resize(Int size, const T & val) {
+    Int tmp_size = this->size_;
     this->resize(size);
     if (size > tmp_size) {
       // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
       std::fill_n(values + this->nb_component * tmp_size,
                   (size - tmp_size) * this->nb_component, val);
     }
   }
 
   /// get the amount of space allocated in bytes
   inline UInt getMemorySize() const final {
     return this->allocated_size * this->nb_component * sizeof(T);
   }
 
   /// Get the real size allocated in memory
-  inline UInt getAllocatedSize() const { return this->allocated_size; }
+  inline Int getAllocatedSize() const { return this->allocated_size; }
 
   /// give the address of the memory allocated for this vector
   [[deprecated("use data instead to be stl compatible")]] T * storage() const {
     return values;
   };
   T * data() const { return values; };
 
 protected:
   /// allocation type agnostic  data access
   T * values{nullptr};
 
-  UInt allocated_size{0};
+  Int allocated_size{0};
 };
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
-inline auto Array<T, is_scal>::operator()(UInt i, UInt j) -> reference {
+inline auto Array<T, is_scal>::operator()(Int i, Int j) -> reference {
   AKANTU_DEBUG_ASSERT(this->size_ > 0,
                       "The array \"" << this->id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < this->size_) && (j < this->nb_component),
                       "The value at position ["
                           << i << "," << j << "] is out of range in array \""
                           << this->id << "\"");
   return this->values[i * this->nb_component + j];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
-inline auto Array<T, is_scal>::operator()(UInt i, UInt j) const
+inline auto Array<T, is_scal>::operator()(Int i, Int j) const
     -> const_reference {
   AKANTU_DEBUG_ASSERT(this->size_ > 0,
                       "The array \"" << this->id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < this->size_) && (j < this->nb_component),
                       "The value at position ["
                           << i << "," << j << "] is out of range in array \""
                           << this->id << "\"");
   // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
   return this->values[i * this->nb_component + j];
 }
 
 template <class T, bool is_scal>
-inline auto Array<T, is_scal>::operator[](UInt i) -> reference {
+inline auto Array<T, is_scal>::operator[](Int i) -> reference {
   AKANTU_DEBUG_ASSERT(this->size_ > 0,
                       "The array \"" << this->id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < this->size_ * this->nb_component),
                       "The value at position ["
                           << i << "] is out of range in array \"" << this->id
                           << "\"");
   return this->values[i];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
-inline auto Array<T, is_scal>::operator[](UInt i) const -> const_reference {
+inline auto Array<T, is_scal>::operator[](Int i) const -> const_reference {
   AKANTU_DEBUG_ASSERT(this->size_ > 0,
                       "The array \"" << this->id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < this->size_ * this->nb_component),
                       "The value at position ["
                           << i << "] is out of range in array \"" << this->id
                           << "\"");
   return this->values[i];
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * 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) {
+template <class T, bool is_scal> inline void Array<T, is_scal>::erase(Int i) {
   AKANTU_DEBUG_IN();
   AKANTU_DEBUG_ASSERT((this->size_ > 0), "The array is empty");
   AKANTU_DEBUG_ASSERT((i < this->size_), "The element at position ["
                                              << i << "] is out of range (" << i
                                              << ">=" << this->size_ << ")");
 
   if (i != (this->size_ - 1)) {
-    for (UInt j = 0; j < this->nb_component; ++j) {
-      // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
+    for (Idx j = 0; j < this->nb_component; ++j) {
       this->values[i * this->nb_component + j] =
           this->values[(this->size_ - 1) * this->nb_component + j];
     }
   }
 
   this->resize(this->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> & other) {
   AKANTU_DEBUG_ASSERT((this->size_ == other.size_) &&
                           (this->nb_component == other.nb_component),
                       "The too array don't have the same sizes");
 
   T * a = this->values;
   T * b = vect.data();
-  for (UInt i = 0; i < this->size_ * this->nb_component; ++i) {
+  for (Idx i = 0; i < this->size_ * this->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> & other) {
   AKANTU_DEBUG_ASSERT((this->size_ == other.size()) &&
                           (this->nb_component == other.nb_component),
                       "The too array don't have the same sizes");
 
   T * a = this->values;
   T * b = vect.data();
-  for (UInt i = 0; i < this->size_ * this->nb_component; ++i) {
+  for (Idx i = 0; i < this->size_ * this->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 = this->values;
-  for (UInt i = 0; i < this->size_ * this->nb_component; ++i) {
+  for (Idx i = 0; i < this->size_ * this->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> & other) const {
   bool equal = this->nb_component == other.nb_component &&
                this->size_ == other.size_ && this->id == other.id;
   if (not equal) {
     return false;
 
   if (this->values == array.data()) {
     return true;
   }
   return std::equal(this->values,
                     this->values + this->size_ * this->nb_component,
                     array.data());
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 bool Array<T, is_scal>::operator!=(const Array<T, is_scal> & other) const {
   return !operator==(other);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * 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(this->nb_component == vm.size(),
                       "The size of the object does not "
                       "match the number of components");
   for (T * it = this->values;
        it < this->values + this->nb_component * this->size_;
        it += this->nb_component) {
     std::copy_n(vm.data(), this->nb_component, it);
   }
 }
 /* --------------------------------------------------------------------------
  */
 template <class T, bool is_scal>
 void Array<T, is_scal>::append(const Array<T> & other) {
-  AKANTU_DEBUG_ASSERT(this->nb_component == other.nb_component,
-                      "Cannot append an array with a "
-                      "different number of component");
-  UInt old_size = this->size_;
+  AKANTU_DEBUG_ASSERT(
+      this->nb_component == other.nb_component,
+      "Cannot append an array with a different number of component");
+  Idx old_size = this->size_;
   this->resize(this->size_ + other.size());
 
   T * tmp = this->values + this->nb_component * old_size;
   std::copy_n(other.data(), other.size() * this->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)
+Array<T, is_scal>::Array(Int size, Int nb_component, const ID & id)
     : parent(size, nb_component, id) {}
 
 template <>
-inline Array<std::string, false>::Array(UInt size, UInt nb_component,
+inline Array<std::string, false>::Array(Int size, Int nb_component,
                                         const ID & id)
     : parent(size, nb_component, "", id) {}
 
 /* --------------------------------------------------------------------------
  */
 template <class T, bool is_scal>
-Array<T, is_scal>::Array(UInt size, UInt nb_component, const_reference value,
+Array<T, is_scal>::Array(Int size, Int nb_component, const_reference value,
                          const ID & id)
     : parent(size, nb_component, value, id) {}
 
 /* --------------------------------------------------------------------------
  */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(const Array & vect, const ID & id)
     : parent(vect, id) {}
 
 /* --------------------------------------------------------------------------
  */
 template <class T, bool is_scal>
 Array<T, is_scal> &
 Array<T, is_scal>::operator=(const Array<T, is_scal> & other) {
   AKANTU_DEBUG_WARNING("You are copying the array "
                        << this->id << " are you sure it is on purpose");
 
   if (&other == this) {
     return *this;
   }
 
   parent::operator=(other);
   return *this;
 }
 
 /* --------------------------------------------------------------------------
  */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(const std::vector<T> & vect) : parent(vect) {}
 
 /* --------------------------------------------------------------------------
  */
 template <class T, bool is_scal> Array<T, is_scal>::~Array() = default;
 
 /* --------------------------------------------------------------------------
  */
 /**
  * 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_reference elem) const {
+Idx Array<T, is_scal>::find(const_reference 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);
+  return (it != end) ? it - begin : Idx(-1);
 }
 
 /* --------------------------------------------------------------------------
  */
 // template <class T, bool is_scal> UInt Array<T,
 // is_scal>::find(T elem[]) const
 // {
 //   AKANTU_DEBUG_IN();
 //   T * it = this->values;
 //   UInt i = 0;
 //   for (; i < this->size_; ++i) {
 //     if (*it == elem[0]) {
 //       T * cit = it;
 //       UInt c = 0;
 //       for (; (c < this->nb_component) && (*cit ==
 //       elem[c]); ++c, ++cit)
 //         ;
 //       if (c == this->nb_component) {
 //         AKANTU_DEBUG_OUT();
 //         return i;
 //       }
 //     }
 //     it += this->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) {
+inline Idx Array<T, is_scal>::find(const C<T> & elem) {
   AKANTU_DEBUG_ASSERT(elem.size() == this->nb_component,
                       "Cannot find an element with a wrong size ("
                           << elem.size() << ") != " << this->nb_component);
   return this->find(elem.data());
 }
 
 /* --------------------------------------------------------------------------
  */
 /**
  * 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.
  * @param no_sanity_check turns off all checkes
  */
 template <class T, bool is_scal>
 void Array<T, is_scal>::copy(const Array<T, is_scal> & other,
                              bool no_sanity_check) {
   AKANTU_DEBUG_IN();
 
   if (not no_sanity_check and (other.nb_component != this->nb_component)) {
     AKANTU_ERROR("The two arrays do not have the same "
                  "number of components");
   }
 
   this->resize((other.size_ * other.nb_component) / this->nb_component);
 
   std::copy_n(vect.data(), this->size_ * this->nb_component, this->values);
 
   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) {
     std::string space(indent, AKANTU_INDENT);
 
     stream << space << " + values         : {";
-    for (UInt i = 0; i < vect.size(); ++i) {
+    for (Idx i = 0; i < vect.size(); ++i) {
       stream << "{";
-      for (UInt j = 0; j < vect.getNbComponent(); ++j) {
+      for (Idx 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(indent, 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->getAllocatedSize()
          << std::endl;
   stream << space
          << " + memory size    : " << printMemorySize<T>(this->getMemorySize())
          << std::endl;
   if (not AKANTU_DEBUG_LEVEL_IS_TEST()) {
     stream << space << " + address        : " << std::hex << this->values
            << std::dec << std::endl;
   }
 
   stream.precision(prec);
   stream.flags(ff);
 
   if (AKANTU_DEBUG_TEST(dblDump) || AKANTU_DEBUG_LEVEL_IS_TEST()) {
     ArrayPrintHelper<is_scal or std::is_enum<T>::value>::print_content(
         *this, stream, indent);
   }
 
   stream << space << "]" << std::endl;
 }
 
 /* --------------------------------------------------------------------------
  */
 /* Inline Functions ArrayBase */
 /* --------------------------------------------------------------------------
  */
 
 // inline bool ArrayBase::empty() { return (this->size_ ==
 // 0); }
 
 #ifndef SWIG
 /* -------------------------------------------------------------------------- */
 /* Begin/End functions implementation                                         */
 /* -------------------------------------------------------------------------- */
 namespace detail {
   template <class Tuple, size_t... Is>
   constexpr auto take_front_impl(Tuple && t,
                                  std::index_sequence<Is...> /*idxs*/) {
     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... 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) {
     const auto is_const_arr =
         std::is_const<std::remove_reference_t<Arr>>::value;
     using type = ViewIteratorHelper_t<sizeof...(Ns) - 1, T>;
     using iterator = std::conditional_t<is_const_arr, const_view_iterator<type>,
                                         view_iterator<type>>;
     static_assert(sizeof...(Ns), "You should provide a least one size");
 
     if (array.getNbComponent() * array.size() !=
-        product_all(std::forward<Ns>(ns)...)) {
+        Int(product_all(std::forward<Ns>(ns)...))) {
       AKANTU_CUSTOM_EXCEPTION_INFO(
           debug::ArrayException(),
           "The iterator on "
               << debug::demangle(typeid(Arr).name())
               << to_string_all(array.size(), array.getNbComponent())
               << "is not compatible with the type "
               << debug::demangle(typeid(type).name()) << to_string_all(ns...));
     }
 
     auto && it =
         aka::apply([&](auto... n) { return iterator(data, n...); },
                    take_front<sizeof...(Ns) - 1>(std::make_tuple(ns...)));
 
     return it;
   }
 } // namespace detail
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <typename... Ns>
-inline decltype(auto) Array<T, is_scal>::begin(Ns &&... ns) {
+inline auto Array<T, is_scal>::begin(Ns &&... ns) {
   return detail::get_iterator(*this, this->values, std::forward<Ns>(ns)...,
                               this->size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
-inline decltype(auto) Array<T, is_scal>::end(Ns &&... ns) {
+inline auto Array<T, is_scal>::end(Ns &&... ns) {
   return detail::get_iterator(*this,
                               this->values + this->nb_component * this->size_,
                               std::forward<Ns>(ns)..., this->size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
-inline decltype(auto) Array<T, is_scal>::begin(Ns &&... ns) const {
+inline auto Array<T, is_scal>::begin(Ns &&... ns) const {
   return detail::get_iterator(*this, this->values, std::forward<Ns>(ns)...,
                               this->size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
-inline decltype(auto) Array<T, is_scal>::end(Ns &&... ns) const {
+inline auto Array<T, is_scal>::end(Ns &&... ns) const {
   return detail::get_iterator(*this,
                               this->values + this->nb_component * this->size_,
                               std::forward<Ns>(ns)..., this->size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
-inline decltype(auto) Array<T, is_scal>::begin_reinterpret(Ns &&... ns) {
+inline auto Array<T, is_scal>::begin_reinterpret(Ns &&... ns) {
   return detail::get_iterator(*this, 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) {
+inline auto Array<T, is_scal>::end_reinterpret(Ns &&... ns) {
   return detail::get_iterator(
       *this, 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 {
+inline auto Array<T, is_scal>::begin_reinterpret(Ns &&... ns) const {
   return detail::get_iterator(*this, 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 {
+inline auto Array<T, is_scal>::end_reinterpret(Ns &&... ns) const {
   return detail::get_iterator(
       *this, 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() = default;
     ArrayView(Array && array, Ns... ns) noexcept
         : array(array), sizes(std::move(ns)...) {}
 
     ArrayView(const ArrayView & array_view) = default;
     ArrayView & operator=(const ArrayView & array_view) = default;
 
     ArrayView(ArrayView && array_view) noexcept = default;
     ArrayView & operator=(ArrayView && array_view) noexcept = default;
 
-    decltype(auto) begin() {
+    auto begin() {
       return aka::apply(
-          [&](auto &&... ns) { return array.get().begin_reinterpret(ns...); },
+          [&](auto &&... ns) {
+            return detail::get_iterator(array.get(), array.get().data(),
+                                        std::forward<Ns>(ns)...);
+          },
           sizes);
     }
 
-    decltype(auto) begin() const {
+    auto begin() const {
       return aka::apply(
-          [&](auto &&... ns) { return array.get().begin_reinterpret(ns...); },
+          [&](auto &&... ns) {
+            return detail::get_iterator(array.get(), array.get().data(),
+                                        std::forward<Ns>(ns)...);
+          },
           sizes);
     }
 
-    decltype(auto) end() {
+    auto end() {
       return aka::apply(
-          [&](auto &&... ns) { return array.get().end_reinterpret(ns...); },
+          [&](auto &&... ns) {
+            return detail::get_iterator(
+                array.get(),
+                array.get().data() +
+                    detail::product_all(std::forward<Ns>(ns)...),
+                std::forward<Ns>(ns)...);
+          },
           sizes);
     }
 
-    decltype(auto) end() const {
+    auto end() const {
       return aka::apply(
-          [&](auto &&... ns) { return array.get().end_reinterpret(ns...); },
+          [&](auto &&... ns) {
+            return detail::get_iterator(
+                array.get(),
+                array.get().data() +
+                    detail::product_all(std::forward<Ns>(ns)...),
+                std::forward<Ns>(ns)...);
+          },
           sizes);
     }
 
-    decltype(auto) size() const {
+    auto size() const {
       return std::get<std::tuple_size<tuple>::value - 1>(sizes);
     }
 
-    decltype(auto) dims() const { return std::tuple_size<tuple>::value - 1; }
+    auto dims() const { return std::tuple_size<tuple>::value - 1; }
 
   private:
     std::reference_wrapper<std::remove_reference_t<Array>> array;
     tuple sizes;
   };
 } // namespace detail
 
 /* -------------------------------------------------------------------------- */
 template <typename Array, typename... Ns>
 decltype(auto) make_view(Array && array, const Ns... ns) {
   static_assert(aka::conjunction<std::is_integral<std::decay_t<Ns>>...>::value,
                 "Ns should be integral types");
   AKANTU_DEBUG_ASSERT((detail::product_all(ns...) != 0),
                       "You must specify non zero dimensions");
   auto size = std::forward<decltype(array)>(array).size() *
               std::forward<decltype(array)>(array).getNbComponent() /
               detail::product_all(ns...);
 
   return detail::ArrayView<Array, std::common_type_t<size_t, Ns>...,
                            std::common_type_t<size_t, decltype(size)>>(
       std::forward<Array>(array), std::move(ns)..., size);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <typename R>
 inline auto Array<T, is_scal>::erase(const view_iterator<R> & it) {
   T * curr = it.data();
-  UInt pos = (curr - this->values) / this->nb_component;
+  Idx pos = (curr - this->values) / this->nb_component;
   erase(pos);
   view_iterator<R> rit = it;
   return --rit;
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_AKA_ARRAY_TMPL_HH_ */
diff --git a/src/common/aka_common.hh b/src/common/aka_common.hh
index a872c11a4..1306d2f68 100644
--- a/src/common/aka_common.hh
+++ b/src/common/aka_common.hh
@@ -1,709 +1,712 @@
 /**
  * @file   aka_common.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
  * @date last modification: Sat May 01 2021
  *
  * @brief  common type descriptions for akantu
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_COMMON_HH_
 #define AKANTU_COMMON_HH_
 
 #include "aka_compatibilty_with_cpp_standard.hh"
 
 /* -------------------------------------------------------------------------- */
 #if defined(WIN32)
 #define __attribute__(x)
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include "aka_config.hh"
 #include "aka_error.hh"
 #include "aka_safe_enum.hh"
 /* -------------------------------------------------------------------------- */
 #include <boost/preprocessor.hpp>
 #include <limits>
 #include <list>
 #include <memory>
 #include <string>
 #include <type_traits>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Constants                                                                  */
 /* -------------------------------------------------------------------------- */
 namespace {
-  [[gnu::unused]] constexpr UInt _all_dimensions{
+  [[gnu::unused]] constexpr Int _all_dimensions{
       std::numeric_limits<UInt>::max()};
 #ifdef AKANTU_NDEBUG
   [[gnu::unused]] constexpr Real REAL_INIT_VALUE{0.};
 #else
   [[gnu::unused]] constexpr Real REAL_INIT_VALUE{
       std::numeric_limits<Real>::quiet_NaN()};
 #endif
 } // namespace
 
 /* -------------------------------------------------------------------------- */
 /* Common types                                                               */
 /* -------------------------------------------------------------------------- */
 using ID = std::string;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #include "aka_enum_macros.hh"
 /* -------------------------------------------------------------------------- */
 #include "aka_element_classes_info.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 /* Mesh/FEM/Model types                                                       */
 /* -------------------------------------------------------------------------- */
 
 /// small help to use names for directions
 enum SpatialDirection { _x = 0, _y = 1, _z = 2 };
 
 /// enum MeshIOType type of mesh reader/writer
 enum MeshIOType {
   _miot_auto,        ///< Auto guess of the reader to use based on the extension
   _miot_gmsh,        ///< Gmsh files
   _miot_gmsh_struct, ///< Gsmh reader with reintpretation of elements has
                      /// structures elements
   _miot_diana,       ///< TNO Diana mesh format
   _miot_abaqus       ///< Abaqus mesh format
 };
 
 /// enum MeshEventHandlerPriority defines relative order of execution of
 /// events
 enum EventHandlerPriority {
   _ehp_highest = 0,
   _ehp_mesh = 5,
   _ehp_fe_engine = 9,
   _ehp_synchronizer = 10,
   _ehp_dof_manager = 20,
   _ehp_model = 94,
   _ehp_non_local_manager = 100,
   _ehp_lowest = 100
 };
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_MODEL_TYPES                      \
   (model)                                       \
   (solid_mechanics_model)                       \
   (solid_mechanics_model_cohesive)              \
   (heat_transfer_model)                         \
   (structural_mechanics_model)                  \
   (embedded_model)                              \
   (contact_mechanics_model)                     \
   (coupler_solid_contact)                       \
   (coupler_solid_cohesive_contact)              \
   (phase_field_model)                           \
   (coupler_solid_phasefield)
 // clang-format on
 
 /// enum ModelType defines which type of physics is solved
 AKANTU_CLASS_ENUM_DECLARE(ModelType, AKANTU_MODEL_TYPES)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(ModelType, AKANTU_MODEL_TYPES)
 AKANTU_CLASS_ENUM_INPUT_STREAM(ModelType, AKANTU_MODEL_TYPES)
 #else
 enum class ModelType {
   model,
   solid_mechanics_model,
   solid_mechanics_model_cohesive,
   heat_transfer_model,
   structural_mechanics_model,
   embedded_model,
 };
 #endif
 /// enum AnalysisMethod type of solving method used to solve the equation of
 /// motion
 enum AnalysisMethod {
   _static = 0,
   _implicit_dynamic = 1,
   _explicit_lumped_mass = 2,
   _explicit_lumped_capacity = 2,
   _explicit_consistent_mass = 3,
   _explicit_contact = 4,
   _implicit_contact = 5
 };
 
 /// enum DOFSupportType defines which kind of dof that can exists
 enum DOFSupportType { _dst_nodal, _dst_generic };
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_NON_LINEAR_SOLVER_TYPES                                 \
   (linear)                                                             \
   (newton_raphson)                                                     \
   (newton_raphson_modified)                                            \
   (lumped)                                                             \
   (gmres)                                                              \
   (bfgs)                                                               \
   (cg)                                                                 \
   (newton_raphson_contact)                                             \
   (auto)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(NonLinearSolverType, AKANTU_NON_LINEAR_SOLVER_TYPES)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(NonLinearSolverType,
                                 AKANTU_NON_LINEAR_SOLVER_TYPES)
 AKANTU_CLASS_ENUM_INPUT_STREAM(NonLinearSolverType,
                                AKANTU_NON_LINEAR_SOLVER_TYPES)
 #else
 /// Type of non linear resolution available in akantu
 enum class NonLinearSolverType {
   _linear,                  ///< No non linear convergence loop
   _newton_raphson,          ///< Regular Newton-Raphson
   _newton_raphson_modified, ///< Newton-Raphson with initial tangent
   _lumped,                  ///< Case of lumped mass or equivalent matrix
   _gmres,
   _bfgs,
   _cg,
   _newton_raphson_contact, ///< Regular Newton-Raphson modified
                            /// for contact problem
   _auto, ///< This will take a default value that make sense in case of
          ///  model::getNewSolver
 };
 #endif
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_TIME_STEP_SOLVER_TYPE                                    \
   (static)                                                             \
   (dynamic)                                                            \
   (dynamic_lumped)                                                     \
   (not_defined)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(TimeStepSolverType, AKANTU_TIME_STEP_SOLVER_TYPE)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(TimeStepSolverType,
                                 AKANTU_TIME_STEP_SOLVER_TYPE)
 AKANTU_CLASS_ENUM_INPUT_STREAM(TimeStepSolverType, AKANTU_TIME_STEP_SOLVER_TYPE)
 #else
 /// Type of time stepping solver
 enum class TimeStepSolverType {
   _static,         ///< Static solution
   _dynamic,        ///< Dynamic solver
   _dynamic_lumped, ///< Dynamic solver with lumped mass
   _not_defined,    ///< For not defined cases
 };
 #endif
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_INTEGRATION_SCHEME_TYPE                                 \
   (pseudo_time)                                                        \
   (forward_euler)                                                      \
   (trapezoidal_rule_1)                                                 \
   (backward_euler)                                                     \
   (central_difference)                                                 \
   (fox_goodwin)                                                        \
   (trapezoidal_rule_2)                                                 \
   (linear_acceleration)                                                \
   (newmark_beta)                                                       \
   (generalized_trapezoidal)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(IntegrationSchemeType, AKANTU_INTEGRATION_SCHEME_TYPE)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(IntegrationSchemeType,
                                 AKANTU_INTEGRATION_SCHEME_TYPE)
 AKANTU_CLASS_ENUM_INPUT_STREAM(IntegrationSchemeType,
                                AKANTU_INTEGRATION_SCHEME_TYPE)
 #else
 /// Type of integration scheme
 enum class IntegrationSchemeType {
   _pseudo_time,            ///< Pseudo Time
   _forward_euler,          ///< GeneralizedTrapezoidal(0)
   _trapezoidal_rule_1,     ///< GeneralizedTrapezoidal(1/2)
   _backward_euler,         ///< GeneralizedTrapezoidal(1)
   _central_difference,     ///< NewmarkBeta(0, 1/2)
   _fox_goodwin,            ///< NewmarkBeta(1/6, 1/2)
   _trapezoidal_rule_2,     ///< NewmarkBeta(1/2, 1/2)
   _linear_acceleration,    ///< NewmarkBeta(1/3, 1/2)
   _newmark_beta,           ///< generic NewmarkBeta with user defined
                            /// alpha and beta
   _generalized_trapezoidal ///< generic GeneralizedTrapezoidal with user
                            ///  defined alpha
 };
 #endif
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_SOLVE_CONVERGENCE_CRITERIA       \
   (residual)                                    \
   (solution)                                    \
   (residual_mass_wgh)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(SolveConvergenceCriteria,
                           AKANTU_SOLVE_CONVERGENCE_CRITERIA)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(SolveConvergenceCriteria,
                                 AKANTU_SOLVE_CONVERGENCE_CRITERIA)
 AKANTU_CLASS_ENUM_INPUT_STREAM(SolveConvergenceCriteria,
                                AKANTU_SOLVE_CONVERGENCE_CRITERIA)
 #else
 /// enum SolveConvergenceCriteria different convergence criteria
 enum class SolveConvergenceCriteria {
   _residual,         ///< Use residual to test the convergence
   _solution,         ///< Use solution to test the convergence
   _residual_mass_wgh ///< Use residual weighted by inv. nodal mass to
                      ///< testb
 };
 #endif
 
 /// enum CohesiveMethod type of insertion of cohesive elements
 enum CohesiveMethod { _intrinsic, _extrinsic };
 
 /// @enum MatrixType type of sparse matrix used
 enum MatrixType { _unsymmetric, _symmetric, _mt_not_defined };
 
 /// @enum Type of contact detection
 enum DetectionType { _explicit, _implicit };
 
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_CONTACT_STATE                      \
   (no_contact)                                    \
   (stick)                                         \
   (slip)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(ContactState,
                           AKANTU_CONTACT_STATE)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(ContactState,
                                 AKANTU_CONTACT_STATE)
 AKANTU_CLASS_ENUM_INPUT_STREAM(ContactState,
                                AKANTU_CONTACT_STATE)
 #else
 /// @enum no contact or stick or slip state
 enum class ContactState {
   _no_contact = 0,
   _stick = 1,
   _slip = 2,
 };
 #endif
 
 /* -------------------------------------------------------------------------- */
 /* Ghosts handling                                                            */
 /* -------------------------------------------------------------------------- */
 /// @enum CommunicatorType type of communication method to use
 enum CommunicatorType { _communicator_mpi, _communicator_dummy };
 
 #if !defined(DOXYGEN)
 // clang-format off
 #define AKANTU_SYNCHRONIZATION_TAG              \
   (whatever)                                    \
   (update)                                      \
   (ask_nodes)                                   \
   (size)                                        \
   (smm_mass)                                    \
   (smm_for_gradu)                               \
   (smm_boundary)                                \
   (smm_uv)                                      \
   (smm_res)                                     \
   (smm_init_mat)                                \
   (smm_stress)                                  \
   (smmc_facets)                                 \
   (smmc_facets_conn)                            \
   (smmc_facets_stress)                          \
   (smmc_damage)                                 \
   (giu_global_conn)                             \
   (ce_groups)                                   \
   (ce_insertion_order)                          \
   (gm_clusters)                                 \
   (htm_temperature)                             \
   (htm_gradient_temperature)                    \
   (htm_phi)                                     \
   (htm_gradient_phi)                            \
   (pfm_damage)                                  \
   (pfm_driving)                                 \
   (pfm_history)                                 \
   (pfm_energy)                                  \
   (csp_damage)                                  \
   (csp_strain)                                  \
   (mnl_for_average)                             \
   (mnl_weight)                                  \
   (nh_criterion)                                \
   (test)                                        \
   (user_1)                                      \
   (user_2)                                      \
   (material_id)                                 \
   (for_dump)                                    \
   (cf_nodal)                                    \
   (cf_incr)                                     \
   (solver_solution)
 // clang-format on
 AKANTU_CLASS_ENUM_DECLARE(SynchronizationTag, AKANTU_SYNCHRONIZATION_TAG)
 AKANTU_CLASS_ENUM_OUTPUT_STREAM(SynchronizationTag, AKANTU_SYNCHRONIZATION_TAG)
 #else
 /// @enum SynchronizationTag type of synchronizations
 enum class SynchronizationTag {
   //--- Generic tags ---
   _whatever,
   _update,
   _ask_nodes,
   _size,
 
   //--- SolidMechanicsModel tags ---
   _smm_mass,      ///< synchronization of the SolidMechanicsModel.mass
   _smm_for_gradu, ///< synchronization of the
                   /// SolidMechanicsModel.displacement
   _smm_boundary,  ///< synchronization of the boundary, forces, velocities
                   /// and displacement
   _smm_uv,        ///< synchronization of the nodal velocities and displacement
   _smm_res,       ///< synchronization of the nodal residual
   _smm_init_mat,  ///< synchronization of the data to initialize materials
   _smm_stress,    ///< synchronization of the stresses to compute the
                   ///< internal
                   /// forces
   _smmc_facets,   ///< synchronization of facet data to setup facet synch
   _smmc_facets_conn,   ///< synchronization of facet global connectivity
   _smmc_facets_stress, ///< synchronization of facets' stress to setup
                        ///< facet
                        /// synch
   _smmc_damage,        ///< synchronization of damage
 
   // --- GlobalIdsUpdater tags ---
   _giu_global_conn, ///< synchronization of global connectivities
 
   // --- CohesiveElementInserter tags ---
   _ce_groups, ///< synchronization of cohesive element insertion depending
               /// on facet groups
   _ce_insertion_order, ///< synchronization of the order of insertion of
                        /// cohesive elements
 
   // --- GroupManager tags ---
   _gm_clusters, ///< synchronization of clusters
 
   // --- HeatTransfer tags ---
   _htm_temperature,          ///< synchronization of the nodal temperature
   _htm_gradient_temperature, ///< synchronization of the element gradient
                              /// temperature
 
   // --- PhaseFieldModel tags ---
   _pfm_damage,  ///< synchronization of the nodal damage
   _pfm_driving, ///< synchronization of the driving forces to
                 /// compute the internal
   _pfm_history, ///< synchronization of the damage history to
                 ///  compute the internal
   _pfm_energy,  ///< synchronization of the damage energy
                 /// density to compute the internal
 
   // --- CouplerSolidPhaseField tags ---
   _csp_damage, ///< synchronization of the damage from phase
                /// model to solid model
   _csp_strain, ///< synchronization of the strain from solid
                /// model to phase model
 
   // --- LevelSet tags ---
   _htm_phi,          ///< synchronization of the nodal level set value phi
   _htm_gradient_phi, ///< synchronization of the element gradient phi
 
   //--- Material non local ---
   _mnl_for_average, ///< synchronization of data to average in non local
                     /// material
   _mnl_weight,      ///< synchronization of data for the weight computations
 
   // --- NeighborhoodSynchronization tags ---
   _nh_criterion,
 
   // --- General tags ---
   _test,        ///< Test tag
   _user_1,      ///< tag for user simulations
   _user_2,      ///< tag for user simulations
   _material_id, ///< synchronization of the material ids
   _for_dump,    ///< everything that needs to be synch before dump
 
   // --- Contact & Friction ---
   _cf_nodal, ///< synchronization of disp, velo, and current position
   _cf_incr,  ///< synchronization of increment
 
   // --- Solver tags ---
   _solver_solution ///< synchronization of the solution obained with the
                    /// PETSc solver
 };
 #endif
 
 /// @enum GhostType type of ghost
 enum GhostType {
   _not_ghost = 0,
   _ghost = 1,
   _casper // not used but a real cute ghost
 };
 
 /// Define the flag that can be set to a node
 enum class NodeFlag : std::uint8_t {
   _normal = 0x00,
   _distributed = 0x01,
   _master = 0x03,
   _slave = 0x05,
   _pure_ghost = 0x09,
   _shared_mask = 0x0F,
   _periodic = 0x10,
   _periodic_master = 0x30,
   _periodic_slave = 0x50,
   _periodic_mask = 0xF0,
   _local_master_mask = 0xCC, // ~(_master & _periodic_mask)
 };
 
 inline NodeFlag operator&(const NodeFlag & a, const NodeFlag & b) {
   using under = std::underlying_type_t<NodeFlag>;
   return NodeFlag(under(a) & under(b));
 }
 
 inline NodeFlag operator|(const NodeFlag & a, const NodeFlag & b) {
   using under = std::underlying_type_t<NodeFlag>;
   return NodeFlag(under(a) | under(b));
 }
 
 inline NodeFlag & operator|=(NodeFlag & a, const NodeFlag & b) {
   a = a | b;
   return a;
 }
 
 inline NodeFlag & operator&=(NodeFlag & a, const NodeFlag & b) {
   a = a & b;
   return a;
 }
 
 inline NodeFlag operator~(const NodeFlag & a) {
   using under = std::underlying_type_t<NodeFlag>;
   return NodeFlag(~under(a));
 }
 
 std::ostream & operator<<(std::ostream & stream, NodeFlag flag);
 
 } // namespace akantu
 
 AKANTU_ENUM_HASH(GhostType)
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 struct GhostType_def {
   using type = GhostType;
   static const type _begin_ = _not_ghost;
   static const type _end_ = _casper;
 };
 
 using ghost_type_t = safe_enum<GhostType_def>;
 namespace {
   constexpr ghost_type_t ghost_types{_casper};
 }
 
 /// standard output stream operator for GhostType
 // inline std::ostream & operator<<(std::ostream & stream, GhostType type);
 
 /* -------------------------------------------------------------------------- */
 /* Global defines                                                             */
 /* -------------------------------------------------------------------------- */
 #define AKANTU_MIN_ALLOCATION 2000
 
 #define AKANTU_INDENT ' '
 #define AKANTU_INCLUDE_INLINE_IMPL
 
 /* -------------------------------------------------------------------------- */
 #define AKANTU_SET_MACRO(name, variable, type)                                 \
   inline void set##name(type variable) { this->variable = variable; }
 
 #define AKANTU_GET_MACRO(name, variable, type)                                 \
   inline type get##name() const { return variable; }
 
+#define AKANTU_GET_MACRO_AUTO(name, variable) \
+  inline decltype(auto) get##name() const { return (variable); }
+
 #define AKANTU_GET_MACRO_NOT_CONST(name, variable, type)                       \
   inline type get##name() { return variable; }
 
 #define AKANTU_GET_MACRO_DEREF_PTR(name, ptr)                                  \
   inline const auto & get##name() const {                                      \
     if (not(ptr)) {                                                            \
       AKANTU_EXCEPTION("The member " << #ptr << " is not initialized");        \
     }                                                                          \
     return (*(ptr));                                                           \
   }
 
 #define AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(name, ptr)                        \
   inline auto & get##name() {                                                  \
     if (not(ptr)) {                                                            \
       AKANTU_EXCEPTION("The member " << #ptr << " is not initialized");        \
     }                                                                          \
     return (*(ptr));                                                           \
   }
 
 #define AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, support, con)   \
   inline con Array<type> & get##name(const support & el_type,                  \
                                      GhostType ghost_type = _not_ghost)        \
       con { /* NOLINT */                                                       \
     return variable(el_type, ghost_type);                                      \
   } // NOLINT
 
 #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE(name, variable, type)                 \
   AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType, )
 #define AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(name, variable, type)           \
   AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, ElementType, const)
 
 #define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE(name, variable, type)               \
   AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType, )
 #define AKANTU_GET_MACRO_BY_GEOMETRIE_TYPE_CONST(name, variable, type)         \
   AKANTU_GET_MACRO_BY_SUPPORT_TYPE(name, variable, type, GeometricalType, const)
 
 /* -------------------------------------------------------------------------- */
 /// initialize the static part of akantu
 void initialize(int & argc, char **& argv);
 /// initialize the static part of akantu and read the global input_file
 void initialize(const std::string & input_file, int & argc, char **& argv);
 /* -------------------------------------------------------------------------- */
 /// finilize correctly akantu and clean the memory
 void finalize();
 /* -------------------------------------------------------------------------- */
 /// Read an new input file
 void readInputFile(const std::string & input_file);
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 /* string manipulation */
 /* -------------------------------------------------------------------------- */
 inline std::string to_lower(const std::string & str);
 /* -------------------------------------------------------------------------- */
 inline std::string trim(const std::string & to_trim);
 inline std::string trim(const std::string & to_trim, char c);
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 /// give a string representation of the a human readable size in bit
 template <typename T> std::string printMemorySize(UInt size);
 /* -------------------------------------------------------------------------- */
 
 struct TensorTrait {};
 struct TensorProxyTrait {};
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* Type traits                                                                */
 /* -------------------------------------------------------------------------- */
 namespace aka {
 
 /* ------------------------------------------------------------------------ */
 template <typename T> using is_scalar = std::is_arithmetic<T>;
 /* ------------------------------------------------------------------------ */
 template <typename R, typename T,
           std::enable_if_t<std::is_reference<T>::value> * = nullptr>
 bool is_of_type(T && t) {
   return (
       dynamic_cast<std::add_pointer_t<
           std::conditional_t<std::is_const<std::remove_reference_t<T>>::value,
                              std::add_const_t<R>, R>>>(&t) != nullptr);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename R, typename T> bool is_of_type(std::unique_ptr<T> & t) {
   return (
       dynamic_cast<std::add_pointer_t<
           std::conditional_t<std::is_const<T>::value, std::add_const_t<R>, R>>>(
           t.get()) != nullptr);
 }
 
 /* ------------------------------------------------------------------------ */
 template <typename R, typename T,
           std::enable_if_t<std::is_reference<T>::value> * = nullptr>
 decltype(auto) as_type(T && t) {
   static_assert(
       disjunction<
           std::is_base_of<std::decay_t<T>, std::decay_t<R>>, // down-cast
           std::is_base_of<std::decay_t<R>, std::decay_t<T>>  // up-cast
           >::value,
       "Type T and R are not valid for a as_type conversion");
   return dynamic_cast<std::add_lvalue_reference_t<
       std::conditional_t<std::is_const<std::remove_reference_t<T>>::value,
                          std::add_const_t<R>, R>>>(t);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename R, typename T,
           std::enable_if_t<std::is_pointer<T>::value> * = nullptr>
 decltype(auto) as_type(T && t) {
   return &as_type<R>(*t);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename R, typename T>
 decltype(auto) as_type(const std::shared_ptr<T> & t) {
   return std::dynamic_pointer_cast<R>(t);
 }
 
 } // namespace aka
 
 #include "aka_common_inline_impl.hh"
 
 #include "aka_fwd.hh"
 
 namespace akantu {
 /// get access to the internal argument parser
 cppargparse::ArgumentParser & getStaticArgumentParser();
 
 /// get access to the internal input file parser
 Parser & getStaticParser();
 
 /// get access to the user part of the internal input file parser
 const ParserSection & getUserParser();
 
 #define AKANTU_CURRENT_FUNCTION                                                \
   (std::string(__func__) + "():" + std::to_string(__LINE__))
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #if AKANTU_INTEGER_SIZE == 4
 #define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b9
 #elif AKANTU_INTEGER_SIZE == 8
 #define AKANTU_HASH_COMBINE_MAGIC_NUMBER 0x9e3779b97f4a7c13LL
 #endif
 
 namespace std {
 /**
  * Hashing function for pairs based on hash_combine from boost The magic
  * number is coming from the golden number @f[\phi = \frac{1 + \sqrt5}{2}@f]
  * @f[\frac{2^32}{\phi} = 0x9e3779b9@f]
  * http://stackoverflow.com/questions/4948780/magic-number-in-boosthash-combine
  * http://burtleburtle.net/bob/hash/doobs.html
  */
 template <typename a, typename b> struct hash<std::pair<a, b>> {
   hash() = default;
   size_t operator()(const std::pair<a, b> & p) const {
     size_t seed = ah(p.first);
     return bh(p.second) + AKANTU_HASH_COMBINE_MAGIC_NUMBER + (seed << 6) +
            (seed >> 2);
   }
 
 private:
   const hash<a> ah{};
   const hash<b> bh{};
 };
 
 } // namespace std
 
 #endif // AKANTU_COMMON_HH_
diff --git a/src/common/aka_extern.cc b/src/common/aka_extern.cc
index cc58e8651..f93dc0580 100644
--- a/src/common/aka_extern.cc
+++ b/src/common/aka_extern.cc
@@ -1,98 +1,98 @@
 /**
  * @file   aka_extern.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
  * @date last modification: Tue Oct 27 2020
  *
  * @brief  initialisation of all global variables
  * to insure the order of creation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_math.hh"
 #include "aka_named_argument.hh"
 #include "aka_random_generator.hh"
 #include "communication_tag.hh"
 #include "cppargparse.hh"
 #include "parser.hh"
 #include "solid_mechanics_model.hh"
 #if defined(AKANTU_COHESIVE_ELEMENT)
 #include "solid_mechanics_model_cohesive.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* error.hpp variables                                                        */
 /* -------------------------------------------------------------------------- */
 namespace debug {
   /** \todo write function to get this
    *   values from the environment or a config file
    */
   /// standard output for debug messages
   std::ostream * _akantu_debug_cout = &std::cerr;
 
   /// standard output for normal messages
   std::ostream & _akantu_cout = std::cout;
 
   /// parallel context used in debug messages
   std::string _parallel_context;
 
   Debugger debugger;
 
 } // namespace debug
 
 /* -------------------------------------------------------------------------- */
 /// Paser for commandline arguments
 ::cppargparse::ArgumentParser static_argparser;
 
 /// Parser containing the information parsed by the input file given to initFull
 Parser static_parser;
 
 bool Parser::permissive_parser = false;
 
 /* -------------------------------------------------------------------------- */
 Real Math::tolerance = 1e2 * std::numeric_limits<Real>::epsilon();
 
 /* -------------------------------------------------------------------------- */
-const UInt _all_dimensions [[gnu::unused]] = UInt(-1);
+const Int _all_dimensions [[gnu::unused]] = Int(-1);
 
 /* -------------------------------------------------------------------------- */
-const Array<UInt> empty_filter(0, 1, "empty_filter");
+const Array<Int> empty_filter(0, 1, "empty_filter");
 
 /* -------------------------------------------------------------------------- */
 template <> long int RandomGenerator<UInt>::_seed = 5489U;
 template <> std::default_random_engine RandomGenerator<UInt>::generator(5489U);
 /* -------------------------------------------------------------------------- */
 int Tag::max_tag = 0;
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/common/aka_fwd.hh b/src/common/aka_fwd.hh
index 8d1f83a5f..d0bab7c76 100644
--- a/src/common/aka_fwd.hh
+++ b/src/common/aka_fwd.hh
@@ -1,69 +1,69 @@
 /**
  * @file   aka_fwd.hh
  *
  * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Apr 13 2012
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  File containing forward declarations in akantu.
  * This file helps if circular #include would be needed because two classes
  * refer both to each other. This file usually does not need any modification.
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_FWD_HH_
 #define AKANTU_FWD_HH_
 
 namespace cppargparse {
 class ArgumentParser;
 }
 
 namespace akantu {
 // forward declaration
 template <int dim, class model_type> struct ContactData;
 
 template <typename T, bool is_scal = is_scalar<T>::value> class Array;
 template <typename T, typename SupportType = ElementType>
 class ElementTypeMapArray;
 
 template <class T> class SpatialGrid;
 
 // Model element
 template <class ModelPolicy> class ModelElement;
 
-extern const Array<UInt> empty_filter;
+extern const Array<Int> empty_filter;
 
 class Parser;
 class ParserSection;
 
 extern Parser static_parser; // NOLINT
 
 extern cppargparse::ArgumentParser static_argparser; // NOLINT
 
 class Mesh;
 class SparseMatrix;
 } // namespace akantu
 
 #endif /* AKANTU_FWD_HH_ */
diff --git a/src/common/aka_math.cc b/src/common/aka_math.cc
index 1448ae93b..41051c486 100644
--- a/src/common/aka_math.cc
+++ b/src/common/aka_math.cc
@@ -1,271 +1,324 @@
 /**
  * @file   aka_math.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
  * @author Peter Spijker <peter.spijker@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  Implementation of the math toolbox
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_math.hh"
 #include "aka_array.hh"
 #include "aka_iterators.hh"
+#include "aka_math.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace Math {
-  /* --------------------------------------------------------------------------
-   */
+  /* ------------------------------------------------------------------------ */
   void matrix_vector(UInt m, UInt n, const Array<Real> & A,
                      const Array<Real> & x, Array<Real> & y, Real alpha) {
     AKANTU_DEBUG_IN();
 
     AKANTU_DEBUG_ASSERT(A.size() == x.size(),
                         "The vector A(" << A.getID() << ") and the vector x("
                                         << x.getID()
                                         << ") must have the same size");
 
     AKANTU_DEBUG_ASSERT(
         A.getNbComponent() == m * n,
         "The vector A(" << A.getID() << ") has the good number of component.");
 
     AKANTU_DEBUG_ASSERT(x.getNbComponent() == n,
                         "The vector x("
                             << x.getID()
                             << ") do not the good number of component.");
 
     AKANTU_DEBUG_ASSERT(y.getNbComponent() == n,
                         "The vector y("
                             << y.getID()
                             << ") do not the good number of component.");
 
     UInt nb_element = A.size();
     UInt offset_A = A.getNbComponent();
     UInt offset_x = x.getNbComponent();
 
     y.resize(nb_element);
 
     Real * A_val = A.data();
     Real * x_val = x.data();
     Real * y_val = y.data();
 
     for (UInt el = 0; el < nb_element; ++el) {
       matrix_vector(m, n, A_val, x_val, y_val, alpha);
 
       A_val += offset_A;
       x_val += offset_x;
       y_val += offset_x;
     }
 
-    AKANTU_DEBUG_OUT();
-  }
-
-  /* --------------------------------------------------------------------------
-   */
-  void matrix_matrix(UInt m, UInt n, UInt k, const Array<Real> & A,
-                     const Array<Real> & B, Array<Real> & C, Real alpha) {
-    AKANTU_DEBUG_IN();
-
-    AKANTU_DEBUG_ASSERT(A.size() == B.size(),
-                        "The vector A(" << A.getID() << ") and the vector B("
-                                        << B.getID()
-                                        << ") must have the same size");
-
-    AKANTU_DEBUG_ASSERT(
-        A.getNbComponent() == m * k,
-        "The vector A(" << A.getID() << ") has the good number of component.");
-
-    AKANTU_DEBUG_ASSERT(B.getNbComponent() == k * n,
-                        "The vector B("
-                            << B.getID()
-                            << ") do not the good number of component.");
-
-    AKANTU_DEBUG_ASSERT(C.getNbComponent() == m * n,
-                        "The vector C("
-                            << C.getID()
-                            << ") do not the good number of component.");
-
-    UInt nb_element = A.size();
-    UInt offset_A = A.getNbComponent();
-    UInt offset_B = B.getNbComponent();
-    UInt offset_C = C.getNbComponent();
-
-    C.resize(nb_element);
-
-    Real * A_val = A.data();
-    Real * B_val = B.data();
-    Real * C_val = C.data();
-
-    for (UInt el = 0; el < nb_element; ++el) {
-      matrix_matrix(m, n, k, A_val, B_val, C_val, alpha);
-
-      A_val += offset_A;
-      B_val += offset_B;
-      C_val += offset_C;
-    }
-
-    AKANTU_DEBUG_OUT();
-  }
-
-  /* --------------------------------------------------------------------------
-   */
-  void matrix_matrixt(UInt m, UInt n, UInt k, const Array<Real> & A,
-                      const Array<Real> & B, Array<Real> & C, Real alpha) {
-    AKANTU_DEBUG_IN();
-
-    AKANTU_DEBUG_ASSERT(A.size() == B.size(),
-                        "The vector A(" << A.getID() << ") and the vector B("
-                                        << B.getID()
-                                        << ") must have the same size");
-
-    AKANTU_DEBUG_ASSERT(
-        A.getNbComponent() == m * k,
-        "The vector A(" << A.getID() << ") has the good number of component.");
-
-    AKANTU_DEBUG_ASSERT(B.getNbComponent() == k * n,
-                        "The vector B("
-                            << B.getID()
-                            << ") do not the good number of component.");
-
-    AKANTU_DEBUG_ASSERT(C.getNbComponent() == m * n,
-                        "The vector C("
-                            << C.getID()
-                            << ") do not the good number of component.");
-
-    UInt nb_element = A.size();
-    UInt offset_A = A.getNbComponent();
-    UInt offset_B = B.getNbComponent();
-    UInt offset_C = C.getNbComponent();
-
-    C.resize(nb_element);
-
-    Real * A_val = A.data();
-    Real * B_val = B.data();
-    Real * C_val = C.data();
-
-    for (UInt el = 0; el < nb_element; ++el) {
-      matrix_matrixt(m, n, k, A_val, B_val, C_val, alpha);
-
-      A_val += offset_A;
-      B_val += offset_B;
-      C_val += offset_C;
-    }
-
-    AKANTU_DEBUG_OUT();
-  }
-
-  /* --------------------------------------------------------------------------
-   */
-  void compute_tangents(const Array<Real> & normals, Array<Real> & tangents) {
-    AKANTU_DEBUG_IN();
+    /* --------------------------------------------------------------------------
+     */
+    // void Math::matrix_vector(UInt m, UInt n, const Array<Real> & A,
+    //                          const Array<Real> & x, Array<Real> & y, Real
+    //                          alpha) {
+    //   AKANTU_DEBUG_IN();
+
+    //   AKANTU_DEBUG_ASSERT(A.size() == x.size(),
+    //                       "The vector A(" << A.getID() << ") and the vector
+    //                       x("
+    //                                       << x.getID()
+    //                                       << ") must have the same size");
+
+    //   AKANTU_DEBUG_ASSERT(A.getNbComponent() == m * n,
+    //                       "The vector A(" << A.getID()
+    //                                       << ") has the good number of
+    //                                       component.");
+
+    //   AKANTU_DEBUG_ASSERT(
+    //       x.getNbComponent() == n,
+    //       "The vector x(" << x.getID() << ") do not the good number of
+    //       component.");
+
+    //   AKANTU_DEBUG_ASSERT(
+    //       y.getNbComponent() == n,
+    //       "The vector y(" << y.getID() << ") do not the good number of
+    //       component.");
+
+    //   UInt nb_element = A.size();
+    //   UInt offset_A = A.getNbComponent();
+    //   UInt offset_x = x.getNbComponent();
+
+    //   y.resize(nb_element);
+
+    //   Real * A_val = A.data();
+    //   Real * x_val = x.data();
+    //   Real * y_val = y.data();
+
+    //   for (UInt el = 0; el < nb_element; ++el) {
+    //     matrix_vector(m, n, A_val, x_val, y_val, alpha);
+
+    //     A_val += offset_A;
+    //     x_val += offset_x;
+    //     y_val += offset_x;
+    //   }
+
+    //   AKANTU_DEBUG_OUT();
+    // }
+
+    // /*
+    // --------------------------------------------------------------------------
+    // */ void Math::matrix_matrix(UInt m, UInt n, UInt k, const Array<Real> &
+    // A,
+    //                          const Array<Real> & B, Array<Real> & C, Real
+    //                          alpha) {
+    //   AKANTU_DEBUG_IN();
+
+    //   AKANTU_DEBUG_ASSERT(A.size() == B.size(),
+    //                       "The vector A(" << A.getID() << ") and the vector
+    //                       B("
+    //                                       << B.getID()
+    //                                       << ") must have the same size");
+
+    //   AKANTU_DEBUG_ASSERT(A.getNbComponent() == m * k,
+    //                       "The vector A(" << A.getID()
+    //                                       << ") has the good number of
+    //                                       component.");
+
+    //   AKANTU_DEBUG_ASSERT(
+    //       B.getNbComponent() == k * n,
+    //       "The vector B(" << B.getID() << ") do not the good number of
+    //       component.");
+
+    //   AKANTU_DEBUG_ASSERT(
+    //       C.getNbComponent() == m * n,
+    //       "The vector C(" << C.getID() << ") do not the good number of
+    //       component.");
+
+    //   UInt nb_element = A.size();
+    //   UInt offset_A = A.getNbComponent();
+    //   UInt offset_B = B.getNbComponent();
+    //   UInt offset_C = C.getNbComponent();
+
+    //   C.resize(nb_element);
+
+    //   Real * A_val = A.data();
+    //   Real * B_val = B.data();
+    //   Real * C_val = C.data();
+
+    //   for (UInt el = 0; el < nb_element; ++el) {
+    //     matrix_matrix(m, n, k, A_val, B_val, C_val, alpha);
+
+    //     A_val += offset_A;
+    //     B_val += offset_B;
+    //     C_val += offset_C;
+    //   }
+
+    //   AKANTU_DEBUG_OUT();
+    // }
+
+    // /*
+    // --------------------------------------------------------------------------
+    // */ void Math::matrix_matrixt(UInt m, UInt n, UInt k, const Array<Real> &
+    // A,
+    //                           const Array<Real> & B, Array<Real> & C, Real
+    //                           alpha) {
+    //   AKANTU_DEBUG_IN();
+
+    //   AKANTU_DEBUG_ASSERT(A.size() == B.size(),
+    //                       "The vector A(" << A.getID() << ") and the vector
+    //                       B("
+    //                                       << B.getID()
+    //                                       << ") must have the same size");
+
+    //   AKANTU_DEBUG_ASSERT(A.getNbComponent() == m * k,
+    //                       "The vector A(" << A.getID()
+    //                                       << ") has the good number of
+    //                                       component.");
+
+    //   AKANTU_DEBUG_ASSERT(
+    //       B.getNbComponent() == k * n,
+    //       "The vector B(" << B.getID() << ") do not the good number of
+    //       component.");
+
+    //   AKANTU_DEBUG_ASSERT(
+    //       C.getNbComponent() == m * n,
+    //       "The vector C(" << C.getID() << ") do not the good number of
+    //       component.");
+
+    //   UInt nb_element = A.size();
+    //   UInt offset_A = A.getNbComponent();
+    //   UInt offset_B = B.getNbComponent();
+    //   UInt offset_C = C.getNbComponent();
+
+    //   C.resize(nb_element);
+
+    //   Real * A_val = A.data();
+    //   Real * B_val = B.data();
+    //   Real * C_val = C.data();
+
+    //   for (UInt el = 0; el < nb_element; ++el) {
+    //     matrix_matrixt(m, n, k, A_val, B_val, C_val, alpha);
+
+    //     A_val += offset_A;
+    //     B_val += offset_B;
+    //     C_val += offset_C;
+    //   }
+
+    //   AKANTU_DEBUG_OUT();
+    // }
+
+    /* -------------------------------------------------------------------------
+     */
+    void Math::compute_tangents(const Array<Real> & normals,
+                                Array<Real> & tangents) {
+      AKANTU_DEBUG_IN();
+
+      if (normals.empty()) {
+        return;
+      }
 
-    if (normals.empty()) {
-      return;
-    }
+      auto spatial_dimension = normals.getNbComponent();
+      auto tangent_components = spatial_dimension * (spatial_dimension - 1);
 
-    auto spatial_dimension = normals.getNbComponent();
-    auto tangent_components = spatial_dimension * (spatial_dimension - 1);
+      if (tangent_components == 0) {
+        return;
+      }
 
-    if (tangent_components == 0) {
-      return;
-    }
+      AKANTU_DEBUG_ASSERT(
+          tangent_components == tangents.getNbComponent(),
+          "Cannot compute the tangents, the storage array for tangents"
+              << " does not have the good amount of components.");
 
-    AKANTU_DEBUG_ASSERT(
-        tangent_components == tangents.getNbComponent(),
-        "Cannot compute the tangents, the storage array for tangents"
-            << " does not have the good amount of components.");
-
-    auto nb_normals = normals.size();
-    tangents.resize(nb_normals);
-    tangents.zero();
-
-    /// compute first tangent
-    for (auto && data : zip(make_view(normals, spatial_dimension),
-                            make_view(tangents, tangent_components))) {
-      const auto & normal = std::get<0>(data);
-      auto & tangent = std::get<1>(data);
-
-      if (are_float_equal(norm2(normal.data()), 0.)) {
-        tangent(0) = 1.;
-      } else {
-        normal2(normal.data(), tangent.data());
-      }
-    }
+      auto nb_normals = normals.size();
+      tangents.resize(nb_normals);
+      tangents.zero();
 
-    /// compute second tangent (3D case)
-    if (spatial_dimension == 3) {
+      /// compute first tangent
       for (auto && data : zip(make_view(normals, spatial_dimension),
                               make_view(tangents, tangent_components))) {
         const auto & normal = std::get<0>(data);
         auto & tangent = std::get<1>(data);
 
-        normal3(normal.data(), tangent.data(),
-                tangent.data() + spatial_dimension);
+        if (are_float_equal(norm2(normal.data()), 0.)) {
+          tangent(0) = 1.;
+        } else {
+          normal2(normal.data(), tangent.data());
+        }
       }
-    }
 
-    AKANTU_DEBUG_OUT();
-  } // namespace akantu
+      /// compute second tangent (3D case)
+      if (spatial_dimension == 3) {
+        for (auto && data : zip(make_view(normals, spatial_dimension),
+                                make_view(tangents, tangent_components))) {
+          const auto & normal = std::get<0>(data);
+          auto & tangent = std::get<1>(data);
 
-  /* --------------------------------------------------------------------------
-   */
-  Real reduce(Array<Real> & array) {
-    UInt nb_values = array.size();
-    if (nb_values == 0) {
-      return 0.;
+          normal3(normal.data(), tangent.data(),
+                  tangent.data() + spatial_dimension);
+        }
+      }
+
+      AKANTU_DEBUG_OUT();
     }
 
-    UInt nb_values_to_sum = nb_values >> 1;
+    /* ------------------------------------------------------------------------
+     */
+    Real reduce(Array<Real> & array) {
+      UInt nb_values = array.size();
+      if (nb_values == 0) {
+        return 0.;
+      }
 
-    std::sort(array.begin(), array.end());
+      UInt nb_values_to_sum = nb_values >> 1;
 
-    // as long as the half is not empty
-    while (nb_values_to_sum != 0U) {
-      UInt remaining = (nb_values - 2 * nb_values_to_sum);
-      if (remaining != 0U) {
-        array(nb_values - 2) += array(nb_values - 1);
-      }
+      std::sort(array.begin(), array.end());
 
-      // sum to consecutive values and store the sum in the first half
-      for (UInt i = 0; i < nb_values_to_sum; ++i) {
-        array(i) = array(2 * i) + array(2 * i + 1);
-      }
+      // as long as the half is not empty
+      while (nb_values_to_sum != 0U) {
+        UInt remaining = (nb_values - 2 * nb_values_to_sum);
+        if (remaining != 0U) {
+          array(nb_values - 2) += array(nb_values - 1);
+        }
 
-      nb_values = nb_values_to_sum;
-      nb_values_to_sum >>= 1;
-    }
+        // sum to consecutive values and store the sum in the first half
+        for (UInt i = 0; i < nb_values_to_sum; ++i) {
+          array(i) = array(2 * i) + array(2 * i + 1);
+        }
 
-    return array(0);
-  }
+        nb_values = nb_values_to_sum;
+        nb_values_to_sum >>= 1;
+      }
 
-} // namespace Math
+      return array(0);
+    }
+  } // namespace Math
 } // namespace akantu
diff --git a/src/common/aka_math.hh b/src/common/aka_math.hh
index 62eb756f4..8da259445 100644
--- a/src/common/aka_math.hh
+++ b/src/common/aka_math.hh
@@ -1,287 +1,294 @@
 /**
  * @file   aka_math.hh
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
  * @author Peter Spijker <peter.spijker@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Tue Feb 09 2021
  *
  * @brief  mathematical operations
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 /* -------------------------------------------------------------------------- */
 #include <utility>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_AKA_MATH_H_
 #define AKANTU_AKA_MATH_H_
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 namespace Math {
   /// tolerance for functions that need one
   extern Real tolerance; // NOLINT
 
   /* ------------------------------------------------------------------------ */
   /* Matrix algebra                                                           */
   /* ------------------------------------------------------------------------ */
-  /// @f$ y = A*x @f$
-  void matrix_vector(UInt m, UInt n, const Array<Real> & A,
-                     const Array<Real> & x, Array<Real> & y, Real alpha = 1.);
+  // /// @f$ y = A*x @f$
+  // static void matrix_vector(UInt m, UInt n, const Array<Real, true> & A,
+  //                           const Array<Real, true> & x, Array<Real, true> & y,
+  //                           Real alpha = 1.);
 
-  /// @f$ y = A*x @f$
-  inline void matrix_vector(UInt m, UInt n, Real * A, Real * x, Real * y,
-                            Real alpha = 1.);
+  // /// @f$ y = A*x @f$
+  // static inline void matrix_vector(UInt m, UInt n, Real * A, Real * x, Real * y,
+  //                                  Real alpha = 1.);
 
-  /// @f$ y = A^t*x @f$
-  inline void matrixt_vector(UInt m, UInt n, Real * A, Real * x, Real * y,
-                             Real alpha = 1.);
+  // /// @f$ y = A^t*x @f$
+  // static inline void matrixt_vector(UInt m, UInt n, Real * A, Real * x,
+  //                                   Real * y, Real alpha = 1.);
 
-  /// @f$ C = A*B @f$
-  void matrix_matrix(UInt m, UInt n, UInt k, const Array<Real> & A,
-                     const Array<Real> & B, Array<Real> & C, Real alpha = 1.);
+  // /// @f$ C = A*B @f$
+  // static void matrix_matrix(UInt m, UInt n, UInt k, const Array<Real, true> & A,
+  //                           const Array<Real, true> & B, Array<Real, true> & C,
+  //                           Real alpha = 1.);
 
-  /// @f$ C = A*B^t @f$
-  void matrix_matrixt(UInt m, UInt n, UInt k, const Array<Real> & A,
-                      const Array<Real> & B, Array<Real> & C, Real alpha = 1.);
+  // /// @f$ C = A*B^t @f$
+  // static void matrix_matrixt(UInt m, UInt n, UInt k,
+  //                            const Array<Real, true> & A,
+  //                            const Array<Real, true> & B, Array<Real, true> & C,
+  //                            Real alpha = 1.);
 
-  /// @f$ C = A*B @f$
-  inline void matrix_matrix(UInt m, UInt n, UInt k, Real * A, Real * B,
-                            Real * C, Real alpha = 1.);
+  // /// @f$ C = A*B @f$
+  // static inline void matrix_matrix(UInt m, UInt n, UInt k, Real * A, Real * B,
+  //                                  Real * C, Real alpha = 1.);
 
-  /// @f$ C = A^t*B @f$
-  inline void matrixt_matrix(UInt m, UInt n, UInt k, Real * A, Real * B,
-                             Real * C, Real alpha = 1.);
+  // /// @f$ C = A^t*B @f$
+  // static inline void matrixt_matrix(UInt m, UInt n, UInt k, Real * A, Real * B,
+  //                                   Real * C, Real alpha = 1.);
 
-  /// @f$ C = A*B^t @f$
-  inline void matrix_matrixt(UInt m, UInt n, UInt k, Real * A, Real * B,
-                             Real * C, Real alpha = 1.);
+  // /// @f$ C = A*B^t @f$
+  // static inline void matrix_matrixt(UInt m, UInt n, UInt k, Real * A, Real * B,
+  //                                   Real * C, Real alpha = 1.);
 
-  /// @f$ C = A^t*B^t @f$
-  inline void matrixt_matrixt(UInt m, UInt n, UInt k, Real * A, Real * B,
-                              Real * C, Real alpha = 1.);
+  // /// @f$ C = A^t*B^t @f$
+  // static inline void matrixt_matrixt(UInt m, UInt n, UInt k, Real * A, Real * B,
+  //                                    Real * C, Real alpha = 1.);
 
-  template <bool tr_A, bool tr_B>
-  inline void matMul(UInt m, UInt n, UInt k, Real alpha, Real * A, Real * B,
-                     Real beta, Real * C);
+  // template <bool tr_A, bool tr_B>
+  // static inline void matMul(UInt m, UInt n, UInt k, Real alpha, Real * A,
+  //                           Real * B, Real beta, Real * C);
 
-  template <bool tr_A>
-  inline void matVectMul(UInt m, UInt n, Real alpha, Real * A, Real * x,
-                         Real beta, Real * y);
+  // template <bool tr_A>
+  // static inline void matVectMul(UInt m, UInt n, Real alpha, Real * A, Real * x,
+  //                               Real beta, Real * y);
 
-  inline void aXplusY(UInt n, Real alpha, Real * x, Real * y);
+  // static inline void aXplusY(UInt n, Real alpha, Real * x, Real * y);
 
-  inline void matrix33_eigenvalues(Real * A, Real * Adiag);
+  // static inline void matrix33_eigenvalues(Real * A, Real * Adiag);
 
-  inline void matrix22_eigenvalues(Real * A, Real * Adiag);
-  template <UInt dim> inline void eigenvalues(Real * A, Real * d);
+  // static inline void matrix22_eigenvalues(Real * A, Real * Adiag);
+  // template <Int dim> static inline void eigenvalues(Real * A, Real * d);
 
-  /// solve @f$ A x = \Lambda x @f$ and return d and V such as @f$ A V[i:] =
-  /// d[i] V[i:]@f$
-  template <typename T> void matrixEig(UInt n, T * A, T * d, T * V = nullptr);
+  // /// solve @f$ A x = \Lambda x @f$ and return d and V such as @f$ A V[i:] =
+  // /// d[i] V[i:]@f$
+  // template <typename T>
+  // static void matrixEig(UInt n, T * A, T * d, T * V = nullptr);
 
-  /// determinent of a 2x2 matrix
-  Real det2(const Real * mat);
+  // /// determinent of a 2x2 matrix
+  // static inline Real det2(const Real * mat);
   /// determinent of a 3x3 matrix
-  Real det3(const Real * mat);
-  /// determinent of a nxn matrix
-  template <UInt n> Real det(const Real * mat);
-  /// determinent of a nxn matrix
-  template <typename T> T det(UInt n, const T * A);
-
-  /// inverse a nxn matrix
-  template <UInt n> inline void inv(const Real * A, Real * inv);
-  /// inverse a nxn matrix
-  template <typename T> inline void inv(UInt n, const T * A, T * inv);
-  /// inverse a 3x3 matrix
-  inline void inv3(const Real * mat, Real * inv);
-  /// inverse a 2x2 matrix
-  inline void inv2(const Real * mat, Real * inv);
+  static inline Real det3(const Real * mat);
+  
+  // /// determinent of a nxn matrix
+  // template <UInt n> static inline Real det(const Real * mat);
+  // /// determinent of a nxn matrix
+  // template <typename T> static inline T det(UInt n, const T * mat);
+
+  // /// inverse a nxn matrix
+  // template <UInt n> static inline void inv(const Real * mat, Real * inv);
+  // /// inverse a nxn matrix
+  // template <typename T> static inline void inv(UInt n, const T * mat, T * inv);
+  // /// inverse a 3x3 matrix
+  // static inline void inv3(const Real * mat, Real * inv);
+  // /// inverse a 2x2 matrix
+  // static inline void inv2(const Real * mat, Real * inv);
 
   /// solve A x = b using a LU factorization
   template <typename T>
   inline void solve(UInt n, const T * A, T * x, const T * b);
 
-  /// return the double dot product between 2 tensors in 2d
-  inline Real matrixDoubleDot22(Real * A, Real * B);
+  // /// return the double dot product between 2 tensors in 2d
+  // static inline Real matrixDoubleDot22(Real * A, Real * B);
 
-  /// return the double dot product between 2 tensors in 3d
-  inline Real matrixDoubleDot33(Real * A, Real * B);
+  // /// return the double dot product between 2 tensors in 3d
+  // static inline Real matrixDoubleDot33(Real * A, Real * B);
 
-  /// extension of the double dot product to two 2nd order tensor in dimension n
-  inline Real matrixDoubleDot(UInt n, Real * A, Real * B);
+  // /// extension of the double dot product to two 2nd order tensor in dimension n
+  // static inline Real matrixDoubleDot(UInt n, Real * A, Real * B);
 
-  /* ------------------------------------------------------------------------ */
-  /* Array algebra                                                            */
-  /* ------------------------------------------------------------------------ */
+  // /* ------------------------------------------------------------------------ */
+  // /* Array algebra                                                            */
+  // /* ------------------------------------------------------------------------ */
   /// vector cross product
-  inline void vectorProduct3(const Real * v1, const Real * v2, Real * res);
-
+  static inline void vectorProduct3(const Real * v1, const Real * v2,
+                                    Real * res);
+  
   /// normalize a vector
   inline void normalize2(Real * v);
 
   /// normalize a vector
   inline void normalize3(Real * v);
 
   /// return norm of a 2-vector
   inline Real norm2(const Real * v);
 
   /// return norm of a 3-vector
   inline Real norm3(const Real * v);
 
-  /// return norm of a vector
-  inline Real norm(UInt n, const Real * v);
+  // /// return norm of a vector
+  // static inline Real norm(UInt n, const Real * v);
 
-  /// return the dot product between 2 vectors in 2d
-  inline Real vectorDot2(const Real * v1, const Real * v2);
+  // /// return the dot product between 2 vectors in 2d
+  // static inline Real vectorDot2(const Real * v1, const Real * v2);
 
-  /// return the dot product between 2 vectors in 3d
-  inline Real vectorDot3(const Real * v1, const Real * v2);
+  // /// return the dot product between 2 vectors in 3d
+  // static inline Real vectorDot3(const Real * v1, const Real * v2);
 
-  /// return the dot product between 2 vectors
-  inline Real vectorDot(Real * v1, Real * v2, UInt n);
+  // /// return the dot product between 2 vectors
+  // static inline Real vectorDot(Real * v1, Real * v2, UInt n);
 
   /* ------------------------------------------------------------------------ */
   /* Geometry                                                                 */
   /* ------------------------------------------------------------------------ */
   /// compute normal a normal to a vector
   inline void normal2(const Real * vec, Real * normal);
 
   /// compute normal a normal to a vector
   inline void normal3(const Real * vec1, const Real * vec2, Real * normal);
 
   /// compute the tangents to an array of normal vectors
   void compute_tangents(const Array<Real> & normals, Array<Real> & tangents);
 
   /// distance in 2D between x and y
   inline Real distance_2d(const Real * x, const Real * y);
 
   /// distance in 3D between x and y
   inline Real distance_3d(const Real * x, const Real * y);
 
   /// radius of the in-circle of a triangle in 2d space
   static inline Real triangle_inradius(const Vector<Real> & coord1,
                                        const Vector<Real> & coord2,
                                        const Vector<Real> & coord3);
 
   /// radius of the in-circle of a tetrahedron
   inline Real tetrahedron_inradius(const Real * coord1, const Real * coord2,
                                    const Real * coord3, const Real * coord4);
 
   /// volume of a tetrahedron
   inline Real tetrahedron_volume(const Real * coord1, const Real * coord2,
                                  const Real * coord3, const Real * coord4);
 
   /// compute the barycenter of n points
   inline void barycenter(const Real * coord, UInt nb_points,
                          UInt spatial_dimension, Real * barycenter);
 
   /// vector between x and y
   inline void vector_2d(const Real * x, const Real * y, Real * res);
 
   /// vector pointing from x to y in 3 spatial dimension
   inline void vector_3d(const Real * x, const Real * y, Real * res);
 
   /// test if two scalar are equal within a given tolerance
   inline bool are_float_equal(Real x, Real y);
 
   /// test if two vectors are equal within a given tolerance
   inline bool are_vector_equal(UInt n, Real * x, Real * y);
 
 #ifdef isnan
 #error                                                                         \
     "You probably  included <math.h> which  is incompatible with aka_math  please use\
 <cmath> or add a \"#undef isnan\" before akantu includes"
 #endif
   /// test if a real is a NaN
   inline bool isnan(Real x);
 
   /// test if the line x and y intersects each other
   inline bool intersects(Real x_min, Real x_max, Real y_min, Real y_max);
 
   /// test if a is in the range [x_min, x_max]
   inline bool is_in_range(Real a, Real x_min, Real x_max);
 
   inline Real getTolerance() { return Math::tolerance; }
   inline void setTolerance(Real tol) { Math::tolerance = tol; }
 
   template <UInt p, typename T> inline T pow(T x);
 
   template <class T1, class T2,
             std::enable_if_t<std::is_integral<T1>::value and
                              std::is_integral<T2>::value> * = nullptr>
   inline Real kronecker(T1 i, T2 j) {
     return static_cast<Real>(i == j);
   }
 
   /// reduce all the values of an array, the summation is done in place and the
   /// array is modified
   Real reduce(Array<Real> & array);
 
   class NewtonRaphson {
   public:
     NewtonRaphson(Real tolerance, Real max_iteration)
         : tolerance(tolerance), max_iteration(max_iteration) {}
 
     template <class Functor> Real solve(const Functor & funct, Real x_0);
 
   private:
     Real tolerance;
     Real max_iteration;
   };
 
   struct NewtonRaphsonFunctor {
     explicit NewtonRaphsonFunctor(const std::string & name) : name(name) {}
 
     virtual ~NewtonRaphsonFunctor() = default;
 
     NewtonRaphsonFunctor(const NewtonRaphsonFunctor & other) = default;
     NewtonRaphsonFunctor(NewtonRaphsonFunctor && other) noexcept = default;
     NewtonRaphsonFunctor &
     operator=(const NewtonRaphsonFunctor & other) = default;
     NewtonRaphsonFunctor &
     operator=(NewtonRaphsonFunctor && other) noexcept = default;
 
     virtual Real f(Real x) const = 0;
     virtual Real f_prime(Real x) const = 0;
     std::string name;
   };
 } // namespace Math
 } // namespace akantu
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "aka_math_tmpl.hh"
 
 #endif /* AKANTU_AKA_MATH_H_ */
diff --git a/src/common/aka_math_tmpl.hh b/src/common/aka_math_tmpl.hh
index 50809863a..035d13c3b 100644
--- a/src/common/aka_math_tmpl.hh
+++ b/src/common/aka_math_tmpl.hh
@@ -1,843 +1,742 @@
 /**
  * @file   aka_math_tmpl.hh
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
  * @author Emil Gallyamov <emil.gallyamov@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  * @author Mathilde Radiguet <mathilde.radiguet@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
  * @author Peter Spijker <peter.spijker@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Fri Dec 11 2020
  *
  * @brief  Implementation of the inline functions of the math toolkit
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_blas_lapack.hh"
 #include "aka_math.hh"
 #include "aka_types.hh"
 /* -------------------------------------------------------------------------- */
 #include <cmath>
 #include <typeinfo>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
-namespace Math {
-  /* ------------------------------------------------------------------------ */
-  inline void matrix_vector(UInt im, UInt in,
-                            Real * A, // NOLINT(readability-non-const-parameter)
-                            Real * x, // NOLINT(readability-non-const-parameter)
-                            Real * y, Real alpha) {
-#ifdef AKANTU_USE_BLAS
-    /// y = alpha*op(A)*x + beta*y
-    char tran_A = 'N';
-    int incx = 1;
-    int incy = 1;
-    double beta = 0.;
-    int m = im;
-    int n = in;
-
-    aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
-
-#else
-    std::fill_n(y, im, 0.);
-    for (UInt i = 0; i < im; ++i) {
-      for (UInt j = 0; j < in; ++j) {
-        y[i] += A[i + j * im] * x[j];
-      }
-      y[i] *= alpha;
-    }
-#endif
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void
-  matrixt_vector(UInt im, UInt in,
-                 Real * A, // NOLINT(readability-non-const-parameter)
-                 Real * x, // NOLINT(readability-non-const-parameter)
-                 Real * y, Real alpha) {
-#ifdef AKANTU_USE_BLAS
-    /// y = alpha*op(A)*x + beta*y
-    char tran_A = 'T';
-    int incx = 1;
-    int incy = 1;
-    double beta = 0.;
-    int m = im;
-    int n = in;
-
-    aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
-#else
-    std::fill_n(y, in, 0.);
-    for (UInt i = 0; i < im; ++i) {
-      for (UInt j = 0; j < in; ++j) {
-        y[j] += A[j * im + i] * x[i];
-      }
-      y[i] *= alpha;
-    }
-#endif
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void matrix_matrix(UInt im, UInt in, UInt ik,
-                            Real * A, // NOLINT(readability-non-const-parameter)
-                            Real * B, // NOLINT(readability-non-const-parameter)
-                            Real * C, Real alpha) {
-#ifdef AKANTU_USE_BLAS
-    ///  C := alpha*op(A)*op(B) + beta*C
-    char trans_a = 'N';
-    char trans_b = 'N';
-    double beta = 0.;
-    int m = im, n = in, k = ik;
-
-    aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &m, B, &k, &beta, C,
-             &m);
-#else
-    std::fill_n(C, im * in, 0.);
-    for (UInt j = 0; j < in; ++j) {
-      UInt _jb = j * ik;
-      UInt _jc = j * im;
-      for (UInt i = 0; i < im; ++i) {
-        for (UInt l = 0; l < ik; ++l) {
-          UInt _la = l * im;
-          C[i + _jc] += A[i + _la] * B[l + _jb];
-        }
-        C[i + _jc] *= alpha;
-      }
-    }
-#endif
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void
-  matrixt_matrix(UInt im, UInt in, UInt ik,
-                 Real * A, // NOLINT(readability-non-const-parameter)
-                 Real * B, // NOLINT(readability-non-const-parameter)
-                 Real * C, Real alpha) {
-#ifdef AKANTU_USE_BLAS
-    ///  C := alpha*op(A)*op(B) + beta*C
-    char trans_a = 'T';
-    char trans_b = 'N';
-    double beta = 0.;
-    int m = im, n = in, k = ik;
-
-    aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &k, B, &k, &beta, C,
-             &m);
-#else
-    std::fill_n(C, im * in, 0.);
-    for (UInt j = 0; j < in; ++j) {
-      UInt _jc = j * im;
-      UInt _jb = j * ik;
-      for (UInt i = 0; i < im; ++i) {
-        UInt _ia = i * ik;
-        for (UInt l = 0; l < ik; ++l) {
-          C[i + _jc] += A[l + _ia] * B[l + _jb];
-        }
-        C[i + _jc] *= alpha;
-      }
-    }
-#endif
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void
-  matrix_matrixt(UInt im, UInt in, UInt ik,
-                 Real * A, // NOLINT(readability-non-const-parameter)
-                 Real * B, // NOLINT(readability-non-const-parameter)
-                 Real * C, Real alpha) {
-#ifdef AKANTU_USE_BLAS
-    ///  C := alpha*op(A)*op(B) + beta*C
-    char trans_a = 'N';
-    char trans_b = 'T';
-    double beta = 0.;
-    int m = im, n = in, k = ik;
-
-    aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &m, B, &n, &beta, C,
-             &m);
-#else
-    std::fill_n(C, im * in, 0.);
-    for (UInt j = 0; j < in; ++j) {
-      UInt _jc = j * im;
-      for (UInt i = 0; i < im; ++i) {
-        for (UInt l = 0; l < ik; ++l) {
-          UInt _la = l * im;
-          UInt _lb = l * in;
-          C[i + _jc] += A[i + _la] * B[j + _lb];
-        }
-        C[i + _jc] *= alpha;
-      }
-    }
-#endif
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void
-  matrixt_matrixt(UInt im, UInt in, UInt ik,
-                  Real * A, // NOLINT(readability-non-const-parameter)
-                  Real * B, // NOLINT(readability-non-const-parameter)
-                  Real * C, Real alpha) {
-#ifdef AKANTU_USE_BLAS
-    ///  C := alpha*op(A)*op(B) + beta*C
-    char trans_a = 'T';
-    char trans_b = 'T';
-    double beta = 0.;
-    int m = im, n = in, k = ik;
-
-    aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &k, B, &n, &beta, C,
-             &m);
-#else
-    std::fill_n(C, im * in, 0.);
-    for (UInt j = 0; j < in; ++j) {
-      UInt _jc = j * im;
-      for (UInt i = 0; i < im; ++i) {
-        UInt _ia = i * ik;
-        for (UInt l = 0; l < ik; ++l) {
-          UInt _lb = l * in;
-          C[i + _jc] += A[l + _ia] * B[j + _lb];
-        }
-        C[i + _jc] *= alpha;
-      }
-    }
-#endif
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void aXplusY(UInt n, Real alpha,
-                      Real * x, // NOLINT(readability-non-const-parameter)
-                      Real * y) {
-#ifdef AKANTU_USE_BLAS
-    ///  y := alpha x + y
-    int incx = 1, incy = 1;
-    aka_axpy(&n, &alpha, x, &incx, y, &incy);
-#else
-    for (UInt i = 0; i < n; ++i) {
-      *(y++) += alpha * *(x++);
-    }
-#endif
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline Real vectorDot(Real * v1, // NOLINT(readability-non-const-parameter)
-                        Real * v2, // NOLINT(readability-non-const-parameter)
-                        UInt in) {
-#ifdef AKANTU_USE_BLAS
-    ///  d := v1 . v2
-    int incx = 1, incy = 1, n = in;
-    Real d = aka_dot(&n, v1, &incx, v2, &incy);
-#else
-    Real d = 0;
-    for (UInt i = 0; i < in; ++i) {
-      d += v1[i] * v2[i];
-    }
-#endif
-    return d;
-  }
-
-  /* ------------------------------------------------------------------------ */
-  template <bool tr_A, bool tr_B>
-  inline void matMul(UInt m, UInt n, UInt k, Real alpha,
-                     Real * A, // NOLINT(readability-non-const-parameter)
-                     Real * B, // NOLINT(readability-non-const-parameter)
-                     Real /*beta*/, Real * C) {
-    if (tr_A) {
-      if (tr_B) {
-        matrixt_matrixt(m, n, k, A, B, C, alpha);
-      } else {
-        matrixt_matrix(m, n, k, A, B, C, alpha);
-      }
-    } else {
-      if (tr_B) {
-        matrix_matrixt(m, n, k, A, B, C, alpha);
-      } else {
-        matrix_matrix(m, n, k, A, B, C, alpha);
-      }
-    }
-  }
-
-  /* ------------------------------------------------------------------------ */
-  template <bool tr_A>
-  inline void matVectMul(UInt m, UInt n, Real alpha,
-                         Real * A, // NOLINT(readability-non-const-parameter)
-                         Real * x, // NOLINT(readability-non-const-parameter)
-                         Real /*beta*/, Real * y) {
-    if (tr_A) {
-      matrixt_vector(m, n, A, x, y, alpha);
-    } else {
-      matrix_vector(m, n, A, x, y, alpha);
-    }
-  }
-
-  /* ------------------------------------------------------------------------ */
-  template <typename T>
-  inline void matrixEig(UInt n,
-                        T * A, // NOLINT(readability-non-const-parameter)
-                        T * d, T * V) {
-
-    // Matrix  A is  row major,  so the  lapack function  in fortran  will
-    // process A^t. Asking for the left eigenvectors of A^t will give the
-    // transposed right eigenvectors of A so in the C++ code the right
-    // eigenvectors.
-    char jobvr{'N'};
-    if (V != nullptr) {
-      jobvr = 'V'; // compute left  eigenvectors
-    }
-
-    char jobvl{'N'}; // compute right eigenvectors
-
-    auto * di = new T[n]; // imaginary part of the eigenvalues
-
-    int info;
-    int N = n;
-
-    T wkopt;
-    int lwork = -1;
-    // query and allocate the optimal workspace
-    aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, nullptr, &N, V, &N, &wkopt,
-                &lwork, &info);
-
-    lwork = int(wkopt);
-    auto * work = new T[lwork];
-    // solve the eigenproblem
-    aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, nullptr, &N, V, &N, work,
-                &lwork, &info);
-
-    AKANTU_DEBUG_ASSERT(
-        info == 0,
-        "Problem computing eigenvalues/vectors. DGEEV exited with the value "
-            << info);
-
-    delete[] work;
-    delete[] di; // I hope for you that there was no complex eigenvalues !!!
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void
-  matrix22_eigenvalues(Real * A, // NOLINT(readability-non-const-parameter)
-                       Real * Adiag) {
-    /// d = determinant of Matrix A
-    Real d = det2(A);
-    /// b = trace of Matrix A
-    Real b = A[0] + A[3];
-
-    Real c = std::sqrt(b * b - 4 * d);
-    Adiag[0] = .5 * (b + c);
-    Adiag[1] = .5 * (b - c);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void
-  matrix33_eigenvalues(Real * A, // NOLINT(readability-non-const-parameter)
-                       Real * Adiag) {
-    matrixEig(3, A, Adiag);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  template <UInt dim>
-  inline void eigenvalues(Real * A, // NOLINT(readability-non-const-parameter)
-                          Real * d) {
-    if (dim == 1) {
-      d[0] = A[0];
-    } else if (dim == 2) {
-      matrix22_eigenvalues(A, d);
-    }
-    // else if(dim == 3) { matrix33_eigenvalues(A, d); }
-    else {
-      matrixEig(dim, A, d);
-    }
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline Real det2(const Real * mat) {
-    return mat[0] * mat[3] - mat[1] * mat[2];
-  }
 
-  /* ------------------------------------------------------------------------ */
-  inline Real det3(const Real * mat) {
-    return mat[0] * (mat[4] * mat[8] - mat[7] * mat[5]) -
-           mat[3] * (mat[1] * mat[8] - mat[7] * mat[2]) +
-           mat[6] * (mat[1] * mat[5] - mat[4] * mat[2]);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  template <UInt n> inline Real det(const Real * mat) {
-    if (n == 1) {
-      return *mat;
-    }
-    if (n == 2) {
-      return det2(mat);
-    }
-    if (n == 3) {
-      return det3(mat);
-    }
-    return det(n, mat);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  template <typename T> inline T det(UInt n, const T * A) {
-    int N = n;
-    int info;
-    auto * ipiv = new int[N + 1];
-
-    auto * LU = new T[N * N];
-    std::copy(A, A + N * N, LU);
-
-    // LU factorization of A
-    aka_getrf(&N, &N, LU, &N, ipiv, &info);
-    if (info > 0) {
-      AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
-                                                                   << " )");
-    }
-
-    // det(A) = det(L) * det(U) = 1 * det(U) = product_i U_{ii}
-    T det = 1.;
-    for (int i = 0; i < N; ++i) {
-      det *= (2 * (ipiv[i] == i) - 1) * LU[i * n + i];
-    }
-
-    delete[] ipiv;
-    delete[] LU;
-    return det;
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void normal2(const Real * vec, Real * normal) {
-    normal[0] = vec[1];
-    normal[1] = -vec[0];
-    normalize2(normal);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void normal3(const Real * vec1, const Real * vec2, Real * normal) {
-    vectorProduct3(vec1, vec2, normal);
-    normalize3(normal);
-  }
+// // /* -------------------------------------------------------------------------- */
+// // inline void Math::matrix_vector(UInt im, UInt in, Real * A, Real * x, Real * y,
+// //                                 Real alpha) {
+// // #ifdef AKANTU_USE_BLAS
+// //   /// y = alpha*op(A)*x + beta*y
+// //   char tran_A = 'N';
+// //   int incx = 1;
+// //   int incy = 1;
+// //   double beta = 0.;
+// //   int m = im;
+// //   int n = in;
+
+// //   aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
+
+// // #else
+// //   memset(y, 0, im * sizeof(Real));
+// //   for (UInt i = 0; i < im; ++i) {
+// //     for (UInt j = 0; j < in; ++j) {
+// //       y[i] += A[i + j * im] * x[j];
+// //     }
+// //     y[i] *= alpha;
+// //   }
+// // #endif
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline void Math::matrixt_vector(UInt im, UInt in, Real * A, Real * x, Real * y,
+// //                                  Real alpha) {
+// // #ifdef AKANTU_USE_BLAS
+// //   /// y = alpha*op(A)*x + beta*y
+// //   char tran_A = 'T';
+// //   int incx = 1;
+// //   int incy = 1;
+// //   double beta = 0.;
+// //   int m = im;
+// //   int n = in;
+
+// //   aka_gemv(&tran_A, &m, &n, &alpha, A, &m, x, &incx, &beta, y, &incy);
+// // #else
+// //   memset(y, 0, in * sizeof(Real));
+// //   for (UInt i = 0; i < im; ++i) {
+// //     for (UInt j = 0; j < in; ++j) {
+// //       y[j] += A[j * im + i] * x[i];
+// //     }
+// //     y[i] *= alpha;
+// //   }
+// // #endif
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline void Math::matrix_matrix(UInt im, UInt in, UInt ik, Real * A, Real * B,
+// //                                 Real * C, Real alpha) {
+// // #ifdef AKANTU_USE_BLAS
+// //   ///  C := alpha*op(A)*op(B) + beta*C
+// //   char trans_a = 'N';
+// //   char trans_b = 'N';
+// //   double beta = 0.;
+// //   int m = im, n = in, k = ik;
+
+// //   aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &m, B, &k, &beta, C, &m);
+// // #else
+// //   memset(C, 0, im * in * sizeof(Real));
+// //   for (UInt j = 0; j < in; ++j) {
+// //     UInt _jb = j * ik;
+// //     UInt _jc = j * im;
+// //     for (UInt i = 0; i < im; ++i) {
+// //       for (UInt l = 0; l < ik; ++l) {
+// //         UInt _la = l * im;
+// //         C[i + _jc] += A[i + _la] * B[l + _jb];
+// //       }
+// //       C[i + _jc] *= alpha;
+// //     }
+// //   }
+// // #endif
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline void Math::matrixt_matrix(UInt im, UInt in, UInt ik, Real * A, Real * B,
+// //                                  Real * C, Real alpha) {
+// // #ifdef AKANTU_USE_BLAS
+// //   ///  C := alpha*op(A)*op(B) + beta*C
+// //   char trans_a = 'T';
+// //   char trans_b = 'N';
+// //   double beta = 0.;
+// //   int m = im, n = in, k = ik;
+
+// //   aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &k, B, &k, &beta, C, &m);
+// // #else
+// //   memset(C, 0, im * in * sizeof(Real));
+// //   for (UInt j = 0; j < in; ++j) {
+// //     UInt _jc = j * im;
+// //     UInt _jb = j * ik;
+// //     for (UInt i = 0; i < im; ++i) {
+// //       UInt _ia = i * ik;
+// //       for (UInt l = 0; l < ik; ++l) {
+// //         C[i + _jc] += A[l + _ia] * B[l + _jb];
+// //       }
+// //       C[i + _jc] *= alpha;
+// //     }
+// //   }
+// // #endif
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline void Math::matrix_matrixt(UInt im, UInt in, UInt ik, Real * A, Real * B,
+// //                                  Real * C, Real alpha) {
+// // #ifdef AKANTU_USE_BLAS
+// //   ///  C := alpha*op(A)*op(B) + beta*C
+// //   char trans_a = 'N';
+// //   char trans_b = 'T';
+// //   double beta = 0.;
+// //   int m = im, n = in, k = ik;
+
+// //   aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &m, B, &n, &beta, C, &m);
+// // #else
+// //   memset(C, 0, im * in * sizeof(Real));
+// //   for (UInt j = 0; j < in; ++j) {
+// //     UInt _jc = j * im;
+// //     for (UInt i = 0; i < im; ++i) {
+// //       for (UInt l = 0; l < ik; ++l) {
+// //         UInt _la = l * im;
+// //         UInt _lb = l * in;
+// //         C[i + _jc] += A[i + _la] * B[j + _lb];
+// //       }
+// //       C[i + _jc] *= alpha;
+// //     }
+// //   }
+// // #endif
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline void Math::matrixt_matrixt(UInt im, UInt in, UInt ik, Real * A, Real * B,
+// //                                   Real * C, Real alpha) {
+// // #ifdef AKANTU_USE_BLAS
+// //   ///  C := alpha*op(A)*op(B) + beta*C
+// //   char trans_a = 'T';
+// //   char trans_b = 'T';
+// //   double beta = 0.;
+// //   int m = im, n = in, k = ik;
+
+// //   aka_gemm(&trans_a, &trans_b, &m, &n, &k, &alpha, A, &k, B, &n, &beta, C, &m);
+// // #else
+// //   memset(C, 0, im * in * sizeof(Real));
+// //   for (UInt j = 0; j < in; ++j) {
+// //     UInt _jc = j * im;
+// //     for (UInt i = 0; i < im; ++i) {
+// //       UInt _ia = i * ik;
+// //       for (UInt l = 0; l < ik; ++l) {
+// //         UInt _lb = l * in;
+// //         C[i + _jc] += A[l + _ia] * B[j + _lb];
+// //       }
+// //       C[i + _jc] *= alpha;
+// //     }
+// //   }
+// // #endif
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline void Math::aXplusY(UInt n, Real alpha, Real * x, Real * y) {
+// // #ifdef AKANTU_USE_BLAS
+// //   ///  y := alpha x + y
+// //   int incx = 1, incy = 1;
+// //   aka_axpy(&n, &alpha, x, &incx, y, &incy);
+// // #else
+// //   for (UInt i = 0; i < n; ++i)
+// //     *(y++) += alpha * *(x++);
+// // #endif
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline Real Math::vectorDot(Real * v1, Real * v2, UInt in) {
+// // #ifdef AKANTU_USE_BLAS
+// //   ///  d := v1 . v2
+// //   int incx = 1, incy = 1, n = in;
+// //   Real d = aka_dot(&n, v1, &incx, v2, &incy);
+// // #else
+// //   Real d = 0;
+// //   for (UInt i = 0; i < in; ++i) {
+// //     d += v1[i] * v2[i];
+// //   }
+// // #endif
+// //   return d;
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // template <bool tr_A, bool tr_B>
+// // inline void Math::matMul(UInt m, UInt n, UInt k, Real alpha, Real * A, Real * B,
+// //                          __attribute__((unused)) Real beta, Real * C) {
+// //   if (tr_A) {
+// //     if (tr_B)
+// //       matrixt_matrixt(m, n, k, A, B, C, alpha);
+// //     else
+// //       matrixt_matrix(m, n, k, A, B, C, alpha);
+// //   } else {
+// //     if (tr_B)
+// //       matrix_matrixt(m, n, k, A, B, C, alpha);
+// //     else
+// //       matrix_matrix(m, n, k, A, B, C, alpha);
+// //   }
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // template <bool tr_A>
+// // inline void Math::matVectMul(UInt m, UInt n, Real alpha, Real * A, Real * x,
+// //                              __attribute__((unused)) Real beta, Real * y) {
+// //   if (tr_A) {
+// //     matrixt_vector(m, n, A, x, y, alpha);
+// //   } else {
+// //     matrix_vector(m, n, A, x, y, alpha);
+// //   }
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // template <typename T> inline void Math::matrixEig(UInt n, T * A, T * d, T * V) {
+
+// //   // Matrix  A is  row major,  so the  lapack function  in fortran  will process
+// //   // A^t. Asking for the left eigenvectors of A^t will give the transposed right
+// //   // eigenvectors of A so in the C++ code the right eigenvectors.
+// //   char jobvr, jobvl;
+// //   if (V != nullptr)
+// //     jobvr = 'V'; // compute left  eigenvectors
+// //   else
+// //     jobvr = 'N'; // compute left  eigenvectors
+
+// //   jobvl = 'N'; // compute right eigenvectors
+
+// //   auto * di = new T[n]; // imaginary part of the eigenvalues
+
+// //   int info;
+// //   int N = n;
+
+// //   T wkopt;
+// //   int lwork = -1;
+// //   // query and allocate the optimal workspace
+// //   aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, nullptr, &N, V, &N, &wkopt,
+// //               &lwork, &info);
+
+// //   lwork = int(wkopt);
+// //   auto * work = new T[lwork];
+// //   // solve the eigenproblem
+// //   aka_geev<T>(&jobvl, &jobvr, &N, A, &N, d, di, nullptr, &N, V, &N, work,
+// //               &lwork, &info);
+
+// //   AKANTU_DEBUG_ASSERT(
+// //       info == 0,
+// //       "Problem computing eigenvalues/vectors. DGEEV exited with the value "
+// //           << info);
+
+// //   delete[] work;
+// //   delete[] di; // I hope for you that there was no complex eigenvalues !!!
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline void Math::matrix22_eigenvalues(Real * A, Real * Adiag) {
+// //   /// d = determinant of Matrix A
+// //   Real d = det2(A);
+// //   /// b = trace of Matrix A
+// //   Real b = A[0] + A[3];
+
+// //   Real c = sqrt(b * b - 4 * d);
+// //   Adiag[0] = .5 * (b + c);
+// //   Adiag[1] = .5 * (b - c);
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline void Math::matrix33_eigenvalues(Real * A, Real * Adiag) {
+// //   matrixEig(3, A, Adiag);
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // template <Int dim> inline void Math::eigenvalues(Real * A, Real * d) {
+// //   if (dim == 1) {
+// //     d[0] = A[0];
+// //   } else if (dim == 2) {
+// //     matrix22_eigenvalues(A, d);
+// //   }
+// //   // else if(dim == 3) { matrix33_eigenvalues(A, d); }
+// //   else
+// //     matrixEig(dim, A, d);
+// // }
+
+// // /* -------------------------------------------------------------------------- */
+// // inline Real Math::det2(const Real * mat) {
+// //   return mat[0] * mat[3] - mat[1] * mat[2];
+// // }
+
+// /* -------------------------------------------------------------------------- */
+// template <UInt n> inline Real Math::det(const Real * mat) {
+//   if (n == 1)
+//     return *mat;
+//   else if (n == 2)
+//     return det2(mat);
+//   else if (n == 3)
+//     return det3(mat);
+//   else
+//     return det(n, mat);
+// }
+
+// /* -------------------------------------------------------------------------- */
+// template <typename T> inline T Math::det(UInt n, const T * A) {
+//   int N = n;
+//   int info;
+//   auto * ipiv = new int[N + 1];
+
+//   auto * LU = new T[N * N];
+//   std::copy(A, A + N * N, LU);
+
+//   // LU factorization of A
+//   aka_getrf(&N, &N, LU, &N, ipiv, &info);
+//   if (info > 0) {
+//     AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
+//                                                                  << " )");
+//   }
+
+//   // det(A) = det(L) * det(U) = 1 * det(U) = product_i U_{ii}
+//   T det = 1.;
+//   for (int i = 0; i < N; ++i)
+//     det *= (2 * (ipiv[i] == i) - 1) * LU[i * n + i];
+
+//   delete[] ipiv;
+//   delete[] LU;
+//   return det;
+// }
 
   /* ------------------------------------------------------------------------ */
   inline void normalize2(Real * vec) {
     Real norm = norm2(vec);
     vec[0] /= norm;
     vec[1] /= norm;
   }
 
   /* ------------------------------------------------------------------------ */
   inline void normalize3(Real * vec) {
     Real norm = norm3(vec);
     vec[0] /= norm;
     vec[1] /= norm;
     vec[2] /= norm;
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real norm2(const Real * vec) {
     return sqrt(vec[0] * vec[0] + vec[1] * vec[1]);
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real norm3(const Real * vec) {
     return sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real norm(UInt n, const Real * vec) {
     Real norm = 0.;
     for (UInt i = 0; i < n; ++i) {
       norm += vec[i] * vec[i];
     }
     return sqrt(norm);
   }
 
   /* ------------------------------------------------------------------------ */
   inline void inv2(const Real * mat, Real * inv) {
     Real det_mat = det2(mat);
 
     inv[0] = mat[3] / det_mat;
     inv[1] = -mat[1] / det_mat;
     inv[2] = -mat[2] / det_mat;
     inv[3] = mat[0] / det_mat;
   }
+// /* -------------------------------------------------------------------------- */
+// inline Real Math::norm(UInt n, const Real * vec) {
+//   Real norm = 0.;
+//   for (UInt i = 0; i < n; ++i) {
+//     norm += vec[i] * vec[i];
+//   }
+//   return sqrt(norm);
+// }
+
+// /* -------------------------------------------------------------------------- */
+// inline void Math::inv2(const Real * mat, Real * inv) {
+//   Real det_mat = det2(mat);
+
+//   inv[0] = mat[3] / det_mat;
+//   inv[1] = -mat[1] / det_mat;
+//   inv[2] = -mat[2] / det_mat;
+//   inv[3] = mat[0] / det_mat;
+// }
+
+// /* -------------------------------------------------------------------------- */
+// inline void Math::inv3(const Real * mat, Real * inv) {
+//   Real det_mat = det3(mat);
+
+//   inv[0] = (mat[4] * mat[8] - mat[7] * mat[5]) / det_mat;
+//   inv[1] = (mat[2] * mat[7] - mat[8] * mat[1]) / det_mat;
+//   inv[2] = (mat[1] * mat[5] - mat[4] * mat[2]) / det_mat;
+//   inv[3] = (mat[5] * mat[6] - mat[8] * mat[3]) / det_mat;
+//   inv[4] = (mat[0] * mat[8] - mat[6] * mat[2]) / det_mat;
+//   inv[5] = (mat[2] * mat[3] - mat[5] * mat[0]) / det_mat;
+//   inv[6] = (mat[3] * mat[7] - mat[6] * mat[4]) / det_mat;
+//   inv[7] = (mat[1] * mat[6] - mat[7] * mat[0]) / det_mat;
+//   inv[8] = (mat[0] * mat[4] - mat[3] * mat[1]) / det_mat;
+// }
+
+// /* -------------------------------------------------------------------------- */
+// template <UInt n> inline void Math::inv(const Real * A, Real * Ainv) {
+//   if (n == 1)
+//     *Ainv = 1. / *A;
+//   else if (n == 2)
+//     inv2(A, Ainv);
+//   else if (n == 3)
+//     inv3(A, Ainv);
+//   else
+//     inv(n, A, Ainv);
+// }
+
+// /* -------------------------------------------------------------------------- */
+// template <typename T> inline void Math::inv(UInt n, const T * A, T * invA) {
+//   int N = n;
+//   int info;
+//   auto * ipiv = new int[N + 1];
+//   int lwork = N * N;
+//   auto * work = new T[lwork];
+
+//   std::copy(A, A + n * n, invA);
+
+//   aka_getrf(&N, &N, invA, &N, ipiv, &info);
+//   if (info > 0) {
+//     AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
+//                                                                  << " )");
+//   }
+
+//   aka_getri(&N, invA, &N, ipiv, work, &lwork, &info);
+//   if (info != 0) {
+//     AKANTU_ERROR("Cannot invert the matrix (info: " << info << " )");
+//   }
+
+//   delete[] ipiv;
+//   delete[] work;
+// }
 
-  /* ------------------------------------------------------------------------ */
-  inline void inv3(const Real * mat, Real * inv) {
-    Real det_mat = det3(mat);
-
-    inv[0] = (mat[4] * mat[8] - mat[7] * mat[5]) / det_mat;
-    inv[1] = (mat[2] * mat[7] - mat[8] * mat[1]) / det_mat;
-    inv[2] = (mat[1] * mat[5] - mat[4] * mat[2]) / det_mat;
-    inv[3] = (mat[5] * mat[6] - mat[8] * mat[3]) / det_mat;
-    inv[4] = (mat[0] * mat[8] - mat[6] * mat[2]) / det_mat;
-    inv[5] = (mat[2] * mat[3] - mat[5] * mat[0]) / det_mat;
-    inv[6] = (mat[3] * mat[7] - mat[6] * mat[4]) / det_mat;
-    inv[7] = (mat[1] * mat[6] - mat[7] * mat[0]) / det_mat;
-    inv[8] = (mat[0] * mat[4] - mat[3] * mat[1]) / det_mat;
-  }
-
-  /* ------------------------------------------------------------------------ */
-  template <UInt n> inline void inv(const Real * A, Real * Ainv) {
-    if (n == 1) {
-      *Ainv = 1. / *A;
-    } else if (n == 2) {
-      inv2(A, Ainv);
-    } else if (n == 3) {
-      inv3(A, Ainv);
-    } else {
-      inv(n, A, Ainv);
-    }
-  }
-
-  /* ------------------------------------------------------------------------ */
-  template <typename T> inline void inv(UInt n, const T * A, T * invA) {
-    int N = n;
-    int info;
-    auto * ipiv = new int[N + 1];
-    int lwork = N * N;
-    auto * work = new T[lwork];
-
-    std::copy(A, A + n * n, invA);
-
-    aka_getrf(&N, &N, invA, &N, ipiv, &info);
-    if (info > 0) {
-      AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
-                                                                   << " )");
-    }
-
-    aka_getri(&N, invA, &N, ipiv, work, &lwork, &info);
-    if (info != 0) {
-      AKANTU_ERROR("Cannot invert the matrix (info: " << info << " )");
-    }
-
-    delete[] ipiv;
-    delete[] work;
-  }
-
-  /* ------------------------------------------------------------------------ */
-  template <typename T>
-  inline void solve(UInt n, const T * A, T * x, const T * b) {
-    int N = n;
-    int info;
-    auto * ipiv = new int[N];
-    auto * lu_A = new T[N * N];
-
-    std::copy(A, A + N * N, lu_A);
-
-    aka_getrf(&N, &N, lu_A, &N, ipiv, &info);
-    if (info > 0) {
-      AKANTU_ERROR("Singular matrix - cannot factorize it (info: " << info
-                                                                   << " )");
-    }
-
-    char trans = 'N';
-    int nrhs = 1;
-
-    std::copy(b, b + N, x);
-
-    aka_getrs(&trans, &N, &nrhs, lu_A, &N, ipiv, x, &N, &info);
-    if (info != 0) {
-      AKANTU_ERROR("Cannot solve the system (info: " << info << " )");
-    }
-
-    delete[] ipiv;
-    delete[] lu_A;
-  }
-
-  /* ------------------------------------------------------------------------ */
-  /* ------------------------------------------------------------------------ */
-  inline Real
-  matrixDoubleDot22(Real * A, // NOLINT(readability-non-const-parameter)
-                    Real * B  // NOLINT(readability-non-const-parameter)
-  ) {
-    Real d;
-    d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2] + A[3] * B[3];
-    return d;
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline Real
-  matrixDoubleDot33(Real * A, // NOLINT(readability-non-const-parameter)
-                    Real * B  // NOLINT(readability-non-const-parameter)
-  ) {
-    Real d;
-    d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2] + A[3] * B[3] + A[4] * B[4] +
-        A[5] * B[5] + A[6] * B[6] + A[7] * B[7] + A[8] * B[8];
-    return d;
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline Real
-  matrixDoubleDot(UInt n,
-                  Real * A, // NOLINT(readability-non-const-parameter)
-                  Real * B  // NOLINT(readability-non-const-parameter)
-  ) {
-    Real d = 0.;
-    for (UInt i = 0; i < n; ++i) {
-      for (UInt j = 0; j < n; ++j) {
-        d += A[i * n + j] * B[i * n + j];
-      }
-    }
-    return d;
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline void vectorProduct3(const Real * v1, const Real * v2, Real * res) {
-    res[0] = v1[1] * v2[2] - v1[2] * v2[1];
-    res[1] = v1[2] * v2[0] - v1[0] * v2[2];
-    res[2] = v1[0] * v2[1] - v1[1] * v2[0];
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline Real vectorDot2(const Real * v1, const Real * v2) {
-    return (v1[0] * v2[0] + v1[1] * v2[1]);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline Real vectorDot3(const Real * v1, const Real * v2) {
-    return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline Real distance_2d(const Real * x, const Real * y) {
-    return std::sqrt((y[0] - x[0]) * (y[0] - x[0]) +
-                     (y[1] - x[1]) * (y[1] - x[1]));
-  }
-
-  /* ------------------------------------------------------------------------ */
-  inline Real triangle_inradius(const Vector<Real> & coord1, const Vector<Real> & coord2,
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+// inline Real Math::matrixDoubleDot22(Real * A, Real * B) {
+//   Real d;
+//   d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2] + A[3] * B[3];
+//   return d;
+// }
+
+// /* -------------------------------------------------------------------------- */
+// inline Real Math::matrixDoubleDot33(Real * A, Real * B) {
+//   Real d;
+//   d = A[0] * B[0] + A[1] * B[1] + A[2] * B[2] + A[3] * B[3] + A[4] * B[4] +
+//       A[5] * B[5] + A[6] * B[6] + A[7] * B[7] + A[8] * B[8];
+//   return d;
+// }
+
+// /* -------------------------------------------------------------------------- */
+// inline Real Math::matrixDoubleDot(UInt n, Real * A, Real * B) {
+//   Real d = 0.;
+//   for (UInt i = 0; i < n; ++i) {
+//     for (UInt j = 0; j < n; ++j) {
+//       d += A[i * n + j] * B[i * n + j];
+//     }
+//   }
+//   return d;
+// }
+
+// /* -------------------------------------------------------------------------- */
+// inline Real Math::vectorDot2(const Real * v1, const Real * v2) {
+//   return (v1[0] * v2[0] + v1[1] * v2[1]);
+// }
+
+// /* -------------------------------------------------------------------------- */
+// inline Real Math::vectorDot3(const Real * v1, const Real * v2) {
+//   return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]);
+// }
+  inline Real triangle_inradius(const Vector<Real> & coord1,
+                                const Vector<Real> & coord2,
                                 const Vector<Real> & coord3) {
     /**
      * @f{eqnarray*}{
      * r &=& A / s \\
      * A &=& 1/4 * \sqrt{(a + b + c) * (a - b + c) * (a + b - c) (-a + b + c)}
      * \\ s &=& \frac{a + b + c}{2}
      * @f}
      */
 
     Real a, b, c;
 
     a = coord1.distance(coord2);
     b = coord2.distance(coord3);
     c = coord1.distance(coord3);
 
     Real s;
     s = (a + b + c) * 0.5;
 
     return std::sqrt((s - a) * (s - b) * (s - c) / s);
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real distance_3d(const Real * x, const Real * y) {
     return std::sqrt((y[0] - x[0]) * (y[0] - x[0]) +
                      (y[1] - x[1]) * (y[1] - x[1]) +
                      (y[2] - x[2]) * (y[2] - x[2]));
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real tetrahedron_volume(const Real * coord1, const Real * coord2,
                                  const Real * coord3, const Real * coord4) {
     Real xx[9];
 
     xx[0] = coord2[0];
     xx[1] = coord2[1];
     xx[2] = coord2[2];
     xx[3] = coord3[0];
     xx[4] = coord3[1];
     xx[5] = coord3[2];
     xx[6] = coord4[0];
     xx[7] = coord4[1];
     xx[8] = coord4[2];
     auto vol = det3(xx);
 
     xx[0] = coord1[0];
     xx[1] = coord1[1];
     xx[2] = coord1[2];
     xx[3] = coord3[0];
     xx[4] = coord3[1];
     xx[5] = coord3[2];
     xx[6] = coord4[0];
     xx[7] = coord4[1];
     xx[8] = coord4[2];
     vol -= det3(xx);
 
     xx[0] = coord1[0];
     xx[1] = coord1[1];
     xx[2] = coord1[2];
     xx[3] = coord2[0];
     xx[4] = coord2[1];
     xx[5] = coord2[2];
     xx[6] = coord4[0];
     xx[7] = coord4[1];
     xx[8] = coord4[2];
     vol += det3(xx);
 
     xx[0] = coord1[0];
     xx[1] = coord1[1];
     xx[2] = coord1[2];
     xx[3] = coord2[0];
     xx[4] = coord2[1];
     xx[5] = coord2[2];
     xx[6] = coord3[0];
     xx[7] = coord3[1];
     xx[8] = coord3[2];
     vol -= det3(xx);
 
     vol /= 6;
 
     return vol;
   }
 
   /* ------------------------------------------------------------------------ */
   inline Real tetrahedron_inradius(const Real * coord1, const Real * coord2,
                                    const Real * coord3, const Real * coord4) {
     auto l12 = distance_3d(coord1, coord2);
     auto l13 = distance_3d(coord1, coord3);
     auto l14 = distance_3d(coord1, coord4);
     auto l23 = distance_3d(coord2, coord3);
     auto l24 = distance_3d(coord2, coord4);
     auto l34 = distance_3d(coord3, coord4);
 
     auto s1 = (l12 + l23 + l13) * 0.5;
     s1 = std::sqrt(s1 * (s1 - l12) * (s1 - l23) * (s1 - l13));
 
     auto s2 = (l12 + l24 + l14) * 0.5;
     s2 = std::sqrt(s2 * (s2 - l12) * (s2 - l24) * (s2 - l14));
 
     auto s3 = (l23 + l34 + l24) * 0.5;
     s3 = std::sqrt(s3 * (s3 - l23) * (s3 - l34) * (s3 - l24));
 
     auto s4 = (l13 + l34 + l14) * 0.5;
     s4 = std::sqrt(s4 * (s4 - l13) * (s4 - l34) * (s4 - l14));
 
     auto volume = tetrahedron_volume(coord1, coord2, coord3, coord4);
 
     return 3 * volume / (s1 + s2 + s3 + s4);
   }
 
   /* ------------------------------------------------------------------------ */
   inline void barycenter(const Real * coord, UInt nb_points,
                          UInt spatial_dimension, Real * barycenter) {
     std::fill_n(barycenter, spatial_dimension, 0.);
     for (UInt n = 0; n < nb_points; ++n) {
       UInt offset = n * spatial_dimension;
       for (UInt i = 0; i < spatial_dimension; ++i) {
         barycenter[i] += coord[offset + i] / (Real)nb_points;
       }
     }
   }
 
   /* ------------------------------------------------------------------------ */
   inline void vector_2d(const Real * x, const Real * y, Real * res) {
     res[0] = y[0] - x[0];
     res[1] = y[1] - x[1];
   }
 
   /* ------------------------------------------------------------------------ */
   inline void vector_3d(const Real * x, const Real * y, Real * res) {
     res[0] = y[0] - x[0];
     res[1] = y[1] - x[1];
     res[2] = y[2] - x[2];
   }
 
   /* ------------------------------------------------------------------------ */
   /// Combined absolute and relative tolerance test proposed in
   /// Real-time collision detection by C. Ericson (2004)
   inline bool are_float_equal(const Real x, const Real y) {
     Real abs_max = std::max(std::abs(x), std::abs(y));
     abs_max = std::max(abs_max, Real(1.));
     return std::abs(x - y) <= (tolerance * abs_max);
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool isnan(Real x) {
 #if defined(__INTEL_COMPILER)
 #pragma warning(push)
 #pragma warning(disable : 1572)
 #endif // defined(__INTEL_COMPILER)
 
     // x = x return false means x = quiet_NaN
     return !(x == x);
 
 #if defined(__INTEL_COMPILER)
 #pragma warning(pop)
 #endif // defined(__INTEL_COMPILER)
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool are_vector_equal(UInt n, Real * x, Real * y) {
     bool test = true;
     for (UInt i = 0; i < n; ++i) {
       test &= are_float_equal(x[i], y[i]);
     }
 
     return test;
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool intersects(Real x_min, Real x_max, Real y_min, Real y_max) {
     return not((x_max < y_min) or (x_min > y_max));
   }
 
   /* ------------------------------------------------------------------------ */
   inline bool is_in_range(Real a, Real x_min, Real x_max) {
     return ((a >= x_min) and (a <= x_max));
   }
 
   /* ------------------------------------------------------------------------ */
   template <UInt p, typename T> inline T pow(T x) {
     return (pow<p - 1, T>(x) * x);
   }
   template <> inline UInt pow<0, UInt>(__attribute__((unused)) UInt x) {
     return (1);
   }
   template <> inline Real pow<0, Real>(__attribute__((unused)) Real x) {
     return (1.);
   }
 
   /* ------------------------------------------------------------------------ */
 
   template <class Functor>
   Real NewtonRaphson::solve(const Functor & funct, Real x_0) {
     Real x = x_0;
     Real f_x = funct.f(x);
     UInt iter = 0;
     while (std::abs(f_x) > this->tolerance && iter < this->max_iteration) {
       x -= f_x / funct.f_prime(x);
       f_x = funct.f(x);
       iter++;
     }
 
     AKANTU_DEBUG_ASSERT(iter < this->max_iteration,
                         "Newton Raphson ("
                             << funct.name << ") solve did not converge in "
                             << this->max_iteration << " iterations (tolerance: "
                             << this->tolerance << ")");
 
     return x;
   }
 
 } // namespace Math
 } // namespace akantu
diff --git a/src/common/aka_types.hh b/src/common/aka_types.hh
index 03ead8ce5..bddaaed8e 100644
--- a/src/common/aka_types.hh
+++ b/src/common/aka_types.hh
@@ -1,799 +1,804 @@
 /**
  * @file   aka_types.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 17 2011
  * @date last modification: Wed Dec 09 2020
  *
  * @brief  description of the "simple" types
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_compatibilty_with_cpp_standard.hh"
 #include "aka_error.hh"
 #include "aka_fwd.hh"
 #include "aka_math.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <array>
 #include <initializer_list>
 #include <numeric>
 #include <type_traits>
 
 #ifndef __AKANTU_AKA_TYPES_HH__
 #define __AKANTU_AKA_TYPES_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace aka {
 template <typename T> struct is_eigen_map : public std::false_type {};
 } // namespace aka
 
 /* -------------------------------------------------------------------------- */
 #define EIGEN_MATRIXBASE_PLUGIN "aka_types_eigen_matrix_base_plugin.hh"
 #define EIGEN_MATRIX_PLUGIN "aka_types_eigen_matrix_plugin.hh"
 #define EIGEN_PLAINOBJECTBASE_PLUGIN                                           \
   "aka_types_eigen_plain_object_base_plugin.hh"
 #include <Eigen/Dense>
 #include <Eigen/Eigenvalues>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 using Eigen::Ref;
 
 template <typename T, Eigen::Index n = Eigen::Dynamic>
 using Vector = Eigen::Matrix<T, n, 1>;
 
 template <typename T, Eigen::Index m = Eigen::Dynamic,
           Eigen::Index n = Eigen::Dynamic>
 using Matrix = Eigen::Matrix<T, m, n, Eigen::AutoAlign | Eigen::ColMajor>;
 
 template <typename T, Eigen::Index n = Eigen::Dynamic>
 using VectorProxy =
     Eigen::Map<std::conditional_t<std::is_const<T>::value,
                                   const Vector<std::remove_const_t<T>, n>,
                                   Vector<std::remove_const_t<T>, n>>>;
 
 template <typename T, Eigen::Index m = Eigen::Dynamic,
           Eigen::Index n = Eigen::Dynamic>
 using MatrixProxy =
     Eigen::Map<std::conditional_t<std::is_const<T>::value,
                                   const Matrix<std::remove_const_t<T>, m, n>,
                                   Matrix<std::remove_const_t<T>, m, n>>>;
 
 using VectorXr = Vector<Real>;
 using MatrixXr = Matrix<Real>;
 
 enum NormType : int8_t { L_1 = 1, L_2 = 2, L_inf = -1 };
 
 struct TensorTraitBase {};
 template <size_t n> struct TensorTrait : public TensorTraitBase {};
 
 } // namespace akantu
 
 namespace aka {
 template <typename Derived>
 using is_matrice = aka::bool_constant<not Derived::IsVectorAtCompileTime>;
 
 template <typename Derived>
 using is_vector = aka::bool_constant<Derived::IsVectorAtCompileTime>;
 
 template <typename... Ds>
 using are_vectors = aka::conjunction<is_vector<Ds>...>;
 
 template <typename... Ds>
 using are_matrices = aka::conjunction<is_matrice<Ds>...>;
 
 template <typename... Ds>
 using enable_if_matrices_t = std::enable_if_t<are_matrices<Ds...>::value>;
 
 // template <typename T> struct is_eigen_map : public std::false_type {};
 
 template <typename PlainObjectType, int MapOptions, typename StrideType>
 struct is_eigen_map<Eigen::Map<PlainObjectType, MapOptions, StrideType>>
     : public std::true_type {};
 } // namespace aka
 
 /* -------------------------------------------------------------------------- */
 namespace aka {
+
 template <typename T>
-using is_tensor = std::is_base_of<akantu::TensorTraitBase, T>;
+struct is_tensor : public std::is_base_of<akantu::TensorTraitBase, T> {};
+
+template <typename PlainObjectType, int MapOptions, typename StrideType>
+struct is_tensor<Eigen::Map<PlainObjectType, MapOptions, StrideType>>
+    : public std::true_type {};
 
 template <typename T, size_t n>
 using is_tensor_n = std::is_base_of<akantu::TensorTrait<n>, T>;
 
 //   template <typename T> using is_vector = is_tensor_n<T, 1>;
 
 //   template <typename T> using is_matrix = is_tensor_n<T, 2>;
 
 template <std::size_t n, typename T = void, typename... Ts>
 using enable_if_tensors_n = std::enable_if<
     aka::conjunction<
         is_tensor_n<Ts, n>...,
         std::is_same<
             std::common_type_t<std::decay_t<typename Ts::value_type>...>,
             std::decay_t<typename Ts::value_type>>...>::value,
     T>;
 
 template <std::size_t n, typename T = void, typename... Ts>
 using enable_if_tensors_n_t = typename enable_if_tensors_n<n, T, Ts...>::type;
 
 //   template <typename T = void, typename... Ms>
 //   using enable_if_vectors_t = typename enable_if_tensors_n<1, T,
 //   Ms...>::type; template <typename T = void, typename... Ms>
 
 //   using enable_if_matricies_t = typename enable_if_tensors_n<2, T,
 //   Ms...>::type;
 } // namespace aka
 
 namespace akantu {
 template <typename T, std::size_t ndim> class TensorBase;
 template <typename T, size_t ndim> class TensorProxy;
 template <typename T, size_t ndim> class Tensor;
 } // namespace akantu
 
 #include "aka_view_iterators.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename T, std::size_t ndim>
 class TensorBase : public TensorTrait<ndim> {
   using RetType = TensorBase<T, ndim>;
   static_assert(ndim > 2, "TensorBase cannot by used for dimensions < 3");
 
 protected:
   using idx_t = std::size_t;
 
   template <typename... Args>
   using valid_args_t = typename std::enable_if<
       aka::conjunction<aka::disjunction<std::is_integral<Args>,
                                         std::is_enum<Args>>...>::value and
           ndim == sizeof...(Args),
       int>::type;
 
 public:
   using proxy = TensorBase<T, ndim>;
 
   template <size_t _ndim = ndim,
             std::enable_if_t<_ndim == 1 or _ndim == 2, int> = 0>
   TensorBase() {
     n.fill(0);
   }
 
   TensorBase() { n.fill(0); }
 
   template <typename... Args, valid_args_t<Args...> = 0>
   constexpr TensorBase(Args... args)
       : n{idx_t(args)...}, _size(detail::product_all(args...)) {}
 
   constexpr TensorBase(const TensorBase & other)
       : n(other.n), _size(other._size), values(other.values) {}
 
   constexpr TensorBase(TensorBase && other)
       : n(std::move(other.n)), _size(std::exchange(other._size, 0)),
         values(std::exchange(other.values, nullptr)) {}
 
 protected:
   template <typename Array, std::size_t... I>
   constexpr auto check_indices(const Array & idx,
                                std::index_sequence<I...>) const {
     bool result = true;
     (void)std::initializer_list<int>{(result &= idx[I] < n[I], 0)...};
     return result;
   }
 
   template <typename... Args> constexpr auto compute_index(Args... args) const {
     std::array<idx_t, sizeof...(Args)> idx{idx_t(args)...};
     AKANTU_DEBUG_ASSERT(
         check_indices(idx, std::make_index_sequence<sizeof...(Args)>{}),
         "The indexes are out of bound");
 
     idx_t index = 0, i = (sizeof...(Args)) - 1;
     for (; i > 0; i--) {
       index += idx[i];
       if (i > 0)
         index *= n[i - 1];
     }
     return index + idx[0];
   }
 
   template <typename S, std::size_t... I>
   constexpr auto get_slice(idx_t s, std::index_sequence<I...>) {
     return S(this->values + s * detail::product_all(n[I]...), n[I]...);
   }
 
   template <typename S, std::size_t... I>
   constexpr auto get_slice(idx_t s, std::index_sequence<I...>) const {
     return S(this->values + s * detail::product_all(n[I]...), n[I]...);
   }
 
 public:
   template <typename... Args, valid_args_t<Args...> = 0>
   inline T & operator()(Args... args) {
     return *(this->values + compute_index(std::move(args)...));
   }
 
   template <typename... Args, valid_args_t<Args...> = 0>
   inline const T & operator()(Args... args) const {
     return *(this->values + compute_index(std::move(args)...));
   }
 
   template <idx_t _ndim = ndim, std::enable_if_t<(_ndim > 3), int> = 0>
   inline auto operator()(idx_t s) {
     return get_slice<TensorProxy<T, ndim - 1>>(
         std::move(s), std::make_index_sequence<ndim - 1>());
   }
 
   template <idx_t _ndim = ndim, std::enable_if_t<(_ndim > 3), int> = 0>
   inline auto operator()(idx_t s) const {
     return get_slice<TensorProxy<T, ndim - 1>>(
         std::move(s), std::make_index_sequence<ndim - 1>());
   }
 
   template <idx_t _ndim = ndim, std::enable_if_t<_ndim == 3, int> = 0>
   inline auto operator()(idx_t s) {
     return get_slice<
         Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>>(
         std::move(s), std::make_index_sequence<ndim - 1>());
   }
 
   template <idx_t _ndim = ndim, std::enable_if_t<_ndim == 3, int> = 0>
   inline auto operator()(idx_t s) const {
     return get_slice<
         Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>>(
         std::move(s), std::make_index_sequence<ndim - 1>());
   }
 
 protected:
   template <class Operator> RetType & transform(Operator && op) {
     std::transform(this->values, this->values + this->_size, this->values,
                    std::forward<Operator>(op));
     return *(static_cast<RetType *>(this));
   }
 
   template <class Other, class Operator>
   RetType & transform(Other && other, Operator && op) {
     AKANTU_DEBUG_ASSERT(_size == other.size(),
                         "The two tensors do not have the same size "
                             << this->_size << " != " << other._size);
 
     std::transform(this->values, this->values + this->_size, other.values,
                    this->values, std::forward<Operator>(op));
     return *(static_cast<RetType *>(this));
   }
 
   template <class Operator> T accumulate(T init, Operator && op) {
     return std::accumulate(this->values, this->values + this->_size,
                            std::move(init), std::forward<Operator>(op));
   }
 
   template <class Other, class Init, class Accumulate, class Operator>
   T transform_reduce(Other && other, T init, Accumulate && acc,
                      Operator && op) {
     return std::inner_product(
         this->values, this->values + this->_size, other.data(), std::move(init),
         std::forward<Accumulate>(acc), std::forward<Operator>(op));
   }
 
   // arithmetic operators ------------------------------------------------------
   /* ------------------------------------------------------------------------ */
 public:
   inline decltype(auto) operator+=(const TensorBase & other) {
     return transform(other, [](auto && a, auto && b) { return a + b; });
   }
 
   /* ------------------------------------------------------------------------ */
   inline TensorBase & operator-=(const TensorBase & other) {
     return transform(other, [](auto && a, auto && b) { return a - b; });
   }
 
   /* ------------------------------------------------------------------------ */
   inline TensorBase & operator+=(const T & x) {
     return transform([&x](auto && a) { return a + x; });
   }
 
   /* ------------------------------------------------------------------------ */
   inline TensorBase & operator-=(const T & x) {
     return transform([&x](auto && a) { return a - x; });
   }
 
   /* ------------------------------------------------------------------------ */
   inline TensorBase & operator*=(const T & x) {
     return transform([&x](auto && a) { return a * x; });
   }
 
   /* ---------------------------------------------------------------------- */
   inline TensorBase & operator/=(const T & x) {
     return transform([&x](auto && a) { return a / x; });
   }
 
   /// Y = \alpha X + Y
   inline TensorBase & aXplusY(const TensorBase & other, const T alpha = 1.) {
     return transform(other,
                      [&alpha](auto && a, auto && b) { return alpha * a + b; });
   }
 
   /* ------------------------------------------------------------------------ */
 
   template <typename TO, std::size_t ndim_o, bool is_proxy_o>
   friend class TensorBase;
 
   T * data() { return values; }
   const T * data() const { return values; }
 
   // clang-format off
   [[deprecated("use data instead to be stl compatible")]]
   T * storage() {
     return values;
   }
 
   [[deprecated("use data instead to be stl compatible")]]
   const T * storage() const {
     return values;
   }
   // clang-format on
 
   auto size() const { return _size; }
   auto size(idx_t i) const {
     AKANTU_DEBUG_ASSERT(i < ndim, "This tensor has only " << ndim
                                                           << " dimensions, not "
                                                           << (i + 1));
     return n[i];
   };
 
   inline void set(const T & t) { std::fill_n(values, _size, t); };
   inline void clear() { set(T()); };
 
 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>
   auto norm() -> std::enable_if_t<norm_type == L_inf, T> const {
     return accumulate(
         T(), [](auto && init, auto && a) { return init + std::abs(a); });
   }
 
   template <NormType norm_type>
   auto norm() -> std::enable_if_t<norm_type == L_1, T> const {
     return accumulate(T(), [](auto && init, auto && a) {
       return std::max(init, std::abs(a));
     });
   }
 
   template <NormType norm_type>
   auto norm() -> std::enable_if_t<norm_type == L_2, T> const {
     return std::sqrt(
         accumulate(T(), [](auto && init, auto && a) { return init + a * a; }));
   }
 
   template <NormType norm_type>
   auto norm() -> std::enable_if_t<(norm_type > L_2), T> const {
     return std::pow(accumulate(T(),
                                [](auto && init, auto && a) {
                                  return init + std::pow(a, norm_type);
                                }),
                     1. / norm_type);
   }
 
   T norm() const { return norm<L_2>(); }
 
 protected:
   template <std::size_t N, typename... Args,
             std::enable_if_t<(sizeof...(Args) == ndim), int> = 0>
   void serialize(std::ostream & stream, Args... args) const {
     stream << this->operator()(std::move(args)...);
   }
 
   template <std::size_t N, typename... Args,
             std::enable_if_t<(sizeof...(Args) < ndim), int> = 0>
   void serialize(std::ostream & stream, Args... args) const {
     stream << "[";
     for (idx_t i = 0; i < n[N]; ++i) {
       if (i != 0)
         stream << ",";
       serialize<N + 1>(stream, std::move(args)..., i);
     }
     stream << "]";
   }
 
 public:
   void printself(std::ostream & stream) const { serialize<0>(stream); };
 
 protected:
   template <std::size_t... I>
   constexpr decltype(auto) begin(std::index_sequence<I...>) {
     return view_iterator<ViewIteratorHelper_t<sizeof...(I), T>>(values,
                                                                 n[I]...);
   }
 
   template <std::size_t... I>
   constexpr decltype(auto) end(std::index_sequence<I...>) {
     return view_iterator<ViewIteratorHelper_t<sizeof...(I), T>>(values + _size,
                                                                 n[I]...);
   }
 
 public:
   decltype(auto) begin() { return begin(std::make_index_sequence<ndim - 1>{}); }
   decltype(auto) end() { return end(std::make_index_sequence<ndim - 1>{}); }
 
 protected:
   // size per dimension
   std::array<idx_t, ndim> n;
 
   // total storage size
   idx_t _size{0};
 
   // actual data location
   T * values{nullptr};
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T, size_t ndim>
 class TensorProxy : public TensorBase<T, ndim> {
 private:
   using parent = TensorBase<T, ndim>;
 
 public:
   // proxy constructor
   template <typename... Args>
   constexpr TensorProxy(T * data, Args... args) : parent(args...) {
     this->values = data;
   }
 
   constexpr TensorProxy(const TensorProxy<T, ndim> & other) : parent(other) {
     this->values = other.values;
   }
 
   constexpr TensorProxy(const Tensor<T, ndim> & other) : parent(other) {
     this->values = other.values;
   }
 
   // move constructors ---------------------------------------------------------
   // proxy -> proxy
   TensorProxy(TensorProxy && other) : parent(other) {}
 
   TensorProxy & operator=(const TensorBase<T, ndim> & other) {
     AKANTU_DEBUG_ASSERT(
         other.size() == this->size(),
         "You are trying to copy too a tensors proxy with the wrong size "
             << this->_size << " != " << other._size);
 
     static_assert(std::is_trivially_copyable<T>{},
                   "Cannot copy a tensor on non trivial types");
 
     std::copy(other.values, other.values + this->_size, this->values);
     return *this;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T, size_t ndim> class Tensor : public TensorBase<T, ndim> {
 private:
   using parent = TensorBase<T, ndim>;
 
 public:
   template <typename... Args> constexpr Tensor(Args... args) : parent(args...) {
     static_assert(
         std::is_trivially_constructible<T>{},
         "Cannot create a tensor on non trivially constructible types");
     this->values = new T[this->_size];
   }
 
   /* ------------------------------------------------------------------------ */
   virtual ~Tensor() { delete[] this->values; }
 
   // copy constructors ---------------------------------------------------------
   constexpr Tensor(const Tensor & other) : parent(other) {
     this->values = new T[this->_size];
     std::copy(other.values, other.values + this->_size, this->values);
   }
 
   constexpr explicit Tensor(const TensorProxy<T, ndim> & other)
       : parent(other) {
     //    static_assert(false, "Copying data are you sure");
     this->values = new T[this->_size];
     std::copy(other.values, other.values + this->_size, this->values);
   }
 
   // move constructors ---------------------------------------------------------
   // proxy -> proxy, non proxy -> non proxy
   Tensor(Tensor && other) : parent(other) {}
 
   // copy operator -------------------------------------------------------------
   /// operator= copy-and-swap
   Tensor & operator=(const TensorBase<T, ndim> & other) {
     if (&other == this)
       return *this;
 
     std::cout << "Warning: operator= delete data" << std::endl;
     delete[] this->values;
     this->n = other.n;
     this->_size = other._size;
 
     static_assert(
         std::is_trivially_constructible<T>{},
         "Cannot create a tensor on non trivially constructible types");
 
     this->values = new T[this->_size];
 
     static_assert(std::is_trivially_copyable<T>{},
                   "Cannot copy a tensor on non trivial types");
 
     std::copy(other.values, other.values + this->_size, this->values);
 
     return *this;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T> using Tensor3 = Tensor<T, 3>;
 template <typename T> using Tensor3Proxy = TensorProxy<T, 3>;
 template <typename T> using Tensor3Base = TensorBase<T, 3>;
 
 class ArrayBase;
 
 /* -------------------------------------------------------------------------- */
 namespace details {
   template <typename T> struct MapPlainObjectType { using type = T; };
 
   template <typename PlainObjectType, int MapOptions, typename StrideType>
   struct MapPlainObjectType<
       Eigen::Map<PlainObjectType, MapOptions, StrideType>> {
     using type = PlainObjectType;
   };
 
   template <typename T>
   using MapPlainObjectType_t = typename MapPlainObjectType<T>::type;
 
   template <typename Scalar, Idx...> struct EigenMatrixViewHelper {};
 
   template <typename Scalar, Idx RowsAtCompileTime>
   struct EigenMatrixViewHelper<Scalar, RowsAtCompileTime> {
     using type = Eigen::Matrix<Scalar, RowsAtCompileTime, 1>;
   };
 
   template <typename Scalar, Idx RowsAtCompileTime, Idx ColsAtCompileTime>
   struct EigenMatrixViewHelper<Scalar, RowsAtCompileTime, ColsAtCompileTime> {
     using type = Eigen::Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime>;
   };
 
   template <typename Scalar, Idx... sizes>
   using EigenMatrixViewHelper_t =
       typename EigenMatrixViewHelper<Scalar, sizes...>::type;
 
   template <typename Array, Idx... sizes> class EigenView {
     static_assert(sizeof...(sizes) == 1 or sizeof...(sizes) == 2,
                   "Eigen only supports Vector and Matrices");
     using size_type = typename std::decay_t<Array>::size_type;
     using value_type = typename std::decay_t<Array>::value_type;
 
   public:
     EigenView(Array && array, decltype(sizes)... sizes_)
         : array(array), sizes_(sizes_...) {}
 
     EigenView(Array && array) : array(array), sizes_(sizes...) {}
 
     EigenView(const EigenView & other) = default;
     EigenView(EigenView && other) = default;
 
     template <typename T = std::remove_reference_t<
                   decltype(*std::declval<Array>().data())>,
               std::enable_if_t<not std::is_const<T>::value> * = nullptr>
     decltype(auto) begin() {
       return aka::make_from_tuple<::akantu::view_iterator<
           Eigen::Map<EigenMatrixViewHelper_t<value_type, sizes...>>>>(
           std::tuple_cat(std::make_tuple(array.get().data()), sizes_));
     }
 
     template <typename T = std::remove_reference_t<
                   decltype(*std::declval<Array>().data())>,
               std::enable_if_t<not std::is_const<T>::value> * = nullptr>
     decltype(auto) end() {
       return aka::make_from_tuple<::akantu::view_iterator<
           Eigen::Map<EigenMatrixViewHelper_t<value_type, sizes...>>>>(
           std::tuple_cat(std::make_tuple(array.get().data() + array_size()),
                          sizes_));
     }
 
     decltype(auto) begin() const {
       return aka::make_from_tuple<::akantu::view_iterator<
           Eigen::Map<const EigenMatrixViewHelper_t<value_type, sizes...>>>>(
           std::tuple_cat(std::make_tuple(array.get().data()), sizes_));
     }
     decltype(auto) end() const {
       return aka::make_from_tuple<::akantu::view_iterator<
           Eigen::Map<const EigenMatrixViewHelper_t<value_type, sizes...>>>>(
           std::tuple_cat(std::make_tuple(array.get().data() + array_size()),
                          sizes_));
     }
 
   private:
     template <
         class A = Array,
         std::enable_if_t<std::is_base_of<ArrayBase, std::decay_t<A>>::value> * =
             nullptr>
     size_type array_size() {
       return array.get().size() * array.get().getNbComponent();
     }
 
     template <class A = Array,
               std::enable_if_t<not std::is_base_of<
                   ArrayBase, std::decay_t<A>>::value> * = nullptr>
     size_type array_size() {
       return array.get().size();
     }
 
   private:
     std::reference_wrapper<std::remove_reference_t<Array>> array;
     std::tuple<decltype(sizes)...> sizes_;
   };
 
 } // namespace details
 
 template <Idx RowsAtCompileTime, typename Array>
 decltype(auto) make_view(Array && array) {
   return details::EigenView<Array, RowsAtCompileTime>(
       std::forward<Array>(array), RowsAtCompileTime);
 }
 
 template <Idx RowsAtCompileTime, Idx ColsAtCompileTime, typename Array>
 decltype(auto) make_view(Array && array) {
   return details::EigenView<Array, RowsAtCompileTime, ColsAtCompileTime>(
       std::forward<Array>(array), RowsAtCompileTime, ColsAtCompileTime);
 }
 
 } // namespace akantu
 
 namespace Eigen {
 /* -------------------------------------------------------------------------- */
 /* Vector                                                                     */
 /* -------------------------------------------------------------------------- */
 template <typename Derived>
 template <typename ED, typename T,
           std::enable_if_t<not std::is_const<T>::value and
                            ED::IsVectorAtCompileTime> *>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE decltype(auto)
 MatrixBase<Derived>::begin() {
   return ::akantu::view_iterator<typename Derived::Scalar>(
       this->derived().data());
 }
 
 template <typename Derived>
 template <typename ED, typename T,
           std::enable_if_t<not std::is_const<T>::value and
                            ED::IsVectorAtCompileTime> *>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE decltype(auto)
 MatrixBase<Derived>::end() {
   return ::akantu::view_iterator<typename Derived::Scalar>(
       this->derived().data() + this->size());
 }
 
 template <typename Derived>
 template <typename ED, std::enable_if_t<ED::IsVectorAtCompileTime> *>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE decltype(auto)
 MatrixBase<Derived>::begin() const {
   using Scalar = typename Derived::Scalar;
   return ::akantu::const_view_iterator<Scalar>(this->derived().data());
 }
 
 template <typename Derived>
 template <typename ED, std::enable_if_t<ED::IsVectorAtCompileTime> *>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE decltype(auto)
 MatrixBase<Derived>::end() const {
   using Scalar = typename Derived::Scalar;
   return ::akantu::const_view_iterator<Scalar>(this->derived().data() +
                                                this->size());
 }
 
 /* -------------------------------------------------------------------------- */
 /* Matrix                                                                     */
 /* -------------------------------------------------------------------------- */
 template <typename Derived>
 template <typename ED, typename T,
           std::enable_if_t<not std::is_const<T>::value and
                            not ED::IsVectorAtCompileTime> *>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE decltype(auto)
 MatrixBase<Derived>::begin() {
   return ::akantu::view_iterator<
       Map<Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, 1>>>(
       this->derived().data(), this->rows());
 }
 
 template <typename Derived>
 template <typename ED, typename T,
           std::enable_if_t<not std::is_const<T>::value and
                            not ED::IsVectorAtCompileTime> *>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE decltype(auto)
 MatrixBase<Derived>::end() {
   return ::akantu::view_iterator<
       Map<Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, 1>>>(
       this->derived().data() + this->size(), this->rows());
 }
 
 template <typename Derived>
 template <typename ED, std::enable_if_t<not ED::IsVectorAtCompileTime> *>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE decltype(auto)
 MatrixBase<Derived>::begin() const {
   using Scalar = typename Derived::Scalar;
   return ::akantu::const_view_iterator<
       Map<const Matrix<Scalar, Derived::RowsAtCompileTime, 1>>>(
       const_cast<Scalar *>(this->derived().data()), this->rows());
 }
 
 template <typename Derived>
 template <typename ED, std::enable_if_t<not ED::IsVectorAtCompileTime> *>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE decltype(auto)
 MatrixBase<Derived>::end() const {
   using Scalar = typename Derived::Scalar;
   return ::akantu::const_view_iterator<
       Map<const Matrix<Scalar, Derived::RowsAtCompileTime, 1>>>(
       const_cast<Scalar *>(this->derived().data()) + this->size(),
       this->rows());
 }
 
 template <typename Derived>
 template <typename OtherDerived>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void
 MatrixBase<Derived>::eig(MatrixBase<OtherDerived> & values) {
   EigenSolver<akantu::details::MapPlainObjectType_t<std::decay_t<Derived>>>
       solver(*this, false);
   values = solver.eigenvalues();
 }
 
 template <typename Derived>
 template <typename D1, typename D2>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void
 MatrixBase<Derived>::eig(MatrixBase<D1> & values, MatrixBase<D2> & vectors) {
   EigenSolver<akantu::details::MapPlainObjectType_t<std::decay_t<Derived>>>
       solver(*this, false);
   values = solver.eigenvalues();
   vectors = solver.eigenvectors();
 }
 
 template <typename Derived>
 template <typename OtherDerived>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void
 MatrixBase<Derived>::eigh(MatrixBase<OtherDerived> & values) {
   SelfAdjointEigenSolver<
       akantu::details::MapPlainObjectType_t<std::decay_t<Derived>>>
       solver(*this, false);
   values = solver.eigenvalues();
 }
 
 template <typename Derived>
 template <typename D1, typename D2>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void
 MatrixBase<Derived>::eigh(MatrixBase<D1> & values, MatrixBase<D2> & vectors) {
   SelfAdjointEigenSolver<
       akantu::details::MapPlainObjectType_t<std::decay_t<Derived>>>
       solver(*this, false);
   values = solver.eigenvalues();
   vectors = solver.eigenvectors();
 }
 
 } // namespace Eigen
 
 #endif /* AKANTU_AKA_TYPES_HH_ */
diff --git a/src/common/aka_view_iterators.hh b/src/common/aka_view_iterators.hh
index 94bbeb2ba..9c3c4c6f0 100644
--- a/src/common/aka_view_iterators.hh
+++ b/src/common/aka_view_iterators.hh
@@ -1,515 +1,558 @@
 /**
  * @file   aka_view_iterators.hh
  *
  * @author Nicolas Richart
  *
  * @date creation  Thu Nov 15 2018
  *
  * @brief View iterators
  *
  * @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_types.hh"
+//#include "aka_types.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_VIEW_ITERATORS_HH__
 #define __AKANTU_AKA_VIEW_ITERATORS_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Iterators                                                                  */
 /* -------------------------------------------------------------------------- */
 namespace detail {
   template <class R> struct IteratorHelper { static constexpr Int dim = 0; };
 
   template <class Derived> struct IteratorHelper<Eigen::MatrixBase<Derived>> {
   private:
     using T = typename Derived::Scalar;
     static constexpr Int m = Derived::RowsAtCompileTime;
     static constexpr Int n = Derived::ColsAtCompileTime;
 
   public:
     static constexpr Int dim =
         Eigen::MatrixBase<Derived>::IsVectorAtCompileTime ? 1 : 2;
     using pointer = T *;
     using proxy = Eigen::Map<Eigen::Matrix<T, m, n>>;
     using const_proxy = Eigen::Map<const Eigen::Matrix<T, m, n>>;
   };
 
   template <class Derived> struct IteratorHelper<Eigen::Map<Derived>> {
   private:
     using T = typename Derived::Scalar;
     static constexpr Int m = Derived::RowsAtCompileTime;
     static constexpr Int n = Derived::ColsAtCompileTime;
 
   public:
     static constexpr Int dim =
         Derived::IsVectorAtCompileTime and m != 1 ? 1 : 2;
     using pointer = T *;
     using proxy = Eigen::Map<Derived>;
     using const_proxy = Eigen::Map<const Derived>;
   };
 
   template <typename T, std::size_t _dim>
   struct IteratorHelper<Tensor<T, _dim>> {
     static constexpr Int dim = _dim;
     using pointer = T *;
     using proxy = TensorProxy<T, _dim>;
     using const_proxy = TensorProxy<const T, _dim>;
   };
 
   template <typename T, std::size_t _dim>
   struct IteratorHelper<TensorProxy<T, _dim>> {
     static constexpr Int dim = _dim;
     using pointer = T *;
     using proxy = TensorProxy<T, _dim>;
     using const_proxy = TensorProxy<const T, _dim>;
   };
 
   /* --------------------------------------------------------------------------
    */
   template <class R, class daughter, class IR = R,
             Int dim = IteratorHelper<std::decay_t<R>>::dim>
   class internal_view_iterator {
   protected:
     using helper = IteratorHelper<std::decay_t<R>>;
     using internal_value_type = IR;
     using internal_pointer = IR *;
     using scalar_pointer = typename helper::pointer;
     using proxy_t = typename helper::proxy;
     using const_proxy_t = typename helper::const_proxy;
 
   public:
     using pointer = proxy_t *;
     using value_type = proxy_t;
     using reference = proxy_t &;
     using const_reference = const_proxy_t &;
     using difference_type = Int;
     using iterator_category = std::random_access_iterator_tag;
 
   private:
     template <std::size_t... I>
     constexpr auto get_new_const_proxy(scalar_pointer data,
                                        std::index_sequence<I...>) const {
       return const_proxy_t(data, dims[I]...);
     }
 
     constexpr auto get_new_const_proxy(scalar_pointer data) const {
       return get_new_const_proxy(data, std::make_index_sequence<dim>());
     }
     template <std::size_t... I>
     constexpr auto get_new_proxy(scalar_pointer data,
                                  std::index_sequence<I...>) {
       return proxy_t(data, dims[I]...);
     }
 
     constexpr auto get_new_proxy(scalar_pointer data) {
       return get_new_proxy(data, std::make_index_sequence<dim>());
     }
 
     template <typename T, std::size_t... I>
     constexpr void reset_proxy(T & t, scalar_pointer data,
                                std::index_sequence<I...>) const {
       new (&t) T(data, dims[I]...);
     }
 
     template <typename T> constexpr auto reset_proxy(T & t) const {
       return reset_proxy(t, this->ret_ptr, std::make_index_sequence<dim>());
     }
 
   protected:
     template <typename OR, typename OD, typename OIR,
               std::enable_if_t<std::is_convertible<
                   decltype(std::declval<OIR>().data()),
                   decltype(std::declval<IR>().data())>::value> * = nullptr>
     explicit internal_view_iterator(
         internal_view_iterator<OR, OD, OIR, dim> & it)
         : dims(it.dims), _offset(it._offset), initial(it.initial),
           ret_ptr(it.ret_ptr), proxy(get_new_proxy(it.ret_ptr)),
           const_proxy(get_new_const_proxy(it.ret_ptr)) {}
 
     template <typename OR, typename OD, typename OIR, Int _dim>
     friend class internal_view_iterator;
 
     template <typename... Args>
     using valid_args_t = std::enable_if_t<
         aka::conjunction<aka::disjunction<std::is_integral<Args>,
                                           std::is_enum<Args>>...>::value and
             dim == sizeof...(Args),
         int>;
 
   public:
     template <typename... Ns, valid_args_t<Ns...> = 0>
     internal_view_iterator(scalar_pointer data, Ns... ns)
         : dims({Int(ns)...}),
           _offset(detail::product_all(std::forward<Ns>(ns)...)), initial(data),
           ret_ptr(data), proxy(data, ns...), const_proxy(data, ns...) {}
 
     // Static 1x1 matrix cannot be differenciated from vector in eigen
     template <typename RD = std::decay_t<R>,
               std::enable_if_t<RD::RowsAtCompileTime == 1 and
                                RD::ColsAtCompileTime == 1> * = nullptr>
-    internal_view_iterator(scalar_pointer data, Idx rows)
+    constexpr internal_view_iterator(scalar_pointer data, Idx rows)
         : dims({rows, 1}), _offset(rows), initial(data), ret_ptr(data),
-          proxy(data, rows, 1), const_proxy(data, rows, 1) {}
+          proxy(data, rows, 1), const_proxy(data, rows, 1) {
+      AKANTU_DEBUG_ASSERT(rows == 1, "1x1 Matrix");
+    }
+
+    // Static matrix again hard to distinguish from vectors
+    template <typename RD = std::decay_t<R>,
+              std::enable_if_t<(RD::RowsAtCompileTime > 1) and
+                               RD::ColsAtCompileTime == 1> * = nullptr>
+    constexpr internal_view_iterator(scalar_pointer data, Idx rows, Idx cols)
+        : dims({rows}), _offset(rows), initial(data), ret_ptr(data),
+          proxy(data, rows, 1), const_proxy(data, rows, 1) {
+      AKANTU_DEBUG_ASSERT(cols == 1, "nx1 Matrix");
+    }
 
     template <Int _dim = dim, std::enable_if_t<_dim == 1> * = nullptr>
     internal_view_iterator() : proxy(nullptr, 0), const_proxy(nullptr, 0) {}
 
     template <Int _dim = dim, std::enable_if_t<_dim == 2> * = nullptr>
     internal_view_iterator()
         : proxy(nullptr, 0, 0), const_proxy(nullptr, 0, 0) {}
 
     internal_view_iterator(const internal_view_iterator & it)
         : proxy(get_new_proxy(it.ret_ptr)),
           const_proxy(get_new_const_proxy(it.ret_ptr)) {
       if (this != &it) {
         this->dims = it.dims;
         this->_offset = it._offset;
         this->initial = it.initial;
         this->ret_ptr = it.ret_ptr;
       }
     }
 
     internal_view_iterator(internal_view_iterator && it) = default;
 
     virtual ~internal_view_iterator() = default;
 
+    template <typename OR, typename OD, typename OIR,
+              std::enable_if_t<std::is_convertible<
+                  decltype(std::declval<OIR>().data()),
+                  decltype(std::declval<IR>().data())>::value> * = nullptr>
+    inline internal_view_iterator &
+    operator=(const internal_view_iterator<OR, OD, OIR, dim> & it) {
+      this->_offset = it._offset;
+      this->initial = it.initial;
+      this->ret_ptr = it.ret_ptr;
+      reset_proxy(this->proxy);
+      reset_proxy(this->const_proxy);
+      return *this;
+    }
+
     inline internal_view_iterator &
     operator=(const internal_view_iterator & it) {
       if (this != &it) {
         this->_offset = it._offset;
         this->initial = it.initial;
         this->ret_ptr = it.ret_ptr;
         reset_proxy(this->proxy);
         reset_proxy(this->const_proxy);
       }
       return *this;
     }
 
   public:
     UInt getCurrentIndex() {
       return (this->ret_ptr - this->initial) / this->_offset;
     }
 
     inline reference operator*() {
       reset_proxy(proxy);
       return proxy;
     }
 
     inline const_reference operator*() const {
       reset_proxy(const_proxy);
       return proxy;
     }
 
     inline pointer operator->() {
       reset_proxy(proxy);
       return &proxy;
     }
 
     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+=(UInt n) {
       ret_ptr += _offset * n;
       return static_cast<daughter &>(*this);
     }
 
     inline daughter & operator-=(UInt n) {
       ret_ptr -= _offset * n;
       return static_cast<daughter &>(*this);
     }
 
     inline auto operator[](UInt n) {
       return get_new_proxy(ret_ptr + n * _offset);
     }
 
     inline auto operator[](UInt n) const {
       return get_new_const_proxy(ret_ptr + n * _offset);
     }
 
     inline bool operator==(const internal_view_iterator & other) const {
       return this->ret_ptr == other.ret_ptr;
     }
 
     inline bool operator!=(const internal_view_iterator & other) const {
       return this->ret_ptr != other.ret_ptr;
     }
 
     inline bool operator<(const internal_view_iterator & other) const {
       return this->ret_ptr < other.ret_ptr;
     }
 
     inline bool operator<=(const internal_view_iterator & other) const {
       return this->ret_ptr <= other.ret_ptr;
     }
 
     inline bool operator>(const internal_view_iterator & other) const {
       return this->ret_ptr > other.ret_ptr;
     }
 
     inline bool operator>=(const internal_view_iterator & 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 internal_view_iterator & b) {
       return (this->ret_ptr - b.ret_ptr) / _offset;
     }
 
     inline scalar_pointer data() const { return ret_ptr; }
     inline difference_type offset() const { return _offset; }
+    inline decltype(auto) getDims() const { return dims; }
 
   protected:
     std::array<Int, dim> dims;
     difference_type _offset{0};
     scalar_pointer initial{nullptr};
     scalar_pointer ret_ptr{nullptr};
     proxy_t proxy;
     const_proxy_t const_proxy;
   };
 
   /* ------------------------------------------------------------------------ */
   /**
    * Specialization for scalar types
    */
   template <class R, class daughter, class IR>
   class internal_view_iterator<R, daughter, IR, 0> {
   public:
     using value_type = R;
     using pointer = R *;
     using reference = R &;
     using const_reference = const R &;
     using difference_type = std::ptrdiff_t;
     using iterator_category = std::random_access_iterator_tag;
 
   protected:
     using internal_value_type = IR;
     using internal_pointer = IR *;
 
   public:
     internal_view_iterator(pointer data = nullptr) : ret(data), initial(data){};
     internal_view_iterator(const internal_view_iterator & it) = default;
     internal_view_iterator(internal_view_iterator && it) = default;
 
     virtual ~internal_view_iterator() = default;
 
     inline internal_view_iterator &
     operator=(const internal_view_iterator & 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 internal_view_iterator & other) const {
       return ret == other.ret;
     }
     inline bool operator!=(const internal_view_iterator & other) const {
       return ret != other.ret;
     }
     inline bool operator<(const internal_view_iterator & other) const {
       return ret < other.ret;
     }
     inline bool operator<=(const internal_view_iterator & other) const {
       return ret <= other.ret;
     }
     inline bool operator>(const internal_view_iterator & other) const {
       return ret > other.ret;
     }
     inline bool operator>=(const internal_view_iterator & 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 internal_view_iterator & b) {
       return ret - b.ret;
     }
 
     inline pointer data() const { return ret; }
 
   protected:
     pointer ret{nullptr};
     pointer initial{nullptr};
   };
 } // namespace detail
 
 /* -------------------------------------------------------------------------- */
 template <typename R> class view_iterator;
 
 template <typename R>
 class const_view_iterator
     : public detail::internal_view_iterator<const R, const_view_iterator<R>,
                                             R> {
 public:
   using parent =
       detail::internal_view_iterator<const R, const_view_iterator, R>;
   using value_type = typename parent::value_type;
   using pointer = typename parent::pointer;
   using reference = typename parent::reference;
   using difference_type = typename parent::difference_type;
   using iterator_category = typename parent::iterator_category;
 
 public:
   const_view_iterator() : parent(){};
   const_view_iterator(const const_view_iterator & it) = default;
   const_view_iterator(const_view_iterator && it) = default;
 
   template <typename P, typename... Ns>
   const_view_iterator(P * data, Ns... ns) : parent(data, ns...) {}
 
   const_view_iterator & operator=(const const_view_iterator & it) = default;
 
   template <typename OR,
             std::enable_if_t<not std::is_same<R, OR>::value> * = nullptr>
   const_view_iterator(const_view_iterator<OR> & it) : parent(it) {}
+
+  template <typename OR,
+            std::enable_if_t<not std::is_same<R, OR>::value> * = nullptr>
+  const_view_iterator & operator=(const const_view_iterator<OR> & it) {
+    return dynamic_cast<const_view_iterator &>(parent::operator=(it));
+  }
 };
 
 template <class R, bool is_tensor_ = aka::is_tensor<R>::value>
 struct ConstConverterIteratorHelper {
+protected:
+  template <std::size_t... I>
+  static inline auto convert_helper(const view_iterator<R> & it,
+                                    std::index_sequence<I...>) {
+    return const_view_iterator<R>(it.data(), it.getDims()[I]...);
+  }
+
+public:
   static inline auto convert(const view_iterator<R> & it) {
-    return const_view_iterator<R>(std::unique_ptr<R>(new R(*it, false)));
+    return convert_helper(
+        it, std::make_index_sequence<
+                std::tuple_size<decltype(it.getDims())>::value>());
   }
 };
 
 template <class R> struct ConstConverterIteratorHelper<R, false> {
   static inline auto convert(const view_iterator<R> & it) {
     return const_view_iterator<R>(it.data());
   }
 };
 
 template <typename R>
 class view_iterator
     : public detail::internal_view_iterator<R, view_iterator<R>> {
 public:
   using parent = detail::internal_view_iterator<R, view_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:
   view_iterator() : parent(){};
   view_iterator(const view_iterator & it) = default;
   view_iterator(view_iterator && it) = default;
 
   template <typename P, typename... Ns>
   view_iterator(P * data, Ns... ns) : parent(data, ns...) {}
 
   view_iterator & operator=(const view_iterator & it) = default;
 
   operator const_view_iterator<R>() {
     return ConstConverterIteratorHelper<R>::convert(*this);
   }
 };
 
 namespace {
   template <std::size_t dim, typename T> struct ViewIteratorHelper {
     using type = TensorProxy<T, dim>;
   };
 
   template <typename T> struct ViewIteratorHelper<0, T> { using type = T; };
   template <typename T> struct ViewIteratorHelper<1, T> {
     using type = Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1>>;
   };
   template <typename T> struct ViewIteratorHelper<1, const T> {
     using type = Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, 1>>;
   };
 
   template <typename T> struct ViewIteratorHelper<2, T> {
     using type = Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>;
   };
 
   template <typename T> struct ViewIteratorHelper<2, const T> {
     using type =
         Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>;
   };
 
   template <std::size_t dim, typename T>
   using ViewIteratorHelper_t = typename ViewIteratorHelper<dim, T>::type;
 } // namespace
 
 // #include <iterator>
 
 // namespace std {
 // template <typename R>
 // struct iterator_traits<::akantu::types::details::vector_iterator<R>> {
 // protected:
 //   using iterator = ::akantu::types::details::vector_iterator<R>;
 
 // public:
 //   using iterator_category = typename iterator::iterator_category;
 //   using value_type = typename iterator::value_type;
 //   using difference_type = typename iterator::difference_type;
 //   using pointer = typename iterator::pointer;
 //   using reference = typename iterator::reference;
 // };
 // } // namespace std
 
 } // namespace akantu
 
 #endif /* !__AKANTU_AKA_VIEW_ITERATORS_HH__ */
diff --git a/src/common/aka_voigthelper.hh b/src/common/aka_voigthelper.hh
index c0bd499be..3ec994b2a 100644
--- a/src/common/aka_voigthelper.hh
+++ b/src/common/aka_voigthelper.hh
@@ -1,103 +1,103 @@
 /**
  * @file   aka_voigthelper.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Till Junge <till.junge@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 20 2013
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  Helper file for Voigt notation
  * Wikipedia convention: @f[2*\epsilon_{ij} (i!=j) = voigt_\epsilon_{I}@f]
  * http://en.wikipedia.org/wiki/Voigt_notation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 AKA_VOIGTHELPER_HH_
 #define AKA_VOIGTHELPER_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> class VoigtHelper {
+template <Int dim> class VoigtHelper {
   static_assert(dim > 0U, "Cannot be < 1D");
   static_assert(dim < 4U, "Cannot be > 3D");
 
 public:
   /* ------------------------------------------------------------------------ */
   template <class M, class V>
   static inline void matrixToVoigt(M && matrix, V && vector);
 
   template <class M> static inline decltype(auto) matrixToVoigt(M && matrix);
 
   template <class M, class V>
   static inline void matrixToVoigtWithFactors(M && matrix, V && vector);
 
   template <class M>
   static inline decltype(auto) matrixToVoigtWithFactors(M && matrix);
 
   template <class M, class V>
   static inline void voigtToMatrix(V && vector, M && matrix);
 
   template <class V> static inline decltype(auto) voigtToMatrix(V && vector);
   /* ------------------------------------------------------------------------ */
 
   /// transfer the B matrix to a Voigt notation B matrix
   inline static void transferBMatrixToSymVoigtBMatrix(
       const Matrix<Real> & B, Matrix<Real> & Bvoigt, UInt nb_nodes_per_element);
 
   /// transfer the BNL matrix to a Voigt notation B matrix (See Bathe et al.
   /// IJNME vol 9, 1975)
   inline static void transferBMatrixToBNL(const Matrix<Real> & B,
                                           Matrix<Real> & Bvoigt,
                                           UInt nb_nodes_per_element);
 
   /// transfer the BL2 matrix to a Voigt notation B matrix (See Bathe et al.
   /// IJNME vol 9, 1975)
   inline static void transferBMatrixToBL2(const Matrix<Real> & B,
                                           const Matrix<Real> & grad_u,
                                           Matrix<Real> & Bvoigt,
                                           UInt nb_nodes_per_element);
 
 public:
   static constexpr UInt size{(dim * (dim - 1)) / 2 + dim};
   // matrix of vector index I as function of tensor indices i,j
   static const UInt mat[dim][dim];
   // array of matrix indices ij as function of vector index I
   static const UInt vec[dim * dim][2];
   // factors to multiply the strain by for voigt notation
   static const Real factors[size];
 };
 
 } // namespace akantu
 
 #include "aka_voigthelper_tmpl.hh"
 
 #endif
diff --git a/src/common/aka_voigthelper_tmpl.hh b/src/common/aka_voigthelper_tmpl.hh
index 2ba35a305..f390439a3 100644
--- a/src/common/aka_voigthelper_tmpl.hh
+++ b/src/common/aka_voigthelper_tmpl.hh
@@ -1,243 +1,243 @@
 /**
  * @file   aka_voigthelper_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 20 2013
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  implementation of the voight helper
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_voigthelper.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_AKA_VOIGTHELPER_TMPL_HH_
 #define AKANTU_AKA_VOIGTHELPER_TMPL_HH_
 
 namespace akantu {
 
-template <UInt dim> constexpr UInt VoigtHelper<dim>::size;
+template <Int dim> constexpr UInt VoigtHelper<dim>::size;
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class M, class V>
 inline void VoigtHelper<dim>::matrixToVoigt(M && matrix, V && vector) {
   for (UInt I = 0; I < size; ++I) {
     auto i = vec[I][0];
     auto j = vec[I][1];
     vector(I) = matrix(i, j);
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class M>
 inline decltype(auto) VoigtHelper<dim>::matrixToVoigt(M && matrix) {
   Vector<Real> vector(size);
   matrixToVoigt(std::forward<M>(matrix), vector);
   return vector;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class M, class V>
 inline void VoigtHelper<dim>::matrixToVoigtWithFactors(M && matrix,
                                                        V && vector) {
   for (UInt I = 0; I < size; ++I) {
     auto i = vec[I][0];
     auto j = vec[I][1];
     vector(I) = factors[I] * matrix(i, j);
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class M>
 inline decltype(auto) VoigtHelper<dim>::matrixToVoigtWithFactors(M && matrix) {
   Vector<Real> vector(size);
   matrixToVoigtWithFactors(std::forward<M>(matrix), vector);
   return vector;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class M, class V>
 inline void VoigtHelper<dim>::voigtToMatrix(V && vector, M && matrix) {
   for (UInt I = 0; I < size; ++I) {
     auto i = vec[I][0];
     auto j = vec[I][1];
     matrix(i, j) = matrix(j, i) = vector(I);
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class V>
 inline decltype(auto) VoigtHelper<dim>::voigtToMatrix(V && vector) {
   Matrix<Real> matrix(dim, dim);
   voigtToMatrix(std::forward<V>(vector), matrix);
   return matrix;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
     const Matrix<Real> & B, Matrix<Real> & Bvoigt, UInt nb_nodes_per_element) {
   Bvoigt.zero();
 
   for (UInt i = 0; i < dim; ++i) {
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       Bvoigt(i, i + n * dim) = B(i, n);
     }
   }
 
   if (dim == 2) {
     /// in 2D, fill the @f$ [\frac{\partial N_i}{\partial x}, \frac{\partial
     /// N_i}{\partial y}]@f$ row
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       Bvoigt(2, 1 + n * 2) = B(0, n);
       Bvoigt(2, 0 + n * 2) = B(1, n);
     }
   }
 
   if (dim == 3) {
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       Real dndx = B(0, n);
       Real dndy = B(1, n);
       Real dndz = B(2, n);
 
       /// in 3D, fill the @f$ [0, \frac{\partial N_i}{\partial y},
       /// \frac{N_i}{\partial z}]@f$ row
       Bvoigt(3, 1 + n * 3) = dndz;
       Bvoigt(3, 2 + n * 3) = dndy;
 
       /// in 3D, fill the @f$ [\frac{\partial N_i}{\partial x}, 0,
       /// \frac{N_i}{\partial z}]@f$ row
       Bvoigt(4, 0 + n * 3) = dndz;
       Bvoigt(4, 2 + n * 3) = dndx;
 
       /// in 3D, fill the @f$ [\frac{\partial N_i}{\partial x},
       /// \frac{N_i}{\partial y}, 0]@f$ row
       Bvoigt(5, 0 + n * 3) = dndy;
       Bvoigt(5, 1 + n * 3) = dndx;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void VoigtHelper<dim>::transferBMatrixToBNL(const Matrix<Real> & B,
                                                    Matrix<Real> & Bvoigt,
                                                    UInt nb_nodes_per_element) {
   Bvoigt.zero();
 
   // see Finite element formulations for large deformation dynamic analysis,
   // Bathe et al. IJNME vol 9, 1975, page 364 B_{NL}
   for (UInt i = 0; i < dim; ++i) {
     for (UInt m = 0; m < nb_nodes_per_element; ++m) {
       for (UInt n = 0; n < dim; ++n) {
         // std::cout << B(n, m) << std::endl;
         Bvoigt(i * dim + n, m * dim + i) = B(n, m);
       }
     }
   }
   // TODO: Verify the 2D and 1D case
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void VoigtHelper<1>::transferBMatrixToBL2(const Matrix<Real> & B,
                                                  const Matrix<Real> & grad_u,
                                                  Matrix<Real> & Bvoigt,
                                                  UInt nb_nodes_per_element) {
   Bvoigt.zero();
   for (UInt j = 0; j < nb_nodes_per_element; ++j) {
     Bvoigt(0, j) = grad_u(0, 0) * B(0, j);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void VoigtHelper<3>::transferBMatrixToBL2(const Matrix<Real> & dNdX,
                                                  const Matrix<Real> & grad_u,
                                                  Matrix<Real> & Bvoigt,
                                                  UInt nb_nodes_per_element) {
   Bvoigt.zero();
 
   for (UInt I = 0; I < 3; ++I) {
     for (UInt a = 0; a < nb_nodes_per_element; ++a) {
       for (UInt i = 0; i < 3; ++i) {
         Bvoigt(I, a * 3 + i) = grad_u(i, I) * dNdX(I, a);
       }
     }
   }
 
   for (UInt Iv = 3; Iv < 6; ++Iv) {
     for (UInt a = 0; a < nb_nodes_per_element; ++a) {
       for (UInt k = 0; k < 3; ++k) {
         UInt aux = Iv - 3;
         for (UInt m = 0; m < 3; ++m) {
           if (m != aux) {
             UInt index1 = m;
             UInt index2 = 3 - m - aux;
             Bvoigt(Iv, a * 3 + k) += grad_u(k, index1) * dNdX(index2, a);
           }
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void VoigtHelper<2>::transferBMatrixToBL2(const Matrix<Real> & B,
                                                  const Matrix<Real> & grad_u,
                                                  Matrix<Real> & Bvoigt,
                                                  UInt nb_nodes_per_element) {
 
   Bvoigt.zero();
 
   for (UInt i = 0; i < 2; ++i) {
     for (UInt j = 0; j < nb_nodes_per_element; ++j) {
       for (UInt k = 0; k < 2; ++k) {
         Bvoigt(i, j * 2 + k) = grad_u(k, i) * B(i, j);
       }
     }
   }
 
   for (UInt j = 0; j < nb_nodes_per_element; ++j) {
     for (UInt k = 0; k < 2; ++k) {
       for (UInt m = 0; m < 2; ++m) {
         UInt index1 = m;
         UInt index2 = (2 - 1) - m;
         Bvoigt(2, j * 2 + k) += grad_u(k, index1) * B(index2, j);
       }
     }
   }
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_AKA_VOIGTHELPER_TMPL_HH_ */
diff --git a/src/fe_engine/element.hh b/src/fe_engine/element.hh
index 3c5b29168..0c1975355 100644
--- a/src/fe_engine/element.hh
+++ b/src/fe_engine/element.hh
@@ -1,129 +1,129 @@
 /**
  * @file   element.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  Element helper class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_ELEMENT_HH_
 #define AKANTU_ELEMENT_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Element                                                                    */
 /* -------------------------------------------------------------------------- */
 class Element {
 public:
   ElementType type;
-  UInt element;
+  Idx element;
   GhostType ghost_type;
 
   // ElementKind kind;
   // ElementType type{_not_defined};
   // UInt element{0};
   // GhostType ghost_type{_not_ghost};
   // ElementKind kind{_ek_regular};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   inline ElementKind kind() const;
 
   inline bool operator==(const Element & elem) const {
     return std::tie(type, element, ghost_type) ==
            std::tie(elem.type, elem.element, elem.ghost_type);
   }
 
   inline bool operator!=(const Element & elem) const {
     return std::tie(type, element, ghost_type) !=
            std::tie(elem.type, elem.element, elem.ghost_type);
   }
 
   // inline bool operator==(const Element & elem) const {
   //   return ((element == elem.element) && (type == elem.type) &&
   //           (ghost_type == elem.ghost_type) && (kind == elem.kind));
   // }
 
   // inline bool operator!=(const Element & elem) const {
   //   return ((element != elem.element) || (type != elem.type) ||
   //           (ghost_type != elem.ghost_type) || (kind != elem.kind));
   // }
 
   inline bool operator<(const Element & rhs) const;
 };
 
 namespace {
-  const Element ElementNull{_not_defined, UInt(-1), _casper};
+  const Element ElementNull{_not_defined, Idx(-1), _casper};
   //      Element{_not_defined, 0, _casper, _ek_not_defined};
 } // namespace
 
 /* -------------------------------------------------------------------------- */
 inline bool Element::operator<(const Element & rhs) const {
   // bool res =
   //     (rhs == ElementNull) ||
   //     ((this->kind < rhs.kind) ||
   //      ((this->kind == rhs.kind) &&
   //       ((this->ghost_type < rhs.ghost_type) ||
   //        ((this->ghost_type == rhs.ghost_type) &&
   //         ((this->type < rhs.type) ||
   //          ((this->type == rhs.type) && (this->element < rhs.element)))))));
   return ((rhs == ElementNull) ||
           std::tie(ghost_type, type, element) <
               std::tie(rhs.ghost_type, rhs.type, rhs.element));
 }
 
 } // namespace akantu
 
 namespace std {
 inline string to_string(const akantu::Element & _this) {
   if (_this == akantu::ElementNull) {
     return "ElementNull";
   }
 
   string str = "Element [" + to_string(_this.type) + ", " +
                to_string(_this.element) + ", " + to_string(_this.ghost_type) +
                "]";
   return str;
 }
 } // namespace std
 
 namespace akantu {
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream, const Element & _this) {
   stream << std::to_string(_this);
   return stream;
 }
 } // namespace akantu
 
 #endif /* AKANTU_ELEMENT_HH_ */
diff --git a/src/fe_engine/element_class.hh b/src/fe_engine/element_class.hh
index f7c27d531..c32a08992 100644
--- a/src/fe_engine/element_class.hh
+++ b/src/fe_engine/element_class.hh
@@ -1,466 +1,465 @@
 /**
  * @file   element_class.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Dec 11 2020
  *
  * @brief  Declaration of the ElementClass main class and the
  * Integration and Interpolation elements
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 Int spatial_dimension{0};
   static const GaussIntegrationType gauss_integration_type{_git_not_defined};
-  static const UInt polynomial_degree{0};
+  static const Int polynomial_degree{0};
 };
 
 #if !defined(DOXYGEN)
 /// 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 Int spatial_dimension{sp};                                    \
     static const GaussIntegrationType gauss_integration_type{gauss_int_type};  \
-    static const UInt polynomial_degree{min_int_order};                        \
+    static const Int polynomial_degree{min_int_order};                         \
   }
 #else
 #define AKANTU_DEFINE_ELEMENT_CLASS_PROPERTY(elem_type, geom_type,             \
                                              interp_type, elem_kind, sp,       \
                                              gauss_int_type, min_int_order)
 #endif
 
 /* -------------------------------------------------------------------------- */
 /* 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 coord
   template <class D>
   static inline bool contains(const Eigen::MatrixBase<D> & coord);
 };
 
 #if !defined(DOXYGEN)
 /// Macro to generate the GeometricalShape structures for different geometrical
 /// types
 #define AKANTU_DEFINE_SHAPE(geom_type, geom_shape)                             \
   template <> struct GeometricalShape<geom_type> {                             \
     static const GeometricalShapeType shape{geom_shape};                       \
   }
 
 AKANTU_DEFINE_SHAPE(_gt_hexahedron_20, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_hexahedron_8, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_pentahedron_15, _gst_prism);
 AKANTU_DEFINE_SHAPE(_gt_pentahedron_6, _gst_prism);
 AKANTU_DEFINE_SHAPE(_gt_point, _gst_point);
 AKANTU_DEFINE_SHAPE(_gt_quadrangle_4, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_quadrangle_8, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_segment_2, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_segment_3, _gst_square);
 AKANTU_DEFINE_SHAPE(_gt_tetrahedron_10, _gst_triangle);
 AKANTU_DEFINE_SHAPE(_gt_tetrahedron_4, _gst_triangle);
 AKANTU_DEFINE_SHAPE(_gt_triangle_3, _gst_triangle);
 AKANTU_DEFINE_SHAPE(_gt_triangle_6, _gst_triangle);
 #endif
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type>
 struct GeometricalElementProperty {};
 
 template <ElementType element_type>
 struct ElementClassExtraGeometryProperties {};
 
 /* -------------------------------------------------------------------------- */
 /// Templated GeometricalElement with function getInradius
 template <GeometricalType geometrical_type,
           GeometricalShapeType shape =
               GeometricalShape<geometrical_type>::shape>
 class GeometricalElement {
   using geometrical_property = GeometricalElementProperty<geometrical_type>;
 
 public:
   /// compute the in-radius: \todo should be renamed for characteristic length
   template <class D>
   static inline Real getInradius(const Eigen::MatrixBase<D> & /*X*/) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the normal to the element
   template <class D1, class D2>
   static inline void getNormal(const Eigen::MatrixBase<D1> & /*X*/,
-                               Eigen::MatrixBase<D2> &/*n*/) {
+                               Eigen::MatrixBase<D2> & /*n*/) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// true if the natural coordinates are in the element
   template <class D>
   static inline bool contains(const Eigen::MatrixBase<D> & coord);
 
 public:
-  static AKANTU_GET_MACRO_NOT_CONST(SpatialDimension,
-                                    geometrical_property::spatial_dimension,
-                                    UInt);
-  static AKANTU_GET_MACRO_NOT_CONST(NbNodesPerElement,
-                                    geometrical_property::nb_nodes_per_element,
-                                    UInt);
+  static constexpr auto getSpatialDimension() {
+    return geometrical_property::spatial_dimension;
+  }
+  static constexpr auto getNbNodesPerElement() {
+    return geometrical_property::nb_nodes_per_element;
+  }
   static inline constexpr auto getNbFacetTypes() {
     return geometrical_property::nb_facet_types;
   };
-  static inline constexpr UInt getNbFacetsPerElement(UInt t);
-  static inline constexpr UInt getNbFacetsPerElement();
+  static inline constexpr Int getNbFacetsPerElement(Idx t);
+  static inline constexpr Int getNbFacetsPerElement();
   static inline constexpr decltype(auto)
-  getFacetLocalConnectivityPerElement(UInt t = 0);
+  getFacetLocalConnectivityPerElement(Idx t = 0);
 };
 
 /* -------------------------------------------------------------------------- */
 /* Interpolation                                                              */
 /* -------------------------------------------------------------------------- */
 /// default InterpolationProperty structure
 template <InterpolationType interpolation_type> struct InterpolationProperty {};
 
 #if !defined(DOXYGEN)
 /// Macro to generate the InterpolationProperty structures for different
 /// interpolation types
 #define AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(itp_type, itp_kind,          \
                                                   nb_nodes, ndim)              \
   template <> struct InterpolationProperty<itp_type> {                         \
     static constexpr InterpolationKind kind{itp_kind};                         \
-    static constexpr UInt nb_nodes_per_element{nb_nodes};                      \
-    static constexpr UInt natural_space_dimension{ndim};                       \
+    static constexpr Int nb_nodes_per_element{nb_nodes};                       \
+    static constexpr Int natural_space_dimension{ndim};                        \
   }
 #else
 #define AKANTU_DEFINE_INTERPOLATION_TYPE_PROPERTY(itp_type, itp_kind,          \
                                                   nb_nodes, ndim)
 #endif
 /* -------------------------------------------------------------------------- */
 /// Generic (templated by the enum InterpolationType which specifies the order
 /// and the dimension of the interpolation) class handling the elemental
 /// interpolation
 template <InterpolationType interpolation_type,
           InterpolationKind kind =
               InterpolationProperty<interpolation_type>::kind>
 class InterpolationElement {
 public:
   using interpolation_property = InterpolationProperty<interpolation_type>;
 
   /// compute the shape values for a given set of points in natural coordinates
   template <class D1, class D2,
             aka::enable_if_t<aka::are_matrices<D1, D2>::value> * = nullptr>
   static inline void computeShapes(const Eigen::MatrixBase<D1> & natural_coord,
                                    const Eigen::MatrixBase<D2> & shapes);
 
   /// compute the shape values for a given point in natural coordinates
   template <class D1, class D2,
             aka::enable_if_t<aka::are_vectors<D1, D2>::value> * = nullptr>
   static inline void computeShapes(const Eigen::MatrixBase<D1> &,
                                    Eigen::MatrixBase<D2> &) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /**
    * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the variation of
    * shape functions along with variation of natural coordinates on a given set
    * of points in natural coordinates
    */
   template <class D>
   static inline void computeDNDS(const Eigen::MatrixBase<D> & Xs,
                                  Tensor3Base<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 D1, class D2>
   static inline void computeDNDS(const Eigen::MatrixBase<D1> & /*Xs*/,
                                  Eigen::MatrixBase<D2> & /*dNdS*/) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /**
    * compute @f$ @f$
    
    **/
   static inline void computeD2NDS2(const Matrix<Real> & natural_coord,
 				   Tensor3<Real> & d2nds2);
 
   /**
    * compute @f$ B_{ij} = \frac{\partial N_j}{\partial S_i} @f$ the
    * second 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 computeD2NDS2(const vector_type &, matrix_type &) {
     AKANTU_TO_IMPLEMENT();
   }
 
 
   /// compute jacobian (or integration variable change factor) for a given point
   /// in the case of spatial_dimension != natural_space_dimension
   template <class D>
   static inline Real computeSpecialJacobian(const Eigen::MatrixBase<D> &) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// interpolate a field given (arbitrary) natural coordinates
   template <class Derived1, class Derived2>
   static inline decltype(auto) interpolateOnNaturalCoordinates(
       const Eigen::MatrixBase<Derived1> & natural_coords,
       const Eigen::MatrixBase<Derived2> & nodal_values) {
     using interpolation = InterpolationProperty<interpolation_type>;
     Eigen::Matrix<Real, interpolation::nb_nodes_per_element, 1> shapes;
     computeShapes(natural_coords, shapes);
 
     return interpolate(nodal_values, shapes);
   }
 
   /// interpolate a field given the shape functions on the interpolation point
   template <class Derived1, class Derived2>
   static inline auto
   interpolate(const Eigen::MatrixBase<Derived1> & nodal_values,
               const Eigen::MatrixBase<Derived2> & shapes) {
     return nodal_values * shapes;
   }
 
   /// interpolate a field given the shape functions on the interpolations points
   template <class Derived1, class Derived2, class Derived3,
             aka::enable_if_matrices_t<Derived1, Derived2, Derived3> * = nullptr>
   static inline void
   interpolate(const Eigen::MatrixBase<Derived1> & nodal_values,
               const Eigen::MatrixBase<Derived2> & Ns,
               const Eigen::MatrixBase<Derived3> & interpolated);
 
   /// compute the gradient of a given field on the given natural coordinates
   template <class Derived1, class Derived2>
   static inline decltype(auto) gradientOnNaturalCoordinates(
       const Eigen::MatrixBase<Derived1> & natural_coords,
       const Eigen::MatrixBase<Derived2> & f);
 
 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);
+  static constexpr auto getShapeSize() {
+    return InterpolationProperty<interpolation_type>::nb_nodes_per_element;
+  }
+  static constexpr auto getShapeDerivativesSize() {
+    return (InterpolationProperty<interpolation_type>::nb_nodes_per_element *
+            InterpolationProperty<interpolation_type>::natural_space_dimension);
+  }
+  static constexpr auto getNaturalSpaceDimension() {
+    return InterpolationProperty<interpolation_type>::natural_space_dimension;
+  }
+  static constexpr auto getNbNodesPerInterpolationElement() {
+    return InterpolationProperty<interpolation_type>::nb_nodes_per_element;
+  }
 };
 
 /* -------------------------------------------------------------------------- */
 /* Integration                                                                */
 /* -------------------------------------------------------------------------- */
-template <GaussIntegrationType git_class, UInt nb_points>
+template <GaussIntegrationType git_class, Int 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>
+          Int n = ElementClassProperty<type>::polynomial_degree>
 class GaussIntegrationElement {
 public:
-  static constexpr UInt getNbQuadraturePoints();
+  static constexpr Int getNbQuadraturePoints();
   static constexpr decltype(auto) getQuadraturePoints();
   static constexpr decltype(auto) getWeights();
 };
 
 /* -------------------------------------------------------------------------- */
 /* ElementClass                                                               */
 /* -------------------------------------------------------------------------- */
 template <ElementType element_type,
           ElementKind element_kind =
               ElementClassProperty<element_type>::element_kind>
 class ElementClass
     : public GeometricalElement<
           ElementClassProperty<element_type>::geometrical_type>,
       public InterpolationElement<
           ElementClassProperty<element_type>::interpolation_type> {
 protected:
   using geometrical_element =
       GeometricalElement<ElementClassProperty<element_type>::geometrical_type>;
   using interpolation_element = InterpolationElement<
       ElementClassProperty<element_type>::interpolation_type>;
 
   using element_property = ElementClassProperty<element_type>;
   using interpolation_property =
       typename interpolation_element::interpolation_property;
 
 public:
   /**
    * compute @f$ J = \frac{\partial x_j}{\partial s_i} @f$ the variation of real
    * coordinates along with variation of natural coordinates on a given point in
    * natural coordinates
    */
   static inline void computeJMat(const Ref<const MatrixXr> & dnds,
                                  const Ref<const MatrixXr> & node_coords,
                                  Ref<MatrixXr> 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 Ref<const MatrixXr> & node_coords,
                                  Tensor3<Real> & J);
 
   /// compute the jacobians of a serie of natural coordinates
   static inline void computeJacobian(const Ref<const MatrixXr> & natural_coords,
                                      const Ref<const MatrixXr> & node_coords,
                                      Ref<VectorXr> jacobians);
 
   /// compute jacobian (or integration variable change factor) for a set of
   /// points
   static inline void computeJacobian(const Tensor3<Real> & J,
                                      Ref<VectorXr> jacobians);
 
   /// compute jacobian (or integration variable change factor) for a given point
   static inline void computeJacobian(const Ref<const MatrixXr> & 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 Ref<const MatrixXr> & J,
                                              const Ref<const MatrixXr> & dnds,
                                              Ref<MatrixXr> shape_deriv);
 
   /// compute the normal of a surface defined by the function f
   static inline void
   computeNormalsOnNaturalCoordinates(const Ref<const MatrixXr> & coord,
                                      const Ref<const MatrixXr> & f,
                                      Ref<MatrixXr> normals);
 
   /// get natural coordinates from real coordinates
   static inline void inverseMap(const Ref<const VectorXr> & real_coords,
                                 const Ref<const MatrixXr> & node_coords,
                                 Ref<VectorXr> natural_coords,
                                 Real tolerance = 1e-10);
 
   /// get natural coordinates from real coordinates
   template <class Derived1, class Derived2, class Derived3,
             aka::enable_if_matrices_t<Derived1, Derived2, Derived3> * = nullptr>
   static inline void
   inverseMap(const Eigen::MatrixBase<Derived1> & real_coords,
              const Eigen::MatrixBase<Derived2> & node_coords,
              const Eigen::MatrixBase<Derived3> & natural_coords_,
              UInt max_iterations = 100,
              Real tolerance = 1e-10);
 
 public:
-  static AKANTU_GET_MACRO_NOT_CONST(Kind, element_kind, ElementKind);
-  static constexpr AKANTU_GET_MACRO_NOT_CONST(
-      SpatialDimension, ElementClassProperty<element_type>::spatial_dimension,
-      UInt);
+  static constexpr auto getKind() { return element_kind; }
+  static constexpr auto getSpatialDimension() {
+    return ElementClassProperty<element_type>::spatial_dimension;
+  }
 
   using element_class_extra_geom_property =
       ElementClassExtraGeometryProperties<element_type>;
 
   static constexpr decltype(auto) getP1ElementType() {
     return element_class_extra_geom_property::p1_type;
   }
   static constexpr decltype(auto) getFacetType(UInt t = 0) {
     return element_class_extra_geom_property::facet_type[t];
   }
   static constexpr decltype(auto) getFacetTypes();
 };
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #include "geometrical_element_property.hh"
 #include "interpolation_element_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_class_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_class_hexahedron_8_inline_impl.cc"
 #include "element_class_pentahedron_6_inline_impl.cc"
 /* keep order */
 #include "element_class_hexahedron_20_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"
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 #include "element_class_structural.hh"
 #endif
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 #include "cohesive_element.hh"
 #endif
 
 #if defined(AKANTU_IGFEM)
 #include "element_class_igfem.hh"
 #endif
 
 #endif /* AKANTU_ELEMENT_CLASS_HH_ */
diff --git a/src/fe_engine/element_class_tmpl.hh b/src/fe_engine/element_class_tmpl.hh
index 2e14012ad..17594c117 100644
--- a/src/fe_engine/element_class_tmpl.hh
+++ b/src/fe_engine/element_class_tmpl.hh
@@ -1,552 +1,552 @@
 /**
  * @file   element_class_tmpl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Thomas Menouillard <tmenouillard@stucky.ch>
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
  * @date last modification: Fri Dec 11 2020
  *
  * @brief  Implementation of the inline templated function of the element class
  * descriptions
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_class.hh"
 #include "gauss_integration_tmpl.hh"
 #include "aka_iterators.hh"
 /* -------------------------------------------------------------------------- */
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_ELEMENT_CLASS_TMPL_HH_
 #define AKANTU_ELEMENT_CLASS_TMPL_HH_
 
 namespace akantu {
 
 template <ElementType element_type, ElementKind element_kind>
 inline constexpr decltype(auto)
 ElementClass<element_type, element_kind>::getFacetTypes() {
   return Eigen::Map<const Eigen::Matrix<
       ElementType, geometrical_element::getNbFacetTypes(), 1>>(
       element_class_extra_geom_property::facet_type.data());
 }
 
 /* -------------------------------------------------------------------------- */
 /* GeometricalElement                                                         */
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type, GeometricalShapeType shape>
 inline constexpr decltype(auto)
 GeometricalElement<geometrical_type,
-                   shape>::getFacetLocalConnectivityPerElement(UInt t) {
-  int pos = 0;
-  for (UInt i = 0; i < t; ++i) {
+                   shape>::getFacetLocalConnectivityPerElement(Idx t) {
+  Int pos = 0;
+  for (Int i = 0; i < t; ++i) {
     pos += geometrical_property::nb_facets[i] *
            geometrical_property::nb_nodes_per_facet[i];
   }
 
-  return Eigen::Map<const Eigen::Matrix<UInt, Eigen::Dynamic, Eigen::Dynamic>>(
+  return Eigen::Map<const Eigen::Matrix<Int, Eigen::Dynamic, Eigen::Dynamic>>(
       geometrical_property::facet_connectivity_vect.data() + pos,
       geometrical_property::nb_facets[t],
       geometrical_property::nb_nodes_per_facet[t]);
 }
 
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type, GeometricalShapeType shape>
-inline constexpr UInt
+inline constexpr Int
 GeometricalElement<geometrical_type, shape>::getNbFacetsPerElement() {
-  UInt total_nb_facets = 0;
-  for (UInt n = 0; n < geometrical_property::nb_facet_types; ++n) {
+  Int total_nb_facets = 0;
+  for (Int n = 0; n < geometrical_property::nb_facet_types; ++n) {
     total_nb_facets += geometrical_property::nb_facets[n];
   }
 
   return total_nb_facets;
 }
 
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type, GeometricalShapeType shape>
-inline constexpr UInt
-GeometricalElement<geometrical_type, shape>::getNbFacetsPerElement(UInt t) {
+inline constexpr Int
+GeometricalElement<geometrical_type, shape>::getNbFacetsPerElement(Idx t) {
   return geometrical_property::nb_facets[t];
 }
 
 /* -------------------------------------------------------------------------- */
 template <GeometricalType geometrical_type, GeometricalShapeType shape>
 template <class D>
 inline bool GeometricalElement<geometrical_type, shape>::contains(
     const Eigen::MatrixBase<D> & coords) {
   return GeometricalShapeContains<shape>::contains(coords);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class D>
 inline bool GeometricalShapeContains<_gst_point>::contains(
     const Eigen::MatrixBase<D> & coords) {
   return (coords(0) < std::numeric_limits<Real>::epsilon());
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class D>
 inline bool GeometricalShapeContains<_gst_square>::contains(
     const Eigen::MatrixBase<D> & coords) {
   bool in = true;
   for (UInt i = 0; i < coords.size() && in; ++i) {
     in &= ((coords(i) >= -(1. + std::numeric_limits<Real>::epsilon())) &&
            (coords(i) <= (1. + std::numeric_limits<Real>::epsilon())));
   }
   return in;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class D>
 inline bool GeometricalShapeContains<_gst_triangle>::contains(
     const Eigen::MatrixBase<D> & coords) {
   bool in = true;
   Real sum = 0;
   for (Int i = 0; (i < coords.size()) && in; ++i) {
     in &= ((coords(i) >= -(Math::getTolerance())) &&
            (coords(i) <= (1. + Math::getTolerance())));
     sum += coords(i);
   }
   if (in) {
     return (in && (sum <= (1. + Math::getTolerance())));
   }
   return in;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class D>
 inline bool GeometricalShapeContains<_gst_prism>::contains(
     const Eigen::MatrixBase<D> & coords) {
   bool in = ((coords(0) >= -1.) && (coords(0) <= 1.)); // x in segment [-1, 1]
 
   // y and z in triangle
   in &= ((coords(1) >= 0) && (coords(1) <= 1.));
   in &= ((coords(2) >= 0) && (coords(2) <= 1.));
   Real sum = coords(1) + coords(2);
 
   return (in && (sum <= 1));
 }
 
 /* -------------------------------------------------------------------------- */
 /* InterpolationElement                                                       */
 /* -------------------------------------------------------------------------- */
 template <InterpolationType interpolation_type, InterpolationKind kind>
 template <typename D1, typename D2,
           aka::enable_if_t<aka::are_matrices<D1, D2>::value> *>
 inline void InterpolationElement<interpolation_type, kind>::computeShapes(
     const Eigen::MatrixBase<D1> & Xs, const Eigen::MatrixBase<D2> & N_) {
 
   Eigen::MatrixBase<D2> & N = const_cast<Eigen::MatrixBase<D2> &>(
       N_); // as advised by the Eigen developers
 
   for (auto && data : zip(Xs, N)) {
     computeShapes(std::get<0>(data), std::get<1>(data));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <InterpolationType interpolation_type, InterpolationKind kind>
 template <class D>
 inline void InterpolationElement<interpolation_type, kind>::computeDNDS(
     const Eigen::MatrixBase<D> & Xs, Tensor3Base<Real> & dNdS) {
   for (auto && data : zip(Xs, dNdS)) {
     computeDNDS(std::get<0>(data), std::get<1>(data));
   }
 }
 
 // /* --------------------------------------------------------------------------
 // */
 // /**
 //  * interpolate on a point a field for which values are given on the
 //  * node of the element using the shape functions at this interpolation point
 //  *
 //  * @param nodal_values values of the function per node @f$ f_{ij} = f_{n_i j}
 //  *@f$ so it should be a matrix of size nb_nodes_per_element @f$\times@f$
 //  *nb_degree_of_freedom
 //  * @param shapes value of shape functions at the interpolation point
 //  * @param interpolated interpolated value of f @f$ f_j(\xi) = \sum_i f_{n_i
 //  j} *N_i @f$
 //  */
 // template <InterpolationType interpolation_type, InterpolationKind kind>
 // template <typename Derived1, typename Derived2, typename Derived3,
 //           aka::enable_if_t<aka::conjunction<
 //               aka::is_matrice<Derived1>, aka::is_vector<Derived2>>::value> *
 //               = nullptr>
 // inline auto
 // InterpolationElement<interpolation_type, kind>::interpolate(
 //     const Eigen::MatrixBase<Derived1> & nodal_values,
 //     const Eigen::MatrixBase<Derived2> & shapes) {
 //   return nodal_values * shapes;
 // }
 
 /* -------------------------------------------------------------------------- */
 /**
  * interpolate on several points a field  for which values are given on the
  * node of the element using the shape functions at the interpolation point
  *
  * @param nodal_values values of the function per node @f$ f_{ij} = f_{n_i j}
  *@f$ so it should be a matrix of size nb_nodes_per_element @f$\times@f$
  *nb_degree_of_freedom
  * @param shapes value of shape functions at the interpolation point
  * @param interpolated interpolated values of f @f$ f_j(\xi) = \sum_i f_{n_i j}
  *N_i @f$
  */
 template <InterpolationType interpolation_type, InterpolationKind kind>
 template <typename Derived1, typename Derived2, typename Derived3,
           aka::enable_if_matrices_t<Derived1, Derived2, Derived3> *>
 inline void InterpolationElement<interpolation_type, kind>::interpolate(
     const Eigen::MatrixBase<Derived1> & nodal_values,
     const Eigen::MatrixBase<Derived2> & Ns,
     const Eigen::MatrixBase<Derived3> & interpolated_) {
 
   auto && interpolated = const_cast<Eigen::MatrixBase<Derived3> &>(
       interpolated_); // as advised by the Eigen developers
 
-  UInt nb_points = Ns.cols();
-  for (UInt p = 0; p < nb_points; ++p) {
+  auto nb_points = Ns.cols();
+  for (auto p = 0; p < nb_points; ++p) {
     interpolated(p) = interpolate(nodal_values, Ns(p));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * interpolate the field on a point given in natural coordinates the field which
  * values are given on the node of the element
  *
  * @param natural_coords natural coordinates of point where to interpolate \xi
  * @param nodal_values values of the function per node @f$ f_{ij} = f_{n_i j}
  *@f$ so it should be a matrix of size nb_nodes_per_element @f$\times@f$
  *nb_degree_of_freedom
  * @param interpolated interpolated value of f @f$ f_j(\xi) = \sum_i f_{n_i j}
  *N_i @f$
  */
 // template <InterpolationType interpolation_type, InterpolationKind kind>
 // inline decltype(auto)
 // InterpolationElement<interpolation_type,
 // kind>::interpolateOnNaturalCoordinates(
 //     const Ref<const VectorXr> & natural_coords,
 //     const Ref<const MatrixXr> & nodal_values, Ref<VectorXr> interpolated) {
 //   using interpolation = InterpolationProperty<interpolation_type>;
 //   Eigen::Matrix<Real, interpolation::nb_nodes_per_element, 1> shapes;
 //   computeShapes(natural_coords, shapes);
 
 //   return interpolate(nodal_values, shapes);
 // }
 
 /* -------------------------------------------------------------------------- */
 /// @f$ gradient_{ij} = \frac{\partial f_j}{\partial s_i} = \sum_k
 /// \frac{\partial N_k}{\partial s_i}f_{j n_k} @f$
 template <InterpolationType interpolation_type, InterpolationKind kind>
 template <typename Derived1, typename Derived2>
 inline decltype(auto)
 InterpolationElement<interpolation_type, kind>::gradientOnNaturalCoordinates(
     const Eigen::MatrixBase<Derived1> & natural_coords,
     const Eigen::MatrixBase<Derived2> & f) {
   Eigen::Matrix<
       Real, InterpolationProperty<interpolation_type>::natural_space_dimension,
       InterpolationProperty<interpolation_type>::nb_nodes_per_element>
       dnds;
   computeDNDS(natural_coords, dnds);
   return f * dnds.transpose();
 }
 
 /* -------------------------------------------------------------------------- */
 /* ElementClass                                                               */
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeJMat(const Tensor3<Real> & dnds,
                                       const Ref<const MatrixXr> & node_coords,
                                       Tensor3<Real> & J) {
   UInt nb_points = dnds.size(2);
   for (UInt p = 0; p < nb_points; ++p) {
     computeJMat(dnds(p), node_coords, J(p));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeJMat(const Ref<const MatrixXr> & dnds,
                                       const Ref<const MatrixXr> & node_coords,
                                       Ref<MatrixXr> J) {
   /// @f$ J = dxds = dnds * x @f$
   J = dnds * node_coords.transpose();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void ElementClass<type, kind>::computeJacobian(
     const Ref<const MatrixXr> & natural_coords,
     const Ref<const MatrixXr> & node_coords, Ref<VectorXr> jacobians) {
   UInt nb_points = natural_coords.cols();
   Matrix<Real, interpolation_property::natural_space_dimension,
          interpolation_property::nb_nodes_per_element>
       dnds;
   Ref<MatrixXr> J(natural_coords.rows(), node_coords.rows());
 
   for (UInt p = 0; p < nb_points; ++p) {
     interpolation_element::computeDNDS(natural_coords(p), dnds);
     computeJMat(dnds, node_coords, J);
     computeJacobian(J, jacobians(p));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void ElementClass<type, kind>::computeJacobian(const Tensor3<Real> & J,
                                                       Ref<VectorXr> jacobians) {
   UInt nb_points = J.size(2);
   for (UInt p = 0; p < nb_points; ++p) {
     computeJacobian(J(p), jacobians(p));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeJacobian(const Ref<const MatrixXr> & J,
                                           Real & jacobians) {
   if (J.rows() == J.cols()) {
-    jacobians = Math::det<element_property::spatial_dimension>(J.data());
+    jacobians = J.determinant();
   } else {
     interpolation_element::computeSpecialJacobian(J, jacobians);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::computeShapeDerivatives(const Tensor3<Real> & J,
                                                   const Tensor3<Real> & dnds,
                                                   Tensor3<Real> & shape_deriv) {
   UInt nb_points = J.size(2);
   for (UInt p = 0; p < nb_points; ++p) {
     computeShapeDerivatives(J(p), dnds(p), shape_deriv(p));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void ElementClass<type, kind>::computeShapeDerivatives(
     const Ref<const MatrixXr> & J, const Ref<const MatrixXr> & dnds,
     Ref<MatrixXr> shape_deriv) {
   shape_deriv = J.inverse() * dnds;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 inline void ElementClass<type, kind>::computeNormalsOnNaturalCoordinates(
     const Ref<const MatrixXr> & coord, const Ref<const MatrixXr> & f,
     Ref<MatrixXr> normals) {
   UInt dimension = normals.rows();
   UInt nb_points = coord.cols();
 
   AKANTU_DEBUG_ASSERT((dimension - 1) ==
                           interpolation_property::natural_space_dimension,
                       "cannot extract a normal because of dimension mismatch "
                           << dimension - 1 << " "
                           << interpolation_property::natural_space_dimension);
 
   Matrix<Real> J(dimension, interpolation_property::natural_space_dimension);
   for (UInt p = 0; p < nb_points; ++p) {
     J = interpolation_element::gradientOnNaturalCoordinates(coord.col(p), f);
     if (dimension == 2) {
       Math::normal2(J.data(), normals.col(p).data());
     }
     if (dimension == 3) {
       Math::normal3(J.col(0).data(), J.col(1).data(), normals.col(p).data());
     }
   }
 }
 
 /* ------------------------------------------------------------------------- */
 /**
  * In the non linear cases we need to iterate to find the natural coordinates
  *@f$\xi@f$
  * provided real coordinates @f$x@f$.
  *
  * We want to solve: @f$ x- \phi(\xi) = 0@f$ with @f$\phi(\xi) = \sum_I N_I(\xi)
  *x_I@f$
  * the mapping function which uses the nodal coordinates @f$x_I@f$.
  *
  * To that end we use the Newton method and the following series:
  *
  * @f$ \frac{\partial \phi(x_k)}{\partial \xi} \left( \xi_{k+1} - \xi_k \right)
  *= x - \phi(x_k)@f$
  *
  * When we consider elements embedded in a dimension higher than them (2D
  *triangle in a 3D space for example)
  * @f$ J = \frac{\partial \phi(\xi_k)}{\partial \xi}@f$ is of dimension
  *@f$dim_{space} \times dim_{elem}@f$ which
  * is not invertible in most cases. Rather we can solve the problem:
  *
  * @f$ J^T J \left( \xi_{k+1} - \xi_k \right) = J^T \left( x - \phi(\xi_k)
  *\right) @f$
  *
  * So that
  *
  * @f$ d\xi = \xi_{k+1} - \xi_k = (J^T J)^{-1} J^T \left( x - \phi(\xi_k)
  *\right) @f$
  *
  * So that if the series converges we have:
  *
  * @f$ 0 = J^T \left( \phi(\xi_\infty) - x \right) @f$
  *
  * And we see that this is ill-posed only if @f$ J^T x = 0@f$ which means that
  *the vector provided
  * is normal to any tangent which means it is outside of the element itself.
  *
  * @param real_coords: the real coordinates the natural coordinates are sought
  *for
  * @param node_coords: the coordinates of the nodes forming the element
  * @param natural_coords: output->the sought natural coordinates
  * @param spatial_dimension: spatial dimension of the problem
  *
  **/
 template <ElementType type, ElementKind kind>
 inline void
 ElementClass<type, kind>::inverseMap(const Ref<const VectorXr> & real_coords,
                                      const Ref<const MatrixXr> & node_coords,
                                      Ref<VectorXr> natural_coords,
                                      UInt max_iterations,
                                      Real tolerance) {
   UInt spatial_dimension = real_coords.size();
   UInt dimension = natural_coords.size();
 
   // matrix copy of the real_coords
   Matrix<Real> mreal_coords(real_coords.data(), spatial_dimension, 1);
 
   // initial guess
   natural_coords.zero();
 
   // real space coordinates provided by initial guess
   Matrix<Real> physical_guess(spatial_dimension, 1);
 
   // objective function f = real_coords - physical_guess
   Matrix<Real> f(spatial_dimension, 1);
 
   // J Jacobian matrix computed on the natural_guess
   Matrix<Real> J(dimension, spatial_dimension);
 
   // J^t
   Matrix<Real> Jt(spatial_dimension, dimension);
 
   // G = J^t * J
   Matrix<Real> G(dimension, dimension);
 
   // Ginv = G^{-1}
   Matrix<Real> Ginv(dimension, dimension);
 
   // J = Ginv * J^t
   Matrix<Real> F(spatial_dimension, dimension);
 
   // dxi = \xi_{k+1} - \xi in the iterative process
   Matrix<Real> dxi(dimension, 1);
 
   Matrix<Real> dxit(1, dimension);
 
   /* --------------------------- */
   /* init before iteration loop  */
   /* --------------------------- */
   // do interpolation
   auto update_f = [&f, &physical_guess, &natural_coords, &node_coords,
                    &mreal_coords, spatial_dimension]() {
     Vector<Real> physical_guess_v(physical_guess.data(), spatial_dimension);
     interpolation_element::interpolateOnNaturalCoordinates(
         natural_coords, node_coords, physical_guess_v);
 
     // compute initial objective function value f = real_coords - physical_guess
     f = mreal_coords;
     f -= physical_guess;
 
     // compute initial error
     auto error = f.norm();
     return error;
   };
 
   auto inverse_map_error = update_f();
   /* --------------------------- */
   /* iteration loop              */
   /* --------------------------- */
   UInt iterations{0};
   while (tolerance < inverse_map_error and iterations < max_iterations) {
     // compute J^t
     interpolation_element::gradientOnNaturalCoordinates(natural_coords,
                                                         node_coords, Jt);
     J = Jt.transpose();
 
     // compute G
     auto && G = J.transpose() * J;
 
     // compute F
     auto && F = G.inverse() * J.transpose();
 
     // compute increment
     auto && dxi = F * f;
 
     // update our guess
     natural_coords += dxi;
 
     inverse_map_error = update_f();
     iterations++;
   }
 
   if(iterations >= max_iterations) {
     AKANTU_EXCEPTION("The solver in inverse map did not converge");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, ElementKind kind>
 template <typename Derived1, typename Derived2, typename Derived3,
           aka::enable_if_matrices_t<Derived1, Derived2, Derived3> *>
 inline void ElementClass<type, kind>::inverseMap(
     const Eigen::MatrixBase<Derived1> & real_coords,
     const Eigen::MatrixBase<Derived2> & node_coords,
     const Eigen::MatrixBase<Derived3> & natural_coords_, UInt max_iterations,
     Real tolerance) {
   Eigen::MatrixBase<Derived2> & natural_coords =
       const_cast<Eigen::MatrixBase<Derived2> &>(
           natural_coords_); // as advised by the Eigen developers
 
   UInt nb_points = real_coords.cols();
   for (UInt p = 0; p < nb_points; ++p) {
     Vector<Real> X(real_coords(p));
     Vector<Real> ncoord_p(natural_coords(p));
     inverseMap(X, node_coords, ncoord_p, max_iterations, tolerance);
   }
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_ELEMENT_CLASS_TMPL_HH_ */
diff --git a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.hh b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.hh
index 630d6a0b9..e2241cde3 100644
--- a/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.hh
+++ b/src/fe_engine/element_classes/element_class_bernoulli_beam_inline_impl.hh
@@ -1,250 +1,249 @@
 /**
  * @file   element_class_bernoulli_beam_inline_impl.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jul 15 2011
  * @date last modification: Fri Feb 05 2021
  *
  * @brief  Specialization of the element_class class for the type
  * _bernoulli_beam_2
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 
 /**
  * @verbatim
    --x-----q1----|----q2-----x---> x
     -1          0            1
  @endverbatim
  *
  */
 
 /* -------------------------------------------------------------------------- */
-#include "aka_static_if.hh"
 //#include "element_class_structural.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_HH_
 #define AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_HH_
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam_2,
                                                      _itp_lagrange_segment_2, 3,
                                                      2, 6);
 
 AKANTU_DEFINE_STRUCTURAL_INTERPOLATION_TYPE_PROPERTY(_itp_bernoulli_beam_3,
                                                      _itp_lagrange_segment_2, 6,
                                                      4, 6);
 
 AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_2,
                                                 _gt_segment_2,
                                                 _itp_bernoulli_beam_2,
                                                 _segment_2, _ek_structural, 2,
                                                 _git_segment, 3);
 
 AKANTU_DEFINE_STRUCTURAL_ELEMENT_CLASS_PROPERTY(_bernoulli_beam_3,
                                                 _gt_segment_2,
                                                 _itp_bernoulli_beam_3,
                                                 _segment_2, _ek_structural, 3,
                                                 _git_segment, 3);
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <typename Derived1, typename Derived2, typename Derived3>
 inline void
 InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeShapes(
     const Eigen::MatrixBase<Derived1> & natural_coords,
     const Eigen::MatrixBase<Derived2> & real_coord,
     Eigen::MatrixBase<Derived3> & N) {
   Eigen::Matrix<Real, 2, 1> L;
   InterpolationElement<_itp_lagrange_segment_2, _itk_lagrangian>::computeShapes(
       natural_coords, L);
   Eigen::Matrix<Real, 2, 4> H;
   InterpolationElement<_itp_hermite_2, _itk_structural>::computeShapes(
       natural_coords, real_coord, H);
 
   // clang-format off
   //    u1   v1      t1      u2   v2      t2
   N << L(0), 0      , 0      , L(1), 0      , 0      ,  // u
        0   , H(0, 0), H(0, 1), 0   , H(0, 2), H(0, 3),  // v
        0   , H(1, 0), H(1, 1), 0   , H(1, 2), H(1, 3); // theta
   // clang-format on
 }
 
 template <>
 template <typename Derived1, typename Derived2, typename Derived3>
 inline void
 InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::computeShapes(
     const Eigen::MatrixBase<Derived1> & natural_coords,
     const Eigen::MatrixBase<Derived2> & real_coord,
     Eigen::MatrixBase<Derived3> & N) {
   Eigen::Matrix<Real, 2, 1> L;
   InterpolationElement<_itp_lagrange_segment_2, _itk_lagrangian>::computeShapes(
       natural_coords, L);
   Eigen::Matrix<Real, 2, 4> H;
   InterpolationElement<_itp_hermite_2, _itk_structural>::computeShapes(
       natural_coords, real_coord, H);
 
   // clang-format off
   //    u1    v1       w1       tx1   ty1       tz1    u2      v2       w2       tx2   ty2       tz2
   N << L(0), 0      , 0      , 0   , 0       , 0      , L(1), 0      , 0      , 0   , 0       , 0      ,  // u
        0   , H(0, 0), 0      , 0   , 0       , H(0, 1), 0   , H(0, 2), 0      , 0   , 0       , H(0, 3),  // v
        0   , 0      , H(0, 0), 0   , -H(0, 1), 0      , 0   , 0      , H(0, 2), 0   , -H(0, 3), 0      ,  // w
        0   , 0      , 0      , L(0), 0       , 0      , 0   , 0      , 0      , L(1), 0       , 0      ,  // thetax
        0   , 0      , H(1, 0), 0   , -H(1, 1), 0      , 0   , 0      , H(1, 2), 0   , -H(1, 3), 0      ,  // thetay
        0   , H(1, 0), 0      , 0   , 0       , H(1, 1), 0   , H(1, 2), 0      , 0   , 0       , H(1, 3); // thetaz
   // clang-format on
 }
 
 /* -------------------------------------------------------------------------- */
 #if 0
 template <>
 inline void
 InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::computeShapesDisplacements(
     const Vector<Real> & natural_coords, const Matrix<Real> & real_coord,
     Matrix<Real> & N) {
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class D1, class D2, class D3>
 inline void
 InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeDNDS(
     const Eigen::MatrixBase<D1> & Xs, const Eigen::MatrixBase<D2> & xs,
     Eigen::MatrixBase<D3> & dnds) {
   Eigen::Matrix<Real, 1, 2> L;
   InterpolationElement<_itp_lagrange_segment_2, _itk_lagrangian>::computeDNDS(
       Xs, L);
   Eigen::Matrix<Real, 1, 4> H;
   InterpolationElement<_itp_hermite_2, _itk_structural>::computeDNDS(Xs, xs, H);
 
   // Storing the derivatives in dnds
   dnds.block(0, 0, L.rows(), L.cols()) = L;
   dnds.block(0, 2, H.rows(), H.cols()) = H;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template<class D1, class D2>
 inline void
 InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::arrangeInVoigt(
     const Eigen::MatrixBase<D1> & dnds, Eigen::MatrixBase<D2> & B) {
   auto L = dnds.block(0, 0, 1, 2); // Lagrange shape derivatives
   auto H = dnds.block(0, 2, 1, 4); // Hermite shape derivatives
   // clang-format off
   //    u1       v1       t1        u2        v2        t2
   B << L(0, 0), 0,       0,        L(0, 1),  0,        0      ,
        0,      -H(0, 0), -H(0, 1), 0,       -H(0, 2), -H(0, 3);
   // clang-format on
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class D1, class D2, class D3>
 inline void
 InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::computeDNDS(
     const Eigen::MatrixBase<D1> & natural_coords,
     const Eigen::MatrixBase<D2> & real_coord, Eigen::MatrixBase <D3> &dnds) {
   InterpolationElement<_itp_bernoulli_beam_2, _itk_structural>::computeDNDS(
       natural_coords, real_coord, dnds);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template<class D1, class D2>
 inline void
 InterpolationElement<_itp_bernoulli_beam_3, _itk_structural>::arrangeInVoigt(
     const Eigen::MatrixBase<D1> & dnds, Eigen::MatrixBase<D2> & B) {
   auto L = dnds.block(0, 0, 1, 2); // Lagrange shape derivatives
   auto H = dnds.block(0, 2, 1, 4); // Hermite shape derivatives
 
   // clang-format off
   //    u1       v1        w1        x1       y1        z1        u2       v2        w2         x2       y2       z2
   B << L(0, 0), 0       , 0       , 0      , 0       , 0       , L(0, 1), 0       , 0        , 0      , 0        , 0      ,  // eps
        0      , -H(0, 0), 0       , 0      , 0       , -H(0, 1), 0      , -H(0, 2), 0        , 0      , 0        ,-H(0, 3),  // chi strong axis
        0      , 0       , -H(0, 0), 0      , H(0, 1) , 0       , 0      , 0       , -H(0, 2) , 0      , H(0, 3)  , 0      ,  // chi weak axis
        0      , 0       , 0       , L(0, 0), 0       , 0       , 0      , 0       , 0        , L(0, 1), 0        , 0      ; // chi torsion
   // clang-format on
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class Derived1, class Derived2, class Derived3>
 inline void ElementClass<_bernoulli_beam_2>::computeRotationMatrix(
     Eigen::MatrixBase<Derived1> & R, const Eigen::MatrixBase<Derived2> & X,
     const Eigen::MatrixBase<Derived3> &) {
   auto && x2 = X(1); // X2
   auto && x1 = X(0); // X1
 
   auto cs = (x2 - x1) / (x2 - x1).norm();
   
   auto c = cs(0);
   auto s = cs(1);
 
   // clang-format off
   /// Definition of the rotation matrix
   R << c,  s,  0.,
       -s,  c,  0.,
        0., 0., 1.;
   // clang-format on
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <class Derived1, class Derived2, class Derived3>
 inline void ElementClass<_bernoulli_beam_3>::computeRotationMatrix(
     Eigen::MatrixBase<Derived1> & R, const Eigen::MatrixBase<Derived2> & X,
     const Eigen::MatrixBase<Derived3> & n) {
   Vector<Real> x2 = X(1); // X2
   Vector<Real> x1 = X(0); // X1
   auto dim = X.rows();
   Eigen::Matrix<Real, 1, 3> x = (x2 - x1), nv = n;
 
   x.normalize();
   auto x_n = x.cross(nv);
 
   Matrix<Real> Pe(dim, dim);
   Pe << 1., 0., 0., 0., -1., 0., 0., 0., 1.;
 
   Matrix<Real> Pg(dim, dim);
   Pg(0) = x;
   Pg(1) = x_n;
   Pg(2) = n;
 
   Pe *= Pg.inverse();
 
   R.zero();
   /// Definition of the rotation matrix
   for (Int i = 0; i < dim; ++i)
     for (Int j = 0; j < dim; ++j)
       R(i + dim, j + dim) = R(i, j) = Pe(i, j);
     }
   }
 }
 
 } // namespace akantu
 #endif /* AKANTU_ELEMENT_CLASS_BERNOULLI_BEAM_INLINE_IMPL_HH_ */
diff --git a/src/fe_engine/fe_engine.hh b/src/fe_engine/fe_engine.hh
index 7ac11d761..9ac013c37 100644
--- a/src/fe_engine/fe_engine.hh
+++ b/src/fe_engine/fe_engine.hh
@@ -1,385 +1,391 @@
 /**
  * @file   fe_engine.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Emil Gallyamov <emil.gallyamov@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri May 14 2021
  *
  * @brief  FEM class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_type_map.hh"
 #include "mesh_events.hh"
 /* -------------------------------------------------------------------------- */
 #include <functional>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_FE_ENGINE_HH_
 #define AKANTU_FE_ENGINE_HH_
 
 namespace akantu {
 class Mesh;
 class Integrator;
 class ShapeFunctions;
 class DOFManager;
 class Element;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 /**
  * The  generic  FEEngine class  derived  in  a  FEEngineTemplate class
  * containing  the
  * shape functions and the integration method
  */
 class FEEngine : public MeshEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   FEEngine(Mesh & mesh, UInt element_dimension = _all_dimensions,
            const ID & id = "fem");
 
   ~FEEngine() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// pre-compute all the shape functions, their derivatives and the jacobians
   virtual void
   initShapeFunctions(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,
       ElementType type, GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter);
+      const Array<Int> & filter_elements = empty_filter);
 
   /// filter a field
   template <typename T>
   static void
-  filterElementalData(const Mesh & mesh, const Array<T> & elem_f,
+  filterElementalData(const Mesh & mesh, const Array<T> & quad_f,
                       Array<T> & filtered_f, ElementType type,
                       GhostType ghost_type = _not_ghost,
-                      const Array<UInt> & filter_elements = empty_filter);
+                      const Array<Int> & 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, ElementType type,
             GhostType ghost_type = _not_ghost,
-            const Array<UInt> & filter_elements = empty_filter) const = 0;
+            const Array<Int> & filter_elements = empty_filter) const = 0;
 
   /// integrate a scalar value f on all elements of type "type"
   virtual Real
   integrate(const Array<Real> & f, ElementType type,
             GhostType ghost_type = _not_ghost,
-            const Array<UInt> & filter_elements = empty_filter) const = 0;
+            const Array<Int> & 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,
       ElementType type, GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const = 0;
+      const Array<Int> & filter_elements = empty_filter) const = 0;
 
   /// integrate one element scalar value on all elements of type "type"
+  Real integrate(const Ref<const VectorXr> & f, const Element & element) const {
+    return integrate(f, element.type, element.element, element.ghost_type);
+  }
+
+private:
   virtual Real integrate(const Ref<const VectorXr> & f, ElementType type,
                          UInt index,
                          GhostType ghost_type = _not_ghost) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* compatibility with old FEEngine fashion */
   /* ------------------------------------------------------------------------ */
+public:
   /// get the number of integration points
-  virtual UInt
+  virtual Int
   getNbIntegrationPoints(ElementType type,
                          GhostType ghost_type = _not_ghost) const = 0;
 
   /// get the precomputed shapes
   const virtual Array<Real> &
   getShapes(ElementType type, GhostType ghost_type = _not_ghost,
             UInt id = 0) const = 0;
 
   /// get the derivatives of shapes
   const virtual Array<Real> &
   getShapesDerivatives(ElementType type,
                        GhostType ghost_type = _not_ghost,
                        UInt id = 0) const = 0;
 
   /// get integration points
   const virtual MatrixXr &
-  getIntegrationPoints(const ElementType & type,
-                       const GhostType & ghost_type = _not_ghost) const = 0;
+  getIntegrationPoints(ElementType type,
+                       GhostType ghost_type = _not_ghost) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* 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,
-      UInt nb_degree_of_freedom, ElementType type,
+      const UInt nb_degree_of_freedom, ElementType type,
       GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const = 0;
+      const Array<Int> & 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,
       ElementType type, GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const = 0;
+      const Array<Int> & filter_elements = empty_filter) const = 0;
 
   /// Interpolate a nodal field u at the integration points of many element
   /// types -> uq
   virtual void interpolateOnIntegrationPoints(
       const Array<Real> & u, ElementTypeMapArray<Real> & uq,
       const ElementTypeMapArray<UInt> * filter_elements = nullptr) const = 0;
 
   /// pre multiplies a tensor by the shapes derivaties
   virtual void
   computeBtD(const Array<Real> & Ds, Array<Real> & BtDs,
              ElementType type,
              GhostType ghost_type = _not_ghost,
-             const Array<UInt> & filter_elements = empty_filter) const = 0;
+             const Array<Int> & filter_elements = empty_filter) const = 0;
 
   /// left and right  multiplies a tensor by the shapes derivaties
   virtual void
   computeBtDB(const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
               ElementType type,
               GhostType ghost_type = _not_ghost,
-              const Array<UInt> & filter_elements = empty_filter) const = 0;
+              const Array<Int> & filter_elements = empty_filter) const = 0;
 
   /// left multiples a vector by the shape functions
   virtual void
   computeNtb(const Array<Real> & bs, Array<Real> & Ntbs,
              ElementType type,
              GhostType ghost_type = _not_ghost,
-             const Array<UInt> & filter_elements = empty_filter) const = 0;
+             const Array<Int> & filter_elements = empty_filter) const = 0;
 
   /// left and right  multiplies a tensor by the shapes
   virtual void
   computeNtbN(const Array<Real> & bs, Array<Real> & NtbNs,
               ElementType type, GhostType ghost_type = _not_ghost,
               const Array<UInt> & filter_elements = empty_filter) const = 0;
 
   
   /// Compute the interpolation point position in the global coordinates for
   /// many element types
   virtual void computeIntegrationPointsCoordinates(
       ElementTypeMapArray<Real> & integration_points_coordinates,
       const ElementTypeMapArray<UInt> * filter_elements = nullptr) const = 0;
 
   /// Compute the interpolation point position in the global coordinates for an
   /// element type
   virtual void computeIntegrationPointsCoordinates(
       Array<Real> & integration_points_coordinates, ElementType type,
       GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const = 0;
+      const Array<Int> & 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, 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, GhostType ghost_type,
       const ElementTypeMapArray<UInt> * element_filter) const = 0;
 
   /// interpolate on a phyiscal point inside an element
   virtual void interpolate(const Ref<const VectorXr> & real_coords,
                            const Ref<const MatrixXr> & nodal_values,
                            Ref<VectorXr> interpolated,
                            const Element & element) const = 0;
 
   /// compute the shape on a provided point
   virtual void
   computeShapes(const Ref<const VectorXr> & real_coords, UInt elem,
                 ElementType type,  Ref<VectorXr> shapes,
                 GhostType ghost_type = _not_ghost) const = 0;
 
   /// compute the shape derivatives on a provided point
   virtual void
   computeShapeDerivatives(const Ref<const VectorXr> & real_coords, UInt element,
                           ElementType type,
                           Ref<MatrixXr> & shape_derivatives,
                           GhostType ghost_type = _not_ghost) const = 0;
 
   /// assembles the lumped version of @f[ \int N^t rho N @f]
   virtual void assembleFieldLumped(
       const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
       const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
       ElementType type, GhostType ghost_type = _not_ghost) const = 0;
 
   /// assembles the matrix @f[ \int N^t rho N @f]
   virtual void assembleFieldMatrix(
       const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
       const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
       ElementType type, GhostType ghost_type = _not_ghost) const = 0;
 
   /* ------------------------------------------------------------------------ */
   /* Other methods                                                            */
   /* ------------------------------------------------------------------------ */
 
   /// pre-compute normals on integration points
   virtual void computeNormalsOnIntegrationPoints(
       GhostType ghost_type = _not_ghost) = 0;
 
   /// pre-compute normals on integration points
   virtual void computeNormalsOnIntegrationPoints(
       const Array<Real> & /*field*/,
       GhostType /*ghost_type*/ = _not_ghost) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// pre-compute normals on integration points
   virtual void computeNormalsOnIntegrationPoints(
       const Array<Real> & /*field*/, Array<Real> & /*normal*/,
       ElementType /*type*/,
       GhostType /*ghost_type*/ = _not_ghost) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
 private:
   /// initialise the class
   void init();
 
   /* ------------------------------------------------------------------------ */
   /* 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 Ref<const MatrixXr> & coord,
                                         ElementType type);
 
   inline Real getElementInradius(const Element & element) const;
 
   /// 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(ElementType type_facet);
 
   /// get igfem element type for a given regular type
   static inline Vector<ElementType>
   getIGFEMElementTypes(ElementType type);
 
   /// get the interpolation element associated to an element type
   static inline InterpolationType
   getInterpolationType(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;
 
   AKANTU_GET_MACRO(ID, id, ID);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   ID id;
 
   /// 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.hh"
 #include "fe_engine_template.hh"
 
 #endif /* AKANTU_FE_ENGINE_HH_ */
diff --git a/src/fe_engine/fe_engine_inline_impl.hh b/src/fe_engine/fe_engine_inline_impl.hh
index d693952b1..a49d840a3 100644
--- a/src/fe_engine/fe_engine_inline_impl.hh
+++ b/src/fe_engine/fe_engine_inline_impl.hh
@@ -1,208 +1,209 @@
 /**
  * @file   fe_engine_inline_impl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jul 20 2010
  * @date last modification: Fri Dec 11 2020
  *
  * @brief  Implementation of the inline functions of the FEEngine Class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_class.hh"
-#include "fe_engine.hh"
+//#include "fe_engine.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_type_conversion.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_FE_ENGINE_INLINE_IMPL_HH_
 #define AKANTU_FE_ENGINE_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline Real FEEngine::getElementInradius(const Ref<const MatrixXr> & coord,
                                          ElementType type) {
   Real inradius = 0;
 
 #define GET_INRADIUS(type) inradius = ElementClass<type>::getInradius(coord);
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_INRADIUS);
 #undef GET_INRADIUS
 
   return inradius;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real FEEngine::getElementInradius(const Element & element) const {
   auto spatial_dimension = mesh.getSpatialDimension();
   auto positions = make_view(mesh.getNodes(), spatial_dimension).begin();
   auto connectivity = mesh.getConnectivities().get(element);
 
   Matrix<Real> coords(spatial_dimension, connectivity.size());
 
   for(auto && data : zip(connectivity, coords)) {
     std::get<1>(data) = positions[std::get<0>(data)];
   }
 
   return getElementInradius(coords, element.type);
 }
 
 
 /* -------------------------------------------------------------------------- */
 inline InterpolationType FEEngine::getInterpolationType(ElementType type) {
   return convertType<ElementType, InterpolationType>(type);
 }
 
 /* -------------------------------------------------------------------------- */
 /// @todo rewrite this function in order to get the cohesive element
 /// type directly from the facet
 #if defined(AKANTU_COHESIVE_ELEMENT)
 inline ElementType FEEngine::getCohesiveElementType(ElementType type) {
   ElementType ctype;
 #define GET_COHESIVE_TYPE(type)                                                \
   ctype = CohesiveFacetProperty<type>::cohesive_type;
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_COHESIVE_TYPE);
 #undef GET_COHESIVE_TYPE
 
   return ctype;
 }
 #else
 inline ElementType FEEngine::getCohesiveElementType(__attribute__((unused))
                                                     ElementType type_facet) {
   return _not_defined;
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_IGFEM)
 } // akantu
 #include "igfem_helper.hh"
 namespace akantu {
 
 inline Vector<ElementType> FEEngine::getIGFEMElementTypes(ElementType type) {
 
 #define GET_IGFEM_ELEMENT_TYPES(type)                                          \
   return IGFEMHelper::getIGFEMElementTypes<type>();
 
   AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(GET_IGFEM_ELEMENT_TYPES);
 
 #undef GET_IGFEM_ELEMENT_TYPES
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void FEEngine::extractNodalToElementField(const Mesh & mesh,
                                           const Array<T> & nodal_f,
                                           Array<T> & elemental_f,
                                           ElementType type,
                                           GhostType ghost_type,
-                                          const Array<UInt> & filter_elements) {
+                                          const Array<Int> & filter_elements) {
   AKANTU_DEBUG_IN();
 
-  UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
-  UInt nb_degree_of_freedom = nodal_f.getNbComponent();
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
-  UInt * conn_val = mesh.getConnectivity(type, ghost_type).data();
+  auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+  auto nb_degree_of_freedom = nodal_f.getNbComponent();
+  auto nb_element = mesh.getNbElement(type, ghost_type);
+  auto * conn_val = mesh.getConnectivity(type, ghost_type).data();
 
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   elemental_f.resize(nb_element);
 
   T * nodal_f_val = nodal_f.data();
   T * f_val = elemental_f.data();
 
-  UInt * el_conn;
-  for (UInt el = 0; el < nb_element; ++el) {
-    if (filter_elements != empty_filter) {
+  Idx * el_conn;
+  for (Int el = 0; el < nb_element; ++el) {
+    if (filter_elements != empty_filter)
       el_conn = conn_val + filter_elements(el) * nb_nodes_per_element;
     } else {
       el_conn = conn_val + el * nb_nodes_per_element;
     }
 
-    for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-      UInt node = *(el_conn + n);
+    for (Int n = 0; n < nb_nodes_per_element; ++n) {
+      auto node = *(el_conn + n);
       std::copy(nodal_f_val + node * nb_degree_of_freedom,
                 nodal_f_val + (node + 1) * nb_degree_of_freedom, f_val);
       f_val += nb_degree_of_freedom;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void FEEngine::filterElementalData(const Mesh & mesh, const Array<T> & elem_f,
-                                   Array<T> & filtered_f, ElementType type,
+                                   Array<T> & filtered_f,
+                                   ElementType type,
                                    GhostType ghost_type,
-                                   const Array<UInt> & filter_elements) {
+                                   const Array<Int> & filter_elements) {
   AKANTU_DEBUG_IN();
 
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
+  auto nb_element = mesh.getNbElement(type, ghost_type);
   if (nb_element == 0) {
     filtered_f.resize(0);
     return;
   }
 
-  UInt nb_degree_of_freedom = elem_f.getNbComponent();
-  UInt nb_data_per_element = elem_f.size() / nb_element;
+  auto nb_degree_of_freedom = elem_f.getNbComponent();
+  auto nb_data_per_element = elem_f.size() / nb_element;
 
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   filtered_f.resize(nb_element * nb_data_per_element);
 
   T * elem_f_val = elem_f.data();
   T * f_val = filtered_f.data();
 
   UInt el_offset;
-  for (UInt el = 0; el < nb_element; ++el) {
-    if (filter_elements != empty_filter) {
+  for (Idx el = 0; el < nb_element; ++el) {
+    if (filter_elements != empty_filter)
       el_offset = filter_elements(el);
     } else {
       el_offset = el;
     }
 
     std::copy(elem_f_val +
                   el_offset * nb_data_per_element * nb_degree_of_freedom,
               elem_f_val +
                   (el_offset + 1) * nb_data_per_element * nb_degree_of_freedom,
               f_val);
     f_val += nb_degree_of_freedom * nb_data_per_element;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_FE_ENGINE_INLINE_IMPL_HH_ */
diff --git a/src/fe_engine/fe_engine_template.hh b/src/fe_engine/fe_engine_template.hh
index 57d6f2264..e24410a47 100644
--- a/src/fe_engine/fe_engine_template.hh
+++ b/src/fe_engine/fe_engine_template.hh
@@ -1,432 +1,428 @@
 /**
  * @file   fe_engine_template.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri May 14 2021
  *
  * @brief  templated class that calls integration and shape objects
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "fe_engine.hh"
 #include "integrator.hh"
 #include "shape_functions.hh"
 /* -------------------------------------------------------------------------- */
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_FE_ENGINE_TEMPLATE_HH_
 #define AKANTU_FE_ENGINE_TEMPLATE_HH_
 
 namespace akantu {
 class DOFManager;
 namespace fe_engine {
   namespace details {
     template <ElementKind> struct AssembleLumpedTemplateHelper;
     template <ElementKind> struct AssembleFieldMatrixHelper;
   } // namespace details
 } // namespace fe_engine
 
 template <ElementKind, typename> struct AssembleFieldMatrixStructHelper;
 
 struct DefaultIntegrationOrderFunctor {
   template <ElementType type> static inline constexpr int getOrder() {
     return ElementClassProperty<type>::polynomial_degree;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind = _ek_regular,
           class IntegrationOrderFunctor = DefaultIntegrationOrderFunctor>
 class FEEngineTemplate : public FEEngine {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using Integ = I<kind, IntegrationOrderFunctor>;
   using Shape = S<kind>;
 
   FEEngineTemplate(Mesh & mesh, UInt spatial_dimension = _all_dimensions,
                    const ID & id = "fem");
 
   ~FEEngineTemplate() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// pre-compute all the shape functions, their derivatives and the jacobians
   void initShapeFunctions(GhostType ghost_type = _not_ghost) override;
   void initShapeFunctions(const Array<Real> & nodes,
                           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, ElementType type,
-            GhostType ghost_type = _not_ghost,
-            const Array<UInt> & filter_elements = empty_filter) const override;
+            UInt nb_degree_of_freedom, const ElementType & type,
+            const GhostType & ghost_type = _not_ghost,
+            const Array<Int> & filter_elements = empty_filter) const override;
 
   /// integrate a scalar value on all elements of type "type"
   Real
-  integrate(const Array<Real> & f, ElementType type,
-            GhostType ghost_type = _not_ghost,
-            const Array<UInt> & filter_elements = empty_filter) const override;
+  integrate(const Array<Real> & f, const ElementType & type,
+            const GhostType & ghost_type = _not_ghost,
+            const Array<Int> & filter_elements = empty_filter) const override;
 
   /// integrate one element scalar value on all elements of type "type"
-  Real integrate(const Ref<const VectorXr> & f, ElementType type, UInt index,
-                 GhostType ghost_type = _not_ghost) const override;
+  Real integrate(const Ref<const VectorXr> & 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,
-      ElementType type, GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const override;
+      const ElementType & type, const GhostType & ghost_type = _not_ghost,
+      const Array<Int> & filter_elements = empty_filter) const override;
 
   /// interpolate on a phyiscal point inside an element
   void interpolate(const Ref<const VectorXr> & real_coords,
                    const Ref<const MatrixXr> & nodal_values,
                    Ref<VectorXr> interpolated,
                    const Element & element) const override;
 
   /// get the number of integration points
-  UInt getNbIntegrationPoints(ElementType type,
-                              GhostType ghost_type = _not_ghost) const override;
+  Int getNbIntegrationPoints(
+      const ElementType & type,
+      const GhostType & ghost_type = _not_ghost) const override;
 
   /// get shapes precomputed
   const Array<Real> & getShapes(ElementType type,
                                 GhostType ghost_type = _not_ghost,
                                 UInt id = 0) const override;
 
   /// get the derivatives of shapes
   const Array<Real> & getShapesDerivatives(ElementType type,
                                            GhostType ghost_type = _not_ghost,
                                            UInt id = 0) const override;
 
   /// get integration points
   const inline Matrix<Real> &
   getIntegrationPoints(ElementType type,
                        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, UInt nb_degree_of_freedom,
-      ElementType type, GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const override;
+      const Array<Real> & u, Array<Real> & nablauq,
+      const UInt nb_degree_of_freedom, const ElementType & type,
+      const GhostType & ghost_type = _not_ghost,
+      const Array<Int> & 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,
-      ElementType type, GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const override;
+      const ElementType & type, const GhostType & ghost_type = _not_ghost,
+      const Array<Int> & filter_elements = empty_filter) const override;
 
   /// interpolate a nodal field on the integration points given a
   /// by_element_type
   void interpolateOnIntegrationPoints(
       const Array<Real> & u, ElementTypeMapArray<Real> & uq,
       const ElementTypeMapArray<UInt> * filter_elements =
           nullptr) const override;
 
   /// pre multiplies a tensor by the shapes derivaties
   void
-  computeBtD(const Array<Real> & Ds, Array<Real> & BtDs, ElementType type,
-             GhostType ghost_type,
-             const Array<UInt> & filter_elements = empty_filter) const override;
+  computeBtD(const Array<Real> & Ds, Array<Real> & BtDs,
+             const ElementType & type, const GhostType & ghost_type,
+             const Array<Int> & filter_elements = empty_filter) const override;
 
   /// left and right  multiplies a tensor by the shapes derivaties
-  void computeBtDB(
-      const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
-      ElementType type, GhostType ghost_type,
-      const Array<UInt> & filter_elements = empty_filter) const override;
-
-  /// left multiples a vector by the shape functions
   void
-  computeNtb(const Array<Real> & bs, Array<Real> & Ntbs, ElementType type,
-             GhostType ghost_type,
-             const Array<UInt> & filter_elements = empty_filter) const override;
+  computeBtDB(const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
+              const ElementType & type, const GhostType & ghost_type,
+              const Array<Int> & filter_elements = empty_filter) const override;
 
-  /// left and right  multiplies a tensor by the shapes
-  void computeNtbN(
-      const Array<Real> & bs, Array<Real> & NtbNs, ElementType type,
-      GhostType ghost_type,
-      const Array<UInt> & filter_elements = empty_filter) const override;
+  /// left multiples a vector by the shape functions
+  void computeNtb(const Array<Real> & bs, Array<Real> & Ntbs,
+                  const ElementType & type, const GhostType & ghost_type,
+                  const Array<Int> & filter_elements) const override;
 
   /// compute the position of integration points given by an element_type_map
   /// from nodes position
   inline void computeIntegrationPointsCoordinates(
       ElementTypeMapArray<Real> & quadrature_points_coordinates,
       const ElementTypeMapArray<UInt> * filter_elements =
           nullptr) const override;
 
   /// compute the position of integration points from nodes position
   inline void computeIntegrationPointsCoordinates(
-      Array<Real> & quadrature_points_coordinates, ElementType type,
-      GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const override;
+      Array<Real> & quadrature_points_coordinates, const ElementType & type,
+      const GhostType & ghost_type = _not_ghost,
+      const Array<Int> & 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, 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, GhostType ghost_type,
       const ElementTypeMapArray<UInt> * element_filter) const override;
 
   /// Build pre-computed matrices for interpolation of field form integration
   /// points at other given positions (interpolation_points)
   inline void initElementalFieldInterpolationFromIntegrationPoints(
       const ElementTypeMapArray<Real> & interpolation_points_coordinates,
       ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
       ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
       const ElementTypeMapArray<UInt> * element_filter =
           nullptr) const override;
 
   /// find natural coords from real coords provided an element
   void inverseMap(const Vector<Real> & real_coords, UInt element,
                   ElementType type, Vector<Real> & natural_coords,
                   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,
                        ElementType type,
                        GhostType ghost_type = _not_ghost) const;
 
   /// compute the shape on a provided point
   inline void
   computeShapes(const Ref<const VectorXr> & real_coords, UInt element,
                 ElementType type, Ref<VectorXr> shapes,
                 GhostType ghost_type = _not_ghost) const override;
 
   /// compute the shape derivatives on a provided point
   inline void computeShapeDerivatives(
-      const Ref<const VectorXr> & real__coords, UInt element, ElementType type,
-      Ref<MatrixXr> shape_derivatives,
-      GhostType ghost_type = _not_ghost) const override;
+      const Ref<const VectorXr> & real__coords, UInt element,
+      const ElementType & type, Ref<MatrixXr> shape_derivatives,
+      const GhostType & ghost_type = _not_ghost) const override;
 
   /* ------------------------------------------------------------------------ */
   /* Other methods                                                            */
   /* ------------------------------------------------------------------------ */
   /// pre-compute normals on integration points
   void
   computeNormalsOnIntegrationPoints(GhostType ghost_type = _not_ghost) override;
   void
   computeNormalsOnIntegrationPoints(const Array<Real> & field,
                                     GhostType ghost_type = _not_ghost) override;
   void computeNormalsOnIntegrationPoints(
       const Array<Real> & field, Array<Real> & normal, ElementType type,
       GhostType ghost_type = _not_ghost) const override;
   template <ElementType type>
   void computeNormalsOnIntegrationPoints(const Array<Real> & field,
                                          Array<Real> & normal,
                                          GhostType ghost_type) const;
 
 private:
   // To avoid a weird full specialization of a method in a non specalized class
   void computeNormalsOnIntegrationPointsPoint1(const Array<Real> & /*unused*/,
                                                Array<Real> & normal,
                                                GhostType ghost_type) const;
 
 public:
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   void assembleFieldLumped(
       const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
       const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
       ElementType type, GhostType ghost_type) const override;
 
   /// assemble a field as a matrix (ex. rho to mass matrix)
   void assembleFieldMatrix(
       const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
       const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
       ElementType type, GhostType ghost_type) 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,
   //                          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,
   //                          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,
   //                            ElementType type,
   //                            GhostType ghost_type = _not_ghost)
   //                            const;
 
   //   /// compute shapes function in a matrix for structural elements
   //   void
   //   computeShapesMatrix(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,
   //                       GhostType ghost_type = _not_ghost) const
   //                       override;
   // #endif
 
 private:
   friend struct fe_engine::details::AssembleLumpedTemplateHelper<kind>;
   friend struct fe_engine::details::AssembleFieldMatrixHelper<kind>;
   friend struct AssembleFieldMatrixStructHelper<kind, void>;
 
   /// templated function to compute the scaling to assemble a lumped matrix
   template <ElementType type>
   void assembleFieldLumped(
       const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
       const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
       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,
                             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,
                                      GhostType ghost_type) const;
 
   /// assemble a field as a matrix (ex. rho to mass matrix)
   template <ElementType type>
   void assembleFieldMatrix(
       const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
       const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
       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)) GhostType ghost_type) const;
 
 #endif
 
   /* ------------------------------------------------------------------------ */
   /* Mesh Event Handler interface                                             */
   /* ------------------------------------------------------------------------ */
 public:
   void onElementsAdded(const Array<Element> & /*new_elements*/,
                        const NewElementsEvent & /*unused*/) override;
   void onElementsRemoved(const Array<Element> & /*unused*/,
                          const ElementTypeMapArray<UInt> & /*unused*/,
                          const RemovedElementsEvent & /*unused*/) override;
   void onElementsChanged(const Array<Element> & /*unused*/,
                          const Array<Element> & /*unused*/,
                          const ElementTypeMapArray<UInt> & /*unused*/,
                          const ChangedElementsEvent & /*unused*/) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the shape class (probably useless: see getShapeFunction)
   const ShapeFunctions & getShapeFunctionsInterface() const override {
     return shape_functions;
   };
   /// get the shape class
   const Shape & getShapeFunctions() const { return shape_functions; };
 
   /// get the integrator class (probably useless: see getIntegrator)
   const Integrator & getIntegratorInterface() const override {
     return integrator;
   };
   /// get the integrator class
   const Integ & getIntegrator() const { return integrator; };
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   Integ integrator;
   Shape shape_functions;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "fe_engine_template_tmpl.hh"
 #include "fe_engine_template_tmpl_field.hh"
 /* -------------------------------------------------------------------------- */
 /* Shape Linked specialization                                                */
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 #include "fe_engine_template_tmpl_struct.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 /* Shape IGFEM specialization                                                 */
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_IGFEM)
 #include "fe_engine_template_tmpl_igfem.hh"
 #endif
 
 #endif /* AKANTU_FE_ENGINE_TEMPLATE_HH_ */
diff --git a/src/fe_engine/fe_engine_template_cohesive.cc b/src/fe_engine/fe_engine_template_cohesive.cc
index 617ff433b..8f845a189 100644
--- a/src/fe_engine/fe_engine_template_cohesive.cc
+++ b/src/fe_engine/fe_engine_template_cohesive.cc
@@ -1,137 +1,137 @@
 /**
  * @file   fe_engine_template_cohesive.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Oct 31 2012
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  Specialization of the FEEngineTemplate for cohesive element
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "fe_engine_template.hh"
 #include "integrator_gauss.hh"
 #include "shape_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* compatibility functions */
 /* -------------------------------------------------------------------------- */
 template <>
 Real FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive,
                       DefaultIntegrationOrderFunctor>::
-    integrate(const Array<Real> & f, ElementType type,
-              GhostType ghost_type,
-              const Array<UInt> & filter_elements) const {
+    integrate(const Array<Real> & f, const ElementType & type,
+              const GhostType & ghost_type,
+              const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
 #ifndef AKANTU_NDEBUG
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
-  if (filter_elements != empty_filter) {
+  auto nb_element = mesh.getNbElement(type, ghost_type);
+  if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
   }
 
-  UInt nb_quadrature_points = getNbIntegrationPoints(type);
+  auto nb_quadrature_points = getNbIntegrationPoints(type);
 
-  AKANTU_DEBUG_ASSERT(f.size() == nb_element * nb_quadrature_points,
+  AKANTU_DEBUG_ASSERT(f.size() == Int(nb_element * nb_quadrature_points),
                       "The vector f(" << f.getID()
                                       << ") has not the good size.");
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == 1,
                       "The vector f("
                           << f.getID()
                           << ") has not the good number of component.");
 #endif
 
   Real integral = 0.;
 
 #define INTEGRATE(type)                                                        \
   integral = integrator.integrate<type>(f, ghost_type, filter_elements);
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INTEGRATE);
 #undef INTEGRATE
 
   AKANTU_DEBUG_OUT();
   return integral;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive,
                       DefaultIntegrationOrderFunctor>::
     integrate(const Array<Real> & f, Array<Real> & intf,
-              UInt nb_degree_of_freedom, ElementType type,
-              GhostType ghost_type,
-              const Array<UInt> & filter_elements) const {
+              UInt nb_degree_of_freedom, const ElementType & type,
+              const GhostType & ghost_type,
+              const Array<Int> & filter_elements) const {
 
 #ifndef AKANTU_NDEBUG
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
-  if (filter_elements != empty_filter) {
+  auto nb_element = mesh.getNbElement(type, ghost_type);
+  if (filter_elements != empty_filter)
     nb_element = filter_elements.size();
   }
 
-  UInt nb_quadrature_points = getNbIntegrationPoints(type);
+  auto nb_quadrature_points = getNbIntegrationPoints(type);
 
-  AKANTU_DEBUG_ASSERT(f.size() == nb_element * nb_quadrature_points,
+  AKANTU_DEBUG_ASSERT(f.size() == Int(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,
+  AKANTU_DEBUG_ASSERT(f.getNbComponent() == Int(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,
+  AKANTU_DEBUG_ASSERT(intf.getNbComponent() == Int(nb_degree_of_freedom),
                       "The vector intf("
                           << intf.getID()
                           << ") has not the good number of component.");
   AKANTU_DEBUG_ASSERT(intf.size() == nb_element,
                       "The vector intf(" << intf.getID()
                                          << ") has not the good size.");
 #endif
 
 #define INTEGRATE(type)                                                        \
   integrator.integrate<type>(f, intf, nb_degree_of_freedom, ghost_type,        \
                              filter_elements);
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INTEGRATE);
 #undef INTEGRATE
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive,
                       DefaultIntegrationOrderFunctor>::
     gradientOnIntegrationPoints(
         const Array<Real> & /* u */, Array<Real> & /*  nablauq */,
         UInt /* nb_degree_of_freedom */, ElementType /* type  */,
         GhostType /*  ghost_type */,
-        const Array<UInt> & /*  filter_elements */) const {
+        const Array<Int> & /*  filter_elements */) const {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/fe_engine/fe_engine_template_tmpl.hh b/src/fe_engine/fe_engine_template_tmpl.hh
index 3cf781fda..0dc8c0355 100644
--- a/src/fe_engine/fe_engine_template_tmpl.hh
+++ b/src/fe_engine/fe_engine_template_tmpl.hh
@@ -1,1547 +1,1445 @@
 /**
  * @file   fe_engine_template_tmpl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Mohit Pundir <mohit.pundir@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: Fri May 14 2021
  *
  * @brief  Template implementation of FEEngineTemplate
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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, const ID & id)
     : FEEngine(mesh, spatial_dimension, id),
       integrator(mesh, spatial_dimension, id),
       shape_functions(mesh, spatial_dimension, id) {}
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::~FEEngineTemplate() =
     default;
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct GradientOnIntegrationPointsHelper {
       template <class S>
       static void call(const S & /*unused*/, Mesh & /*unused*/,
                        const Array<Real> & /*unused*/, Array<Real> & /*unused*/,
                        const UInt /*unused*/, ElementType /*unused*/,
                        GhostType /*unused*/, const Array<UInt> & /*unused*/) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define COMPUTE_GRADIENT(type)                                                 \
   if (element_dimension == ElementClass<type>::getSpatialDimension())          \
     shape_functions.template gradientOnIntegrationPoints<type>(                \
         u, nablauq, nb_degree_of_freedom, ghost_type, filter_elements);
 
 #define AKANTU_SPECIALIZE_GRADIENT_ON_INTEGRATION_POINTS_HELPER(kind)          \
   template <> struct GradientOnIntegrationPointsHelper<kind> {                 \
     template <class S>                                                         \
     static void call(const S & shape_functions, Mesh & mesh,                   \
                      const Array<Real> & u, Array<Real> & nablauq,             \
-                     const UInt nb_degree_of_freedom, ElementType type,        \
-                     GhostType ghost_type,                                     \
-                     const Array<UInt> & filter_elements) {                    \
+                     const UInt nb_degree_of_freedom,                          \
+                     const ElementType & type, const GhostType & ghost_type,   \
+                     const Array<Int> & 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,
-                                ElementType type, GhostType ghost_type,
-                                const Array<UInt> & filter_elements) const {
+                                const ElementType & type,
+                                const GhostType & ghost_type,
+                                const Array<Int> & 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(
     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, 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,            \
-                     ElementType type, GhostType ghost_type,                   \
-                     const Array<UInt> & filter_elements) {                    \
+                     const ElementType & type, const GhostType & ghost_type,   \
+                     const Array<Int> & 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,
-    ElementType type, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const ElementType & type, const GhostType & ghost_type,
+    const Array<Int> & 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,              \
-                     ElementType type, GhostType ghost_type,                   \
-                     const Array<UInt> & filter_elements) {                    \
+                     const ElementType & type, const GhostType & ghost_type,   \
+                     const Array<Int> & 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, ElementType type, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const Array<Real> & f, const ElementType & type,
+    const GhostType & ghost_type, const Array<Int> & 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 Ref<const VectorXr> & f,      \
                      ElementType type, UInt index, 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 Ref<const VectorXr> & f, ElementType type, UInt index,
     GhostType ghost_type) const {
-Real res =
-          fe_engine::details::IntegrateScalarOnOneElementHelper<kind>::call(
-              integrator, f, type, index, ghost_type);
-      return res;
-    }
+  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 {};
+/* -------------------------------------------------------------------------- */
+/**
+ * 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,            \
-                     ElementType type, GhostType ghost_type,                   \
-                     const Array<UInt> & filter_elements) {                    \
+                     const ElementType & type, const GhostType & ghost_type,   \
+                     const Array<Int> & filter_elements) {                     \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INTEGRATE, kind);                       \
     }                                                                          \
   };
 
-        AKANTU_BOOST_ALL_KIND(
-            AKANTU_SPECIALIZE_INTEGRATE_ON_INTEGRATION_POINTS_HELPER)
+    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,
-                                     ElementType type, 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);
+  } // 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<Int> & 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.");
+  //   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);
-    }
+  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 & /*unused*/, const Array<Real> & /*unused*/,
-                           Array<Real> & /*unused*/, const UInt /*unused*/,
-                           ElementType /*unused*/, GhostType /*unused*/,
-                           const Array<UInt> & /*unused*/) {
-            AKANTU_TO_IMPLEMENT();
-          }
-        };
+/* -------------------------------------------------------------------------- */
+/**
+ * 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 & /*unused*/, const Array<Real> & /*unused*/,
+                       Array<Real> & /*unused*/, const UInt /*unused*/,
+                       ElementType /*unused*/, GhostType /*unused*/,
+                       const Array<UInt> & /*unused*/) {
+        AKANTU_TO_IMPLEMENT();
+      }
+    };
 
 #define INTERPOLATE(type)                                                      \
   shape_functions.template interpolateOnIntegrationPoints<type>(               \
       u, uq, nb_degree_of_freedom, ghost_type, filter_elements);
 
 #define AKANTU_SPECIALIZE_INTERPOLATE_ON_INTEGRATION_POINTS_HELPER(kind)       \
   template <> struct InterpolateOnIntegrationPointsHelper<kind> {              \
     template <class S>                                                         \
     static void call(const S & shape_functions, const Array<Real> & u,         \
                      Array<Real> & uq, const UInt nb_degree_of_freedom,        \
-                     ElementType type, GhostType ghost_type,                   \
-                     const Array<UInt> & filter_elements) {                    \
+                     const ElementType & type, const GhostType & ghost_type,   \
+                     const Array<Int> & 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)
+    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,
-                                       ElementType type, 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();
-      }
+  } // 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<Int> & 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.");
+  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);
+  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);
+  fe_engine::details::InterpolateOnIntegrationPointsHelper<kind>::call(
+      shape_functions, u, uq, nb_degree_of_freedom, type, ghost_type,
+      filter_elements);
 
-      AKANTU_DEBUG_OUT();
-    }
+  AKANTU_DEBUG_OUT();
+}
 
-    /* --------------------------------------------------------------------------
-     */
-    template <template <ElementKind, class> class I,
-              template <ElementKind> class S, ElementKind kind,
-              class IntegrationOrderFunctor>
-    void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
-        interpolateOnIntegrationPoints(
-            const Array<Real> & u, ElementTypeMapArray<Real> & uq,
-            const ElementTypeMapArray<UInt> * filter_elements) const {
-      AKANTU_DEBUG_IN();
-
-      const Array<UInt> * filter = nullptr;
-
-      for (auto ghost_type : ghost_types) {
-        for (auto && type :
-             uq.elementTypes(_all_dimensions, ghost_type, kind)) {
-          UInt nb_quad_per_element = getNbIntegrationPoints(type, ghost_type);
-
-          UInt nb_element = 0;
-
-          if (filter_elements != nullptr) {
-            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);
-        }
+/* -------------------------------------------------------------------------- */
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
+    interpolateOnIntegrationPoints(
+        const Array<Real> & u, ElementTypeMapArray<Real> & uq,
+        const ElementTypeMapArray<UInt> * filter_elements) const {
+  AKANTU_DEBUG_IN();
+
+  const Array<UInt> * filter = nullptr;
+
+  for (auto ghost_type : ghost_types) {
+    for (auto && type : uq.elementTypes(_all_dimensions, ghost_type, kind)) {
+      UInt nb_quad_per_element = getNbIntegrationPoints(type, ghost_type);
+
+      UInt nb_element = 0;
+
+      if (filter_elements != nullptr) {
+        filter = &((*filter_elements)(type, ghost_type));
+        nb_element = filter->size();
+      } else {
+        filter = &empty_filter;
+        nb_element = mesh.getNbElement(type, ghost_type);
       }
 
-      AKANTU_DEBUG_OUT();
+      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);
     }
+  }
 
-    /* --------------------------------------------------------------------------
-     */
-    namespace fe_engine {
-      namespace details {
-        template <ElementKind kind> struct ComputeBtDHelper {};
+  AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+namespace fe_engine {
+  namespace details {
+    template <ElementKind kind> struct ComputeBtDHelper {};
 
 #define COMPUTE_BTD(type)                                                      \
   shape_functions.template computeBtD<type>(Ds, BtDs, ghost_type,              \
                                             filter_elements);
 
 #define AKANTU_SPECIALIZE_COMPUTE_BtD_HELPER(kind)                             \
   template <> struct ComputeBtDHelper<kind> {                                  \
     template <class S>                                                         \
     static void call(const S & shape_functions, const Array<Real> & Ds,        \
-                     Array<Real> & BtDs, ElementType type,                     \
-                     GhostType ghost_type,                                     \
-                     const Array<UInt> & filter_elements) {                    \
+                     Array<Real> & BtDs, const ElementType & type,             \
+                     const GhostType & ghost_type,                             \
+                     const Array<Int> & filter_elements) {                     \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_BTD, kind);                     \
     }                                                                          \
   };
 
-        AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_BtD_HELPER)
+    AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_BtD_HELPER)
 
 #undef AKANTU_SPECIALIZE_COMPUTE_BtD_HELPER
 #undef COMPUTE_BTD
-      } // namespace details
-    }   // namespace fe_engine
-
-    template <template <ElementKind, class> class I,
-              template <ElementKind> class S, ElementKind kind,
-              class IntegrationOrderFunctor>
-    inline void
-    FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeBtD(
-        const Array<Real> & Ds, Array<Real> & BtDs, ElementType type,
-        GhostType ghost_type, const Array<UInt> & filter_elements) const {
-      fe_engine::details::ComputeBtDHelper<kind>::call(
-          shape_functions, Ds, BtDs, type, ghost_type, filter_elements);
-    }
+  } // namespace details
+} // namespace fe_engine
 
-    /* --------------------------------------------------------------------------
-     */
-    namespace fe_engine {
-      namespace details {
-        template <ElementKind kind> struct ComputeBtDBHelper {};
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeBtD(
+    const Array<Real> & Ds, Array<Real> & BtDs, const ElementType & type,
+    const GhostType & ghost_type, const Array<Int> & filter_elements) const {
+  fe_engine::details::ComputeBtDHelper<kind>::call(
+      shape_functions, Ds, BtDs, type, ghost_type, filter_elements);
+}
+
+/* -------------------------------------------------------------------------- */
+namespace fe_engine {
+  namespace details {
+    template <ElementKind kind> struct ComputeBtDBHelper {};
 
 #define COMPUTE_BTDB(type)                                                     \
   shape_functions.template computeBtDB<type>(Ds, BtDBs, order_d, ghost_type,   \
                                              filter_elements);
 
 #define AKANTU_SPECIALIZE_COMPUTE_BtDB_HELPER(kind)                            \
   template <> struct ComputeBtDBHelper<kind> {                                 \
     template <class S>                                                         \
     static void call(const S & shape_functions, const Array<Real> & Ds,        \
-                     Array<Real> & BtDBs, UInt order_d, ElementType type,      \
-                     GhostType ghost_type,                                     \
-                     const Array<UInt> & filter_elements) {                    \
+                     Array<Real> & BtDBs, UInt order_d,                        \
+                     const ElementType & type, const GhostType & ghost_type,   \
+                     const Array<Int> & filter_elements) {                     \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_BTDB, kind);                    \
     }                                                                          \
   };
 
-        AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_BtDB_HELPER)
+    AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_BtDB_HELPER)
 
 #undef AKANTU_SPECIALIZE_COMPUTE_BtDB_HELPER
 #undef COMPUTE_BTDB
-      } // namespace details
-    }   // namespace fe_engine
-
-    template <template <ElementKind, class> class I,
-              template <ElementKind> class S, ElementKind kind,
-              class IntegrationOrderFunctor>
-    inline void
-    FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeBtDB(
-        const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
-        ElementType type, GhostType ghost_type,
-        const Array<UInt> & filter_elements) const {
-      fe_engine::details::ComputeBtDBHelper<kind>::call(
-          shape_functions, Ds, BtDBs, order_d, type, ghost_type,
-          filter_elements);
-    }
+  } // namespace details
+} // namespace fe_engine
 
-    /* --------------------------------------------------------------------------
-     */
-    namespace fe_engine {
-      namespace details {
-        template <ElementKind kind> struct ComputeNtbNHelper {};
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeBtDB(
+    const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d, ElementType type,
+    GhostType ghost_type, const Array<Int> & filter_elements) const {
+  fe_engine::details::ComputeBtDBHelper<kind>::call(
+      shape_functions, Ds, BtDBs, order_d, type, ghost_type, filter_elements);
+}
+
+/* -------------------------------------------------------------------------- */
+namespace fe_engine {
+  namespace details {
+    template <ElementKind kind> struct ComputeNtbNHelper {};
 
 #define COMPUTE_NtbN(type)                                                     \
   shape_functions.template computeNtbN<type>(bs, NtbNs, ghost_type,            \
                                              filter_elements);
 
 #define AKANTU_SPECIALIZE_COMPUTE_NtbN_HELPER(kind)                            \
   template <> struct ComputeNtbNHelper<kind> {                                 \
     template <class S>                                                         \
     static void call(const S & shape_functions, const Array<Real> & bs,        \
                      Array<Real> & NtbNs, ElementType type,                    \
                      GhostType ghost_type,                                     \
                      const Array<UInt> & filter_elements) {                    \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_NtbN, kind);                    \
     }                                                                          \
   };
 
-        AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_NtbN_HELPER)
+    AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_NtbN_HELPER)
 
 #undef AKANTU_SPECIALIZE_COMPUTE_NtbN_HELPER
 #undef COMPUTE_NtbN
-      } // 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>::computeNtbN(
-        const Array<Real> & bs, Array<Real> & NtbNs, ElementType type,
-        GhostType ghost_type, const Array<UInt> & filter_elements) const {
-      fe_engine::details::ComputeNtbNHelper<kind>::call(
-          shape_functions, bs, NtbNs, type, ghost_type, filter_elements);
-    }
+  } // namespace details
+} // namespace fe_engine
 
-    /* --------------------------------------------------------------------------
-     */
-    namespace fe_engine {
-      namespace details {
-        template <ElementKind kind> struct ComputeNtbHelper {};
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::computeNtbN(
+    const Array<Real> & bs, Array<Real> & NtbNs, ElementType type,
+    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+  fe_engine::details::ComputeNtbNHelper<kind>::call(
+      shape_functions, bs, NtbNs, type, ghost_type, filter_elements);
+}
+
+/* -------------------------------------------------------------------------- */
+namespace fe_engine {
+  namespace details {
+    template <ElementKind kind> struct ComputeNtbHelper {};
 
 #define COMPUTE_Ntb(type)                                                      \
   shape_functions.template computeNtb<type>(bs, Ntbs, ghost_type,              \
                                             filter_elements);
 
 #define AKANTU_SPECIALIZE_COMPUTE_Ntb_HELPER(kind)                             \
   template <> struct ComputeNtbHelper<kind> {                                  \
     template <class S>                                                         \
     static void call(const S & shape_functions, const Array<Real> & bs,        \
-                     Array<Real> & Ntbs, ElementType type,                     \
-                     GhostType ghost_type,                                     \
-                     const Array<UInt> & filter_elements) {                    \
+                     Array<Real> & Ntbs, const ElementType & type,             \
+                     const GhostType & ghost_type,                             \
+                     const Array<Int> & filter_elements) {                     \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_Ntb, kind);                     \
     }                                                                          \
   };
 
-        AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_Ntb_HELPER)
+    AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_COMPUTE_Ntb_HELPER)
 
 #undef AKANTU_SPECIALIZE_COMPUTE_Ntb_HELPER
 #undef COMPUTE_Ntb
-      } // 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>::computeNtb(
-        const Array<Real> & bs, Array<Real> & Ntbs, ElementType type,
+  } // 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>::computeNtb(
+    const Array<Real> & bs, Array<Real> & Ntbs, ElementType type,
+    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+  fe_engine::details::ComputeNtbHelper<kind>::call(
+      shape_functions, bs, Ntbs, type, ghost_type, filter_elements);
+}
+
+/* -------------------------------------------------------------------------- */
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
+    computeIntegrationPointsCoordinates(
+        ElementTypeMapArray<Real> & quadrature_points_coordinates,
+        const ElementTypeMapArray<UInt> * filter_elements) const {
+
+  const Array<Real> & nodes_coordinates = mesh.getNodes();
+
+  interpolateOnIntegrationPoints(
+      nodes_coordinates, quadrature_points_coordinates, filter_elements);
+}
+
+/* -------------------------------------------------------------------------- */
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
+    computeIntegrationPointsCoordinates(
+        Array<Real> & quadrature_points_coordinates, ElementType type,
         GhostType ghost_type, const Array<UInt> & filter_elements) const {
-      fe_engine::details::ComputeNtbHelper<kind>::call(
-          shape_functions, bs, Ntbs, type, ghost_type, filter_elements);
-    }
 
-    /* --------------------------------------------------------------------------
-     */
-    template <template <ElementKind, class> class I,
-              template <ElementKind> class S, ElementKind kind,
-              class IntegrationOrderFunctor>
-    inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
-        computeIntegrationPointsCoordinates(
-            ElementTypeMapArray<Real> & quadrature_points_coordinates,
-            const ElementTypeMapArray<UInt> * filter_elements) const {
+  const Array<Real> & nodes_coordinates = mesh.getNodes();
 
-      const Array<Real> & nodes_coordinates = mesh.getNodes();
+  UInt spatial_dimension = mesh.getSpatialDimension();
 
-      interpolateOnIntegrationPoints(
-          nodes_coordinates, quadrature_points_coordinates, filter_elements);
-    }
+  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>::
-        computeIntegrationPointsCoordinates(
-            Array<Real> & quadrature_points_coordinates, ElementType type,
-            GhostType ghost_type, const Array<UInt> & filter_elements) const {
+/* -------------------------------------------------------------------------- */
+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 {
 
-      const Array<Real> & nodes_coordinates = mesh.getNodes();
+  AKANTU_DEBUG_IN();
 
-      UInt spatial_dimension = mesh.getSpatialDimension();
+  UInt spatial_dimension = this->mesh.getSpatialDimension();
 
-      interpolateOnIntegrationPoints(
-          nodes_coordinates, quadrature_points_coordinates, spatial_dimension,
-          type, ghost_type, filter_elements);
-    }
+  ElementTypeMapArray<Real> quadrature_points_coordinates(
+      "quadrature_points_coordinates_for_interpolation", getID());
 
-    /* --------------------------------------------------------------------------
-     */
-    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());
-
-      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);
-    }
+  quadrature_points_coordinates.initialize(*this,
+                                           _nb_component = spatial_dimension);
 
-    /* --------------------------------------------------------------------------
-     */
-    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, GhostType ghost_type,
-            const ElementTypeMapArray<UInt> * element_filter) const {
-
-      ElementTypeMapArray<Real> interpolation_points_coordinates_matrices(
-          "interpolation_points_coordinates_matrices", id);
-      ElementTypeMapArray<Real> quad_points_coordinates_inv_matrices(
-          "quad_points_coordinates_inv_matrices", 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);
-    }
+  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_matrices,
-            const ElementTypeMapArray<Real> &
-                quad_points_coordinates_inv_matrices,
-            ElementTypeMapArray<Real> & result, 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);
-    }
+/* -------------------------------------------------------------------------- */
+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, GhostType ghost_type,
+        const ElementTypeMapArray<UInt> * element_filter) const {
+
+  ElementTypeMapArray<Real> interpolation_points_coordinates_matrices(
+      "interpolation_points_coordinates_matrices", id);
+  ElementTypeMapArray<Real> quad_points_coordinates_inv_matrices(
+      "quad_points_coordinates_inv_matrices", 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);
+}
 
-    /* --------------------------------------------------------------------------
-     */
-    /**
-     * 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 & /*unused*/,
-                           const Vector<Real> & /*unused*/, UInt /*unused*/,
-                           const Matrix<Real> & /*unused*/,
-                           Vector<Real> & /*unused*/, ElementType /*unused*/,
-                           GhostType /*unused*/) {
-            AKANTU_TO_IMPLEMENT();
-          }
-        };
+/* -------------------------------------------------------------------------- */
+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, 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 & /*unused*/, const Vector<Real> & /*unused*/,
+                       UInt /*unused*/, const Matrix<Real> & /*unused*/,
+                       Vector<Real> & /*unused*/, ElementType /*unused*/,
+                       GhostType /*unused*/) {
+        AKANTU_TO_IMPLEMENT();
+      }
+    };
 
 #define INTERPOLATE(type)                                                      \
   shape_functions.template interpolate<type>(                                  \
       real_coords, element, nodal_values, interpolated, ghost_type);
 
 #define AKANTU_SPECIALIZE_INTERPOLATE_HELPER(kind)                             \
   template <> struct InterpolateHelper<kind> {                                 \
     template <class S>                                                         \
     static void call(const S & shape_functions,                                \
-                     const Vector<Real> & real_coords, UInt element,           \
-                     const Matrix<Real> & nodal_values,                        \
-                     Vector<Real> & interpolated, ElementType type,            \
-                     GhostType ghost_type) {                                   \
+                     const Ref<const VectorXr> & real_coords, UInt element,    \
+                     const Ref<const MatrixXr> & nodal_values,                 \
+                     Ref<VectorXr> & 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)
+    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
+  } // 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 Ref<const VectorXr> & real_coords,
-        const Ref<const MatrixXr> & nodal_values, Ref<VectorXr> interpolated,
-        const Element & element) const {
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+inline void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::interpolate(
+    const Ref<const VectorXr> & real_coords,
+    const Ref<const MatrixXr> & nodal_values, Ref<VectorXr> interpolated,
+    const Element & element) const {
 
-      AKANTU_DEBUG_IN();
+  AKANTU_DEBUG_IN();
 
-      fe_engine::details::InterpolateHelper<kind>::call(
-          shape_functions, real_coords, element.element, nodal_values,
-          interpolated, element.type, element.ghost_type);
+  fe_engine::details::InterpolateHelper<kind>::call(
+      shape_functions, real_coords, element.element, nodal_values, interpolated,
+      element.type, element.ghost_type);
 
-      AKANTU_DEBUG_OUT();
-    }
+  AKANTU_DEBUG_OUT();
+}
 
-    /* --------------------------------------------------------------------------
-     */
-    template <template <ElementKind, class> class I,
-              template <ElementKind> class S, ElementKind kind,
-              class IntegrationOrderFunctor>
-    void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
-        computeNormalsOnIntegrationPoints(GhostType ghost_type) {
-      AKANTU_DEBUG_IN();
+/* -------------------------------------------------------------------------- */
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
+    computeNormalsOnIntegrationPoints(GhostType ghost_type) {
+  AKANTU_DEBUG_IN();
 
-      computeNormalsOnIntegrationPoints(mesh.getNodes(), ghost_type);
+  computeNormalsOnIntegrationPoints(mesh.getNodes(), ghost_type);
 
-      AKANTU_DEBUG_OUT();
-    }
+  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,
-                                          GhostType ghost_type) {
-      AKANTU_DEBUG_IN();
-
-      //  Real * coord = mesh.getNodes().data();
-      UInt spatial_dimension = mesh.getSpatialDimension();
-
-      // allocate the normal arrays
-      normals_on_integration_points.initialize(
-          *this, _nb_component = spatial_dimension,
-          _spatial_dimension = element_dimension, _ghost_type = ghost_type,
-          _element_kind = kind);
-
-      // loop over the type to build the normals
-      for (auto & type :
-           mesh.elementTypes(element_dimension, ghost_type, kind)) {
-        auto & normals_on_quad =
-            normals_on_integration_points(type, ghost_type);
-        computeNormalsOnIntegrationPoints(field, normals_on_quad, type,
-                                          ghost_type);
-      }
+/* -------------------------------------------------------------------------- */
+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,
+                                      GhostType ghost_type) {
+  AKANTU_DEBUG_IN();
 
-      AKANTU_DEBUG_OUT();
-    }
+  //  Real * coord = mesh.getNodes().data();
+  UInt spatial_dimension = mesh.getSpatialDimension();
+
+  // allocate the normal arrays
+  normals_on_integration_points.initialize(
+      *this, _nb_component = spatial_dimension,
+      _spatial_dimension = element_dimension, _ghost_type = ghost_type,
+      _element_kind = kind);
 
-    /* --------------------------------------------------------------------------
-     */
-    /**
-     * 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> & /*unused*/,
-                           const Array<Real> & /*unused*/,
-                           Array<Real> & /*unused*/, ElementType /*unused*/,
-                           GhostType /*unused*/) {
-            AKANTU_TO_IMPLEMENT();
-          }
-        };
+  // loop over the type to build the normals
+  for (auto & type : mesh.elementTypes(element_dimension, ghost_type, kind)) {
+    auto & 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> & /*unused*/,
+                       const Array<Real> & /*unused*/, Array<Real> & /*unused*/,
+                       ElementType /*unused*/, GhostType /*unused*/) {
+        AKANTU_TO_IMPLEMENT();
+      }
+    };
 
 #define COMPUTE_NORMALS_ON_INTEGRATION_POINTS(type)                            \
   fem.template computeNormalsOnIntegrationPoints<type>(field, normal,          \
                                                        ghost_type);
 
 #define AKANTU_SPECIALIZE_COMPUTE_NORMALS_ON_INTEGRATION_POINTS(kind)          \
   template <> struct ComputeNormalsOnIntegrationPoints<kind> {                 \
     template <template <ElementKind, class> class I,                           \
               template <ElementKind> class S, ElementKind k, class IOF>        \
     static void call(const FEEngineTemplate<I, S, k, IOF> & fem,               \
                      const Array<Real> & field, Array<Real> & normal,          \
                      ElementType type, 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)
+    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, ElementType type,
-            GhostType ghost_type) const {
-      fe_engine::details::ComputeNormalsOnIntegrationPoints<kind>::call(
-          *this, field, normal, type, ghost_type);
-    }
+  } // namespace details
+} // namespace fe_engine
 
-    /* --------------------------------------------------------------------------
-     */
-    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,
-                                          GhostType ghost_type) const {
-      AKANTU_DEBUG_IN();
-
-      if (type == _point_1) {
-        computeNormalsOnIntegrationPointsPoint1(field, normal, ghost_type);
-        return;
-      }
+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, ElementType type,
+                                      GhostType ghost_type) const {
+  fe_engine::details::ComputeNormalsOnIntegrationPoints<kind>::call(
+      *this, field, normal, type, ghost_type);
+}
 
-      UInt spatial_dimension = mesh.getSpatialDimension();
-      UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
-      UInt nb_points = getNbIntegrationPoints(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,
+                                      GhostType ghost_type) const {
+  AKANTU_DEBUG_IN();
 
-      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);
+  if (type == _point_1) {
+    computeNormalsOnIntegrationPointsPoint1(field, normal, ghost_type);
+    return;
+  }
 
-      const Matrix<Real> & quads =
-          integrator.template getIntegrationPoints<type>(ghost_type);
+  auto spatial_dimension = mesh.getSpatialDimension();
+  auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+  auto nb_points = getNbIntegrationPoints(type, ghost_type);
 
-      Array<Real>::matrix_iterator f_it =
-          f_el.begin(spatial_dimension, nb_nodes_per_element);
+  auto nb_element = mesh.getConnectivity(type, ghost_type).size();
+  normal.resize(nb_element * nb_points);
 
-      for (UInt elem = 0; elem < nb_element; ++elem) {
-        ElementClass<type>::computeNormalsOnNaturalCoordinates(
-            quads, *f_it, *normals_on_quad);
-        ++normals_on_quad;
-        ++f_it;
-      }
+  Array<Real> f_el(0, spatial_dimension * nb_nodes_per_element);
+  FEEngine::extractNodalToElementField(mesh, field, f_el, type, ghost_type);
 
-      AKANTU_DEBUG_OUT();
-    }
+  const auto & quads =
+      integrator.template getIntegrationPoints<type>(ghost_type);
 
-    /* --------------------------------------------------------------------------
-     */
-    /**
-     * 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*/,
-                       ElementType /*type*/, Vector<Real> & /*natural_coords*/,
-                       GhostType /*ghost_type*/) {
-        AKANTU_TO_IMPLEMENT();
-      }
-    };
+  for (auto && data :
+       zip(make_view(normal, spatial_dimension, nb_points),
+           make_view(f_el, spatial_dimension, nb_nodes_per_element))) {
+    ElementClass<type>::computeNormalsOnNaturalCoordinates(
+        quads, std::get<1>(data), std::get<0>(data));
+  }
+
+  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*/,
+                   ElementType /*type*/, Vector<Real> & /*natural_coords*/,
+                   GhostType /*ghost_type*/) {
+    AKANTU_TO_IMPLEMENT();
+  }
+};
 
 #define INVERSE_MAP(type)                                                      \
   shape_functions.template inverseMap<type>(real_coords, element,              \
                                             natural_coords, ghost_type);
 
 #define AKANTU_SPECIALIZE_INVERSE_MAP_HELPER(kind)                             \
   template <> struct InverseMapHelper<kind> {                                  \
     template <class S>                                                         \
     static void call(const S & shape_functions,                                \
                      const Vector<Real> & real_coords, UInt element,           \
                      ElementType type, Vector<Real> & natural_coords,          \
                      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)
+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, ElementType type,
-        Vector<Real> & natural_coords, GhostType ghost_type) const {
+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, ElementType type,
+    Vector<Real> & natural_coords, GhostType ghost_type) const {
 
-      AKANTU_DEBUG_IN();
+  AKANTU_DEBUG_IN();
 
-      InverseMapHelper<kind>::call(shape_functions, real_coords, element, type,
-                                   natural_coords, ghost_type);
+  InverseMapHelper<kind>::call(shape_functions, real_coords, element, type,
+                               natural_coords, ghost_type);
 
-      AKANTU_DEBUG_OUT();
-    }
+  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 & /*unused*/,
-                           const Vector<Real> & /*unused*/, UInt /*unused*/,
-                           ElementType /*unused*/, GhostType /*unused*/) {
-            AKANTU_TO_IMPLEMENT();
-          }
-        };
+/* -------------------------------------------------------------------------- */
+/**
+ * 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 & /*unused*/, const Vector<Real> & /*unused*/,
+                       UInt /*unused*/, ElementType /*unused*/,
+                       GhostType /*unused*/) {
+        AKANTU_TO_IMPLEMENT();
+      }
+    };
 
 #define CONTAINS(type)                                                         \
   contain = shape_functions.template contains<type>(real_coords, element,      \
                                                     ghost_type);
 
 #define AKANTU_SPECIALIZE_CONTAINS_HELPER(kind)                                \
   template <> struct ContainsHelper<kind> {                                    \
     template <template <ElementKind> class S, ElementKind k>                   \
     static bool call(const S<k> & shape_functions,                             \
                      const Vector<Real> & real_coords, UInt element,           \
                      ElementType type, 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)
+    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, ElementType type,
-        GhostType ghost_type) const {
-      return fe_engine::details::ContainsHelper<kind>::call(
-          shape_functions, real_coords, element, type, ghost_type);
-    }
+  } // namespace details
+} // namespace fe_engine
 
-    /* --------------------------------------------------------------------------
-     */
-    /**
-     * Helper class to be able to write a partial specialization on the element
-     * kind
-     */
-    namespace fe_engine {
-      namespace details {
-        template <ElementKind kind> struct ComputeShapesHelper {
-          template <class S>
-          static void call(const S & /*unused*/,
-                           const Vector<Real> & /*unused*/, UInt /*unused*/,
-                           const ElementType /*unused*/,
-                           Vector<Real> & /*unused*/, GhostType /*unused*/) {
-            AKANTU_TO_IMPLEMENT();
-          }
-        };
+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, ElementType type,
+    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 & /*unused*/, const Vector<Real> & /*unused*/,
+                       UInt /*unused*/, const ElementType /*unused*/,
+                       Vector<Real> & /*unused*/, GhostType /*unused*/) {
+        AKANTU_TO_IMPLEMENT();
+      }
+    };
 
 #define COMPUTE_SHAPES(type)                                                   \
   shape_functions.template computeShapes<type>(real_coords, element, shapes,   \
                                                ghost_type);
 
 #define AKANTU_SPECIALIZE_COMPUTE_SHAPES_HELPER(kind)                          \
   template <> struct ComputeShapesHelper<kind> {                               \
     template <class S>                                                         \
     static void call(const S & shape_functions,                                \
-                     const Vector<Real> & real_coords, UInt element,           \
-                     const ElementType type, Vector<Real> & shapes,            \
-                     GhostType ghost_type) {                                   \
+                     const Ref<const VectorXr> & real_coords, UInt element,    \
+                     const ElementType type, Ref<VectorXr> & 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)
+    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 Ref<const VectorXr> & real_coords, UInt element,
-    ElementType type, Ref<VectorXr> shapes,
-    GhostType ghost_type) const {
-AKANTU_DEBUG_IN();
+  } // 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 Ref<const VectorXr> & real_coords, UInt element, ElementType type,
+    Ref<VectorXr> shapes, GhostType ghost_type) const {
+  AKANTU_DEBUG_IN();
 
-      fe_engine::details::ComputeShapesHelper<kind>::call(
-          shape_functions, real_coords, element, type, shapes, ghost_type);
+  fe_engine::details::ComputeShapesHelper<kind>::call(
+      shape_functions, real_coords, element, type, shapes, ghost_type);
 
-      AKANTU_DEBUG_OUT();
-    }
+  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(const S & /*shape_functions*/,
-                           const Ref<const VectorXr> & /*real_coords*/,
-                           UInt /*element*/, ElementType /*type*/,
-                           Ref<MatrixXr> /*shape_derivatives*/,
-                           GhostType /*ghost_type*/) {
-            AKANTU_TO_IMPLEMENT();
-          }
-      };
+/* -------------------------------------------------------------------------- */
+/**
+ * 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(const S & /*shape_functions*/,
+                       const Ref<const VectorXr> & /*real_coords*/,
+                       UInt /*element*/, ElementType /*type*/,
+                       Ref<MatrixXr> /*shape_derivatives*/,
+                       GhostType /*ghost_type*/) {
+        AKANTU_TO_IMPLEMENT();
+      }
+    };
 
 #define COMPUTE_SHAPE_DERIVATIVES(type)                                        \
   Matrix<Real> coords_mat(real_coords.data(), shape_derivatives.rows(), 1);    \
   Tensor3<Real> shapesd_tensor(shape_derivatives.data(),                       \
                                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 Ref<const VectorXr> & real_coords, UInt element,    \
-                     ElementType type, Ref<MatrixXr> shape_derivatives,        \
-                     GhostType ghost_type) {                                   \
-      AKANTU_BOOST_KIND_ELEMENT_SWITCH(COMPUTE_SHAPE_DERIVATIVES, kind);
-      }
-    };
+                     const ElementType type, Ref<MatrixXr> 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 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 Ref<const VectorXr> & real_coords, UInt element, ElementType type,
-    Ref<MatrixXr> shape_derivatives, GhostType ghost_type) const {
-AKANTU_DEBUG_IN();
+    const Ref<const VectorXr> & real_coords, UInt element,
+    const ElementType & type, Ref<MatrixXr> 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);
+  fe_engine::details::ComputeShapeDerivativesHelper<kind>::call(
+      shape_functions, real_coords, element, type, shape_derivatives,
+      ghost_type);
 
-      AKANTU_DEBUG_OUT();
-    }
+  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 {};
+/* -------------------------------------------------------------------------- */
+/**
+ * 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,     \
-                     GhostType ghost_type) {                                   \
-      UInt nb_quad_points = 0;                                                 \
+    static Int call(const I<k, IOF> & integrator, const ElementType type,      \
+                    const GhostType & ghost_type) {                            \
+      Int 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)
+    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(ElementType type, GhostType ghost_type) const {
-      return fe_engine::details::GetNbIntegrationPointsHelper<kind>::call(
-          integrator, type, ghost_type);
-    }
+  } // namespace details
+} // namespace fe_engine
 
-    /* --------------------------------------------------------------------------
-     */
-    /**
-     * Helper class to be able to write a partial specialization on the element
-     * kind
-     */
-    namespace fe_engine {
-      namespace details {
-        template <ElementKind kind> struct GetShapesHelper {};
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+inline Int
+FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::getNbIntegrationPoints(
+    ElementType type, 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,                    \
                                     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)
+    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(
-        ElementType type, GhostType ghost_type, __attribute__((unused)) UInt id)
-        const {
-      return fe_engine::details::GetShapesHelper<kind>::call(shape_functions,
-                                                             type, ghost_type);
-    }
+  } // namespace details
+} // namespace fe_engine
 
-    /* --------------------------------------------------------------------------
-     */
-    /**
-     * Helper class to be able to write a partial specialization on the element
-     * kind
-     */
-    namespace fe_engine {
-      namespace details {
-        template <ElementKind kind> struct GetShapesDerivativesHelper {
-          template <template <ElementKind> class S, ElementKind k>
-          static const Array<Real> &
-          call(const S<k> & /*unused*/, ElementType /*unused*/,
-               GhostType /*unused*/, UInt /*unused*/) {
-            AKANTU_TO_IMPLEMENT();
-          }
-        };
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+inline const Array<Real> &
+FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::getShapes(
+    ElementType type, 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> & /*unused*/,
+                                      ElementType /*unused*/,
+                                      GhostType /*unused*/, UInt /*unused*/) {
+        AKANTU_TO_IMPLEMENT();
+      }
+    };
 
 #define GET_SHAPES_DERIVATIVES(type)                                           \
   ret = &(shape_functions.getShapesDerivatives(type, ghost_type));
 
 #define AKANTU_SPECIALIZE_GET_SHAPES_DERIVATIVES_HELPER(kind)                  \
   template <> struct GetShapesDerivativesHelper<kind> {                        \
     template <template <ElementKind> class S, ElementKind k>                   \
     static const Array<Real> &                                                 \
     call(const S<k> & shape_functions, const ElementType type,                 \
          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)
+    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(
-        ElementType type, GhostType ghost_type, __attribute__((unused)) UInt id)
-        const {
-      return fe_engine::details::GetShapesDerivativesHelper<kind>::call(
-          shape_functions, type, ghost_type, id);
-    }
+  } // namespace details
+} // namespace fe_engine
 
-    /* --------------------------------------------------------------------------
-     */
-    /**
-     * Helper class to be able to write a partial specialization on the element
-     * kind
-     */
-    namespace fe_engine {
-      namespace details {
-        template <ElementKind kind> struct GetIntegrationPointsHelper {};
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+inline const Array<Real> &
+FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::getShapesDerivatives(
+    ElementType type, 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,                   \
                                      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)
+    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(
-        ElementType type, GhostType ghost_type) const {
-      return fe_engine::details::GetIntegrationPointsHelper<kind>::call(
-          integrator, type, ghost_type);
-    }
+  } // 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>::printself(
-        std::ostream & stream, int indent) const {
-      std::string space(indent, 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>
+inline const Matrix<Real> &
+FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::getIntegrationPoints(
+    ElementType type, 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>::onElementsAdded(
-        const Array<Element> & new_elements,
-        const NewElementsEvent & /*unused*/) {
-      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>::printself(
+    std::ostream & stream, int indent) const {
+  std::string space(indent, 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>::onElementsRemoved(
-        const Array<Element> & /*unused*/,
-        const ElementTypeMapArray<UInt> & /*unused*/,
-        const RemovedElementsEvent & /*unused*/) {}
-
-    /* --------------------------------------------------------------------------
-     */
-    template <template <ElementKind, class> class I,
-              template <ElementKind> class S, ElementKind kind,
-              class IntegrationOrderFunctor>
-    void
-    FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::onElementsChanged(
-        const Array<Element> & /*unused*/, const Array<Element> & /*unused*/,
-        const ElementTypeMapArray<UInt> & /*unused*/,
-        const ChangedElementsEvent & /*unused*/) {}
-
-    /* --------------------------------------------------------------------------
-     */
-    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> & /*unused*/,
-                                                Array<Real> & normal,
-                                                GhostType ghost_type) const {
-      AKANTU_DEBUG_IN();
-
-      AKANTU_DEBUG_ASSERT(
-          mesh.getSpatialDimension() == 1,
-          "Mesh dimension must be 1 to compute normals on points!");
-      const auto type = _point_1;
-      auto spatial_dimension = mesh.getSpatialDimension();
-      // UInt nb_nodes_per_element  = Mesh::getNbNodesPerElement(type);
-      auto nb_points = getNbIntegrationPoints(type, ghost_type);
-      const auto & connectivity = mesh.getConnectivity(type, ghost_type);
-      auto nb_element = connectivity.size();
-
-      normal.resize(nb_element * nb_points);
-      auto normals_on_quad =
-          normal.begin_reinterpret(spatial_dimension, nb_points, nb_element);
-      const auto & segments = mesh.getElementToSubelement(type, ghost_type);
-      const auto & coords = mesh.getNodes();
-
-      const Mesh * mesh_segment;
-      if (mesh.isMeshFacets()) {
-        mesh_segment = &(mesh.getMeshParent());
+/* -------------------------------------------------------------------------- */
+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 & /*unused*/) {
+  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> & /*unused*/,
+    const ElementTypeMapArray<UInt> & /*unused*/,
+    const RemovedElementsEvent & /*unused*/) {}
+
+/* -------------------------------------------------------------------------- */
+template <template <ElementKind, class> class I, template <ElementKind> class S,
+          ElementKind kind, class IntegrationOrderFunctor>
+void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::onElementsChanged(
+    const Array<Element> & /*unused*/, const Array<Element> & /*unused*/,
+    const ElementTypeMapArray<UInt> & /*unused*/,
+    const ChangedElementsEvent & /*unused*/) {}
+
+/* -------------------------------------------------------------------------- */
+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> & /*unused*/,
+                                            Array<Real> & normal,
+                                            GhostType ghost_type) const {
+  AKANTU_DEBUG_IN();
+
+  AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == 1,
+                      "Mesh dimension must be 1 to compute normals on points!");
+  const auto type = _point_1;
+  auto spatial_dimension = mesh.getSpatialDimension();
+  // UInt nb_nodes_per_element  = Mesh::getNbNodesPerElement(type);
+  auto nb_points = getNbIntegrationPoints(type, ghost_type);
+  const auto & connectivity = mesh.getConnectivity(type, ghost_type);
+  auto nb_element = connectivity.size();
+
+  normal.resize(nb_element * nb_points);
+  auto normals_on_quad =
+      normal.begin_reinterpret(spatial_dimension, nb_points, nb_element);
+  const auto & segments = mesh.getElementToSubelement(type, ghost_type);
+  const auto & 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) {
+      auto point = connectivity(elem);
+      const auto segment = segments(elem)[0];
+      const auto & segment_connectivity =
+          mesh_segment->getConnectivity(segment.type, segment.ghost_type);
+      Vector<UInt> segment_points = segment_connectivity.begin(
+          Mesh::getNbNodesPerElement(segment.type))[segment.element];
+      Real difference;
+      if (segment_points(0) == point) {
+        difference = coords(elem) - coords(segment_points(1));
       } else {
-        mesh_segment = &mesh;
+        difference = coords(elem) - coords(segment_points(0));
       }
 
-      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) {
-          auto point = connectivity(elem);
-          const auto segment = segments(elem)[0];
-          const auto & segment_connectivity =
-              mesh_segment->getConnectivity(segment.type, segment.ghost_type);
-          Vector<UInt> segment_points = segment_connectivity.begin(
-              Mesh::getNbNodesPerElement(segment.type))[segment.element];
-          Real difference;
-          if (segment_points(0) == point) {
-            difference = coords(elem) - coords(segment_points(1));
-          } else {
-            difference = coords(elem) - coords(segment_points(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;
-      }
+      normal_value = difference / std::abs(difference);
+    }
 
-      AKANTU_DEBUG_OUT();
+    for (UInt n(0); n < nb_points; ++n) {
+      (*normals_on_quad)(0, n) = normal_value;
     }
+    ++normals_on_quad;
+  }
+
+  AKANTU_DEBUG_OUT();
+}
 
 } // namespace akantu
diff --git a/src/fe_engine/fe_engine_template_tmpl_field.hh b/src/fe_engine/fe_engine_template_tmpl_field.hh
index 7e82a2786..d1ef14530 100644
--- a/src/fe_engine/fe_engine_template_tmpl_field.hh
+++ b/src/fe_engine/fe_engine_template_tmpl_field.hh
@@ -1,507 +1,508 @@
 /**
  * @file   fe_engine_template_tmpl_field.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 09 2017
  * @date last modification: Sat Mar 13 2021
  *
  * @brief  implementation of the assemble field s functions
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "fe_engine_template.hh"
+//#include "fe_engine_template.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_FE_ENGINE_TEMPLATE_TMPL_FIELD_HH_
 #define AKANTU_FE_ENGINE_TEMPLATE_TMPL_FIELD_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Matrix lumping functions                                                   */
 /* -------------------------------------------------------------------------- */
 namespace fe_engine {
   namespace details {
     namespace {
       template <class Functor>
       void fillField(const Functor & field_funct, Array<Real> & field,
                      UInt nb_element, UInt nb_integration_points,
                      ElementType type, GhostType ghost_type) {
         UInt nb_degree_of_freedom = field.getNbComponent();
         field.resize(nb_integration_points * nb_element);
 
-        auto field_it = field.begin_reinterpret(
-            nb_degree_of_freedom, nb_integration_points, nb_element);
-
         Element el{type, 0, ghost_type};
-        for (; el.element < nb_element; ++el.element, ++field_it) {
-          field_funct(*field_it, el);
+        for (auto && data : enumerate(make_view(field, nb_degree_of_freedom,
+                                                nb_integration_points))) {
+          el.element = std::get<0>(data);
+          field_funct(std::get<1>(data), el);
         }
       }
     } // namespace
   }   // namespace details
 } // namespace fe_engine
 
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct AssembleLumpedTemplateHelper {
       template <template <ElementKind, class> class I,
                 template <ElementKind> class S, ElementKind k, class IOF>
       static void call(const FEEngineTemplate<I, S, k, IOF> & /*unused*/,
                        const std::function<void(Matrix<Real> &,
                                                 const Element &)> & /*unused*/,
                        const ID & /*unused*/, const ID & /*unused*/,
                        DOFManager & /*unused*/, ElementType /*unused*/,
                        GhostType /*unused*/) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define ASSEMBLE_LUMPED(type)                                                  \
   fem.template assembleFieldLumped<type>(field_funct, lumped, dof_id,          \
                                          dof_manager, ghost_type)
 
 #define AKANTU_SPECIALIZE_ASSEMBLE_HELPER(kind)                                \
   template <> struct AssembleLumpedTemplateHelper<kind> {                      \
     template <template <ElementKind, class> class I,                           \
               template <ElementKind> class S, ElementKind k, class IOF>        \
     static void                                                                \
     call(const FEEngineTemplate<I, S, k, IOF> & fem,                           \
          const std::function<void(Matrix<Real> &, const Element &)> &          \
              field_funct,                                                      \
          const ID & lumped, const ID & dof_id, DOFManager & dof_manager,       \
          ElementType type, GhostType ghost_type) {                             \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_LUMPED, kind);                 \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_ASSEMBLE_HELPER,
                                AKANTU_FE_ENGINE_LIST_ASSEMBLE_FIELDS)
 
 #undef AKANTU_SPECIALIZE_ASSEMBLE_HELPER
 #undef AKANTU_SPECIALIZE_ASSEMBLE_HELPER_LIST_KIND
 #undef ASSEMBLE_LUMPED
   } // namespace details
 } // namespace fe_engine
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IOF>
 void FEEngineTemplate<I, S, kind, IOF>::assembleFieldLumped(
     const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
     const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
     ElementType type, GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
   fe_engine::details::AssembleLumpedTemplateHelper<kind>::call(
       *this, field_funct, matrix_id, dof_id, dof_manager, type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldLumped(
     const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
     const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
     GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_degree_of_freedom = dof_manager.getDOFs(dof_id).getNbComponent();
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   UInt nb_integration_points = this->getNbIntegrationPoints(type);
 
   Array<Real> field(0, nb_degree_of_freedom);
   fe_engine::details::fillField(field_funct, field, nb_element,
                                 nb_integration_points, type, ghost_type);
 
   switch (type) {
   case _triangle_6:
   case _quadrangle_8:
   case _tetrahedron_10:
   case _hexahedron_20:
   case _pentahedron_15:
     this->template assembleLumpedDiagonalScaling<type>(field, matrix_id, dof_id,
                                                        dof_manager, ghost_type);
     break;
   default:
     this->template assembleLumpedRowSum<type>(field, matrix_id, dof_id,
                                               dof_manager, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV =
  * \int \rho \varphi_i dV @f$
  */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     assembleLumpedRowSum(const Array<Real> & field, const ID & matrix_id,
                          const ID & dof_id, DOFManager & dof_manager,
                          GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
-  UInt shapes_size = ElementClass<type>::getShapeSize();
-  UInt nb_degree_of_freedom = field.getNbComponent();
+  auto shapes_size = ElementClass<type>::getShapeSize();
+  auto nb_degree_of_freedom = field.getNbComponent();
 
-  auto * field_times_shapes =
-      new Array<Real>(0, shapes_size * nb_degree_of_freedom);
+  auto field_times_shapes =
+      std::make_shared<Array<Real>>(0, shapes_size * nb_degree_of_freedom);
 
   shape_functions.template computeNtb<type>(field, *field_times_shapes,
                                             ghost_type);
 
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
-  auto * int_field_times_shapes = new Array<Real>(
+  auto nb_element = mesh.getNbElement(type, ghost_type);
+  auto int_field_times_shapes = std::make_shared<Array<Real>>(
       nb_element, shapes_size * nb_degree_of_freedom, "inte_rho_x_shapes");
 
   integrator.template integrate<type>(
       *field_times_shapes, *int_field_times_shapes,
       nb_degree_of_freedom * shapes_size, ghost_type, empty_filter);
 
-  delete field_times_shapes;
-
   dof_manager.assembleElementalArrayToLumpedMatrix(
       dof_id, *int_field_times_shapes, matrix_id, type, ghost_type);
 
-  delete int_field_times_shapes;
-
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * @f$ \tilde{M}_{i} = c * M_{ii} = \int_{V_e} \rho dV @f$
  */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::
     assembleLumpedDiagonalScaling(const Array<Real> & field,
                                   const ID & matrix_id, const ID & dof_id,
                                   DOFManager & dof_manager,
                                   GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
-  ElementType type_p1 = ElementClass<type>::getP1ElementType();
-  UInt nb_nodes_per_element_p1 = Mesh::getNbNodesPerElement(type_p1);
-  UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
-  UInt nb_degree_of_freedom = field.getNbComponent();
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
+  const auto & type_p1 = ElementClass<type>::getP1ElementType();
+  auto nb_nodes_per_element_p1 = Mesh::getNbNodesPerElement(type_p1);
+  auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+  auto nb_degree_of_freedom = field.getNbComponent();
+  auto nb_element = mesh.getNbElement(type, ghost_type);
 
   Vector<Real> nodal_factor(nb_nodes_per_element);
 
 #define ASSIGN_WEIGHT_TO_NODES(corner, mid)                                    \
   {                                                                            \
-    for (UInt n = 0; n < nb_nodes_per_element_p1; n++)                         \
+    for (Int n = 0; n < nb_nodes_per_element_p1; n++)                          \
       nodal_factor(n) = corner;                                                \
-    for (UInt n = nb_nodes_per_element_p1; n < nb_nodes_per_element; n++)      \
+    for (Int n = nb_nodes_per_element_p1; n < nb_nodes_per_element; n++)       \
       nodal_factor(n) = mid;                                                   \
   }
 
   if (type == _triangle_6)
     ASSIGN_WEIGHT_TO_NODES(1. / 12., 1. / 4.);
   if (type == _tetrahedron_10)
     ASSIGN_WEIGHT_TO_NODES(1. / 32., 7. / 48.);
   if (type == _quadrangle_8)
     ASSIGN_WEIGHT_TO_NODES(
         3. / 76.,
         16. / 76.); /** coeff. derived by scaling
                      * the diagonal terms of the corresponding
                      * consistent mass computed with 3x3 gauss points;
                      * coeff. are (1./36., 8./36.) for 2x2 gauss points */
   if (type == _hexahedron_20)
     ASSIGN_WEIGHT_TO_NODES(
         7. / 248., 16. / 248.); /** coeff. derived by scaling
                                  * the diagonal terms of the corresponding
                                  * consistent mass computed with 3x3x3 gauss
                                  * points; coeff. are (1./40.,
                                  * 1./15.) for 2x2x2 gauss points */
   if (type == _pentahedron_15) {
     // coefficients derived by scaling the diagonal terms of the corresponding
     // consistent mass computed with 8 gauss points;
-    for (UInt n = 0; n < nb_nodes_per_element_p1; n++) {
+    for (Int n = 0; n < nb_nodes_per_element_p1; n++)
       nodal_factor(n) = 51. / 2358.;
     }
 
     Real mid_triangle = 192. / 2358.;
     Real mid_quadrangle = 300. / 2358.;
 
     nodal_factor(6) = mid_triangle;
     nodal_factor(7) = mid_triangle;
     nodal_factor(8) = mid_triangle;
     nodal_factor(9) = mid_quadrangle;
     nodal_factor(10) = mid_quadrangle;
     nodal_factor(11) = mid_quadrangle;
     nodal_factor(12) = mid_triangle;
     nodal_factor(13) = mid_triangle;
     nodal_factor(14) = mid_triangle;
   }
 
   if (nb_element == 0) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
 #undef ASSIGN_WEIGHT_TO_NODES
   /// compute @f$ \int \rho dV = \rho V @f$ for each element
   auto int_field = std::make_unique<Array<Real>>(
       field.size(), nb_degree_of_freedom, "inte_rho_x");
   integrator.template integrate<type>(field, *int_field, nb_degree_of_freedom,
                                       ghost_type, empty_filter);
 
   /// distribute the mass of the element to the nodes
   auto lumped_per_node = std::make_unique<Array<Real>>(
       nb_element, nb_degree_of_freedom * nb_nodes_per_element, "mass_per_node");
   auto int_field_it = int_field->begin(nb_degree_of_freedom);
   auto lumped_per_node_it =
       lumped_per_node->begin(nb_degree_of_freedom, nb_nodes_per_element);
 
   for (UInt e = 0; e < nb_element; ++e) {
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       Vector<Real> l = (*lumped_per_node_it)(n);
       l = *int_field_it;
       l *= nodal_factor(n);
     }
     ++int_field_it;
     ++lumped_per_node_it;
   }
 
   dof_manager.assembleElementalArrayToLumpedMatrix(dof_id, *lumped_per_node,
                                                    matrix_id, type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Helper class to be able to write a partial specialization on the element kind
  */
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct AssembleFieldMatrixHelper {
       template <template <ElementKind, class> class I,
                 template <ElementKind> class S, ElementKind k, class IOF>
       static void call(const FEEngineTemplate<I, S, k, IOF> & /*unused*/,
                        const std::function<void(Matrix<Real> &,
                                                 const Element &)> & /*unused*/,
                        const ID & /*unused*/, const ID & /*unused*/,
                        DOFManager & /*unused*/, ElementType /*unused*/,
                        GhostType /*unused*/) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #define ASSEMBLE_MATRIX(type)                                                  \
   fem.template assembleFieldMatrix<type>(field_funct, matrix_id, dof_id,       \
                                          dof_manager, ghost_type)
 
 #define AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER(kind)                   \
   template <> struct AssembleFieldMatrixHelper<kind> {                         \
     template <template <ElementKind, class> class I,                           \
               template <ElementKind> class S, ElementKind k, class IOF>        \
     static void                                                                \
     call(const FEEngineTemplate<I, S, k, IOF> & fem,                           \
          const std::function<void(Matrix<Real> &, const Element &)> &          \
              field_funct,                                                      \
          const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,    \
          ElementType type, GhostType ghost_type) {                             \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(ASSEMBLE_MATRIX, kind);                 \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER,
                                AKANTU_FE_ENGINE_LIST_ASSEMBLE_FIELDS)
 
 #undef AKANTU_SPECIALIZE_ASSEMBLE_FIELD_MATRIX_HELPER
 #undef ASSEMBLE_MATRIX
   } // namespace details
 } // namespace fe_engine
 
 /* -------------------------------------------------------------------------- */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IOF>
 void FEEngineTemplate<I, S, kind, IOF>::assembleFieldMatrix(
     const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
     const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
     ElementType type, GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
   fe_engine::details::AssembleFieldMatrixHelper<kind>::template call(
       *this, field_funct, matrix_id, dof_id, dof_manager, type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 namespace fe_engine {
   namespace details {
     template <ElementKind kind> struct ShapesForMassHelper {
       template <ElementType type, class ShapeFunctions>
       static auto getShapes(ShapeFunctions & shape_functions,
                             const Matrix<Real> & integration_points,
                             const Array<Real> & nodes,
                             UInt & nb_degree_of_freedom, UInt nb_element,
                             GhostType ghost_type) {
 
         UInt shapes_size = ElementClass<type>::getShapeSize();
         Array<Real> shapes(0, shapes_size);
 
         shape_functions.template computeShapesOnIntegrationPoints<type>(
             nodes, integration_points, shapes, ghost_type);
 
         UInt nb_integration_points = integration_points.cols();
         UInt vect_size = nb_integration_points * nb_element;
         UInt lmat_size = nb_degree_of_freedom * shapes_size;
 
         // Extending the shape functions
         /// \todo move this in the shape functions as Voigt format shapes to
         /// have the code in common with the structural elements
         auto shapes_voigt = std::make_unique<Array<Real>>(
             vect_size, lmat_size * nb_degree_of_freedom, 0.);
         auto mshapes_it = shapes_voigt->begin(nb_degree_of_freedom, lmat_size);
         auto shapes_it = shapes.begin(shapes_size);
 
         for (UInt q = 0; q < vect_size; ++q, ++mshapes_it, ++shapes_it) {
           for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
             for (UInt s = 0; s < shapes_size; ++s) {
               (*mshapes_it)(d, s * nb_degree_of_freedom + d) = (*shapes_it)(s);
             }
           }
         }
 
         return shapes_voigt;
       }
     };
 
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
     template <> struct ShapesForMassHelper<_ek_structural> {
       template <ElementType type, class ShapeFunctions>
       static auto getShapes(ShapeFunctions & shape_functions,
                             const Matrix<Real> & integration_points,
                             const Array<Real> & nodes,
                             UInt & nb_degree_of_freedom, UInt /*nb_element*/,
                             GhostType ghost_type) {
 
         auto nb_unknown = ElementClass<type>::getNbStressComponents();
         auto nb_degree_of_freedom_ = ElementClass<type>::getNbDegreeOfFreedom();
         auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
         auto shapes = std::make_unique<Array<Real>>(
             0, nb_unknown * nb_nodes_per_element * nb_degree_of_freedom_);
         nb_degree_of_freedom = nb_unknown;
         shape_functions.template computeShapesMassOnIntegrationPoints<type>(
             nodes, integration_points, *shapes, ghost_type);
 
         return shapes;
       }
     };
 #endif
   } // namespace details
 } // namespace fe_engine
   //
 /* -------------------------------------------------------------------------- */
 /**
  * @f$ \tilde{M}_{i} = \sum_j M_{ij} = \sum_j \int \rho \varphi_i \varphi_j dV =
  * \int \rho \varphi_i dV @f$
  */
 template <template <ElementKind, class> class I, template <ElementKind> class S,
           ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void FEEngineTemplate<I, S, kind, IntegrationOrderFunctor>::assembleFieldMatrix(
     const std::function<void(Matrix<Real> &, const Element &)> & field_funct,
     const ID & matrix_id, const ID & dof_id, DOFManager & dof_manager,
     GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
+  auto shapes_size = ElementClass<type>::getShapeSize();
+  auto nb_degree_of_freedom = dof_manager.getDOFs(dof_id).getNbComponent();
+  auto lmat_size = nb_degree_of_freedom * shapes_size;
+  auto nb_element = mesh.getNbElement(type, ghost_type);
+
   // \int N * N  so degree 2 * degree of N
-  const UInt polynomial_degree =
+  const auto polynomial_degree =
       2 * ElementClassProperty<type>::polynomial_degree;
 
   // getting the integration points
-  Matrix<Real> integration_points =
+  auto integration_points =
       integrator.template getIntegrationPoints<type, polynomial_degree>();
 
-  UInt nb_degree_of_freedom = dof_manager.getDOFs(dof_id).getNbComponent();
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
+  auto nb_integration_points = integration_points.cols();
+  auto vect_size = nb_integration_points * nb_element;
 
   // getting the shapes on the integration points
   auto shapes_voigt =
       fe_engine::details::ShapesForMassHelper<kind>::template getShapes<type>(
           shape_functions, integration_points, mesh.getNodes(),
           nb_degree_of_freedom, nb_element, ghost_type);
 
   auto vect_size = shapes_voigt->size();
 
   // getting the value to assemble on the integration points
   Array<Real> field(vect_size, nb_degree_of_freedom);
   fe_engine::details::fillField(field_funct, field, nb_element,
                                 integration_points.cols(), type, ghost_type);
 
   auto lmat_size = shapes_voigt->getNbComponent() / nb_degree_of_freedom;
 
   // computing \rho * N
-  Array<Real> local_mat(vect_size, lmat_size * lmat_size);
-  auto N_it = shapes_voigt->begin(nb_degree_of_freedom, lmat_size);
-  auto lmat_it = local_mat.begin(lmat_size, lmat_size);
-  auto field_it = field.begin_reinterpret(nb_degree_of_freedom, field.size());
-
-  for (UInt q = 0; q < vect_size; ++q, ++lmat_it, ++N_it, ++field_it) {
-    const auto & rho = *field_it;
-    const auto & N = *N_it;
-    auto & mat = *lmat_it;
+  mshapes_it = make_view(modified_shapes, nb_degree_of_freedom, lmat_size);
+  auto lmat = make_view(local_mat, lmat_size, lmat_size);
+  auto field_it = make_view(field, nb_degree_of_freedom);
+  for (auto && data :
+       zip(make_view(local_mat, lmat_size, lmat_size),
+           make_view(modified_shapes, nb_degree_of_freedom, lmat_size),
+           make_view(field, nb_degree_of_freedom))) {
+    const auto & rho = std::get<2>(data);
+    const auto & N = std::get<1>(data);
+    auto & mat = std::get<0>(data);
 
     Matrix<Real> Nt = N.transpose();
-    for (UInt d = 0; d < Nt.cols(); ++d) {
+    for (Int d = 0; d < Nt.cols(); ++d) {
       Nt(d) *= rho(d);
     }
 
     mat = Nt * N;
   }
 
   // integrate the elemental values
   Array<Real> int_field_times_shapes(nb_element, lmat_size * lmat_size,
                                      "inte_rho_x_shapes");
   this->integrator.template integrate<type, polynomial_degree>(
       local_mat, int_field_times_shapes, lmat_size * lmat_size, ghost_type);
 
   // assemble the elemental values to the matrix
   dof_manager.assembleElementalMatricesToMatrix(
       matrix_id, dof_id, int_field_times_shapes, type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_FE_ENGINE_TEMPLATE_TMPL_FIELD_HH_ */
diff --git a/src/fe_engine/gauss_integration_tmpl.hh b/src/fe_engine/gauss_integration_tmpl.hh
index 439c2bb93..e879729a3 100644
--- a/src/fe_engine/gauss_integration_tmpl.hh
+++ b/src/fe_engine/gauss_integration_tmpl.hh
@@ -1,287 +1,287 @@
 /**
  * @file   gauss_integration_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue May 10 2016
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  implementation of the gauss integration helpers
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_GAUSS_INTEGRATION_TMPL_HH_
 #define AKANTU_GAUSS_INTEGRATION_TMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* GaussIntegrationElement                                                    */
 /* -------------------------------------------------------------------------- */
 namespace _aka_gauss_helpers {
   template <GaussIntegrationType type, UInt n>
   struct GaussIntegrationNbPoints {
     static const UInt nb_points = 0;
   };
 
 #if !defined(DOXYGEN)
   template <UInt n> struct GaussIntegrationNbPoints<_git_not_defined, n> {
     static constexpr UInt nb_points = 0;
   };
 
   template <UInt n> struct GaussIntegrationNbPoints<_git_point, n> {
     static constexpr UInt nb_points = 1;
   };
 
   template <UInt n> struct GaussIntegrationNbPoints<_git_segment, n> {
     static constexpr UInt nb_points = (n + 1) / 2 + (bool((n + 1) % 2) ? 1 : 0);
   };
 
 #define DECLARE_GAUSS_NB_POINTS(type, order, points)                           \
   template <> struct GaussIntegrationNbPoints<type, order> {                   \
     static constexpr UInt nb_points = points;                                  \
   }
 
 #define DECLARE_GAUSS_NB_POINTS_PENT(type, order, xo, yo)                      \
   template <> struct GaussIntegrationNbPoints<type, order> {                   \
     static constexpr UInt x_order = xo;                                        \
     static constexpr UInt yz_order = yo;                                       \
     static constexpr UInt nb_points = 1;                                       \
   }
 
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 1, 1);
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 2, 3);
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 3, 4);
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 4, 6);
   DECLARE_GAUSS_NB_POINTS(_git_triangle, 5, 7);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 1, 1);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 2, 4);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 3, 5);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 4, 15);
   DECLARE_GAUSS_NB_POINTS(_git_tetrahedron, 5, 15);
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 1, 3,
                                2); // order 3 in x, order 2 in y and z
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 2, 3,
                                2); // order 3 in x, order 2 in y and z
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 3, 3,
                                3); // order 3 in x, order 3 in y and z
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 4, 5,
                                5); // order 5 in x, order 5 in y and z
   DECLARE_GAUSS_NB_POINTS_PENT(_git_pentahedron, 5, 5,
                                5); // order 5 in x, order 5 in y and z
 
   template <GaussIntegrationType type, UInt n, UInt on = n,
             bool end_recurse = false>
   struct GaussIntegrationNbPointsHelper {
     static constexpr UInt pnp = GaussIntegrationNbPoints<type, n>::nb_points;
     static constexpr UInt order = n;
     static constexpr UInt nb_points = pnp;
   };
 
   template <GaussIntegrationType type, UInt n, UInt on>
   struct GaussIntegrationNbPointsHelper<type, n, on, true> {
     static constexpr UInt nb_points = 0;
   };
 #endif
 
   /* ------------------------------------------------------------------------ */
   /* Generic helper                                                           */
   /* ------------------------------------------------------------------------ */
   template <GaussIntegrationType type, UInt dimension, UInt n>
   struct GaussIntegrationTypeDataHelper {
     using git_np = GaussIntegrationNbPoints<type, n>;
     using git_data = GaussIntegrationTypeData<type, git_np::nb_points>;
 
     static constexpr UInt getNbQuadraturePoints() { return git_np::nb_points; }
 
     static decltype(auto) getQuadraturePoints() {
       return Eigen::Map<
           const Eigen::Matrix<Real, dimension, git_np::nb_points>>(
           git_data::quad_positions);
     }
 
     static decltype(auto) getWeights() {
       return Eigen::Map<const Eigen::Matrix<Real, git_np::nb_points, 1>>(
           git_data::quad_weights);
     }
   };
 
 #if !defined(DOXYGEN)
   /* ------------------------------------------------------------------------ */
   /* helper for _segment _quadrangle _hexahedron                              */
   /* ------------------------------------------------------------------------ */
   template <UInt dimension, UInt dp>
   struct GaussIntegrationTypeDataHelper<_git_segment, dimension, dp> {
     using git_np = GaussIntegrationNbPoints<_git_segment, dp>;
     using git_data = GaussIntegrationTypeData<_git_segment, git_np::nb_points>;
 
     static constexpr UInt getNbQuadraturePoints() {
       return Math::pow<dimension>(git_np::nb_points);
     }
 
     static constexpr decltype(auto) getQuadraturePoints() {
       const auto tot_nquad = getNbQuadraturePoints();
       const auto nquad = git_np::nb_points;
 
       Eigen::Matrix<Real, dimension, tot_nquad> quads;
       Eigen::Map<const Eigen::Matrix<Real, nquad, 1>> pos(
           git_data::quad_positions);
 
       UInt offset = 1;
       for (UInt d = 0; d < dimension; ++d) {
         for (UInt n = 0, q = 0; n < tot_nquad; ++n, q += offset) {
           auto rq = q % tot_nquad + q / tot_nquad;
           quads(d, rq) = pos(n % nquad);
         }
         offset *= nquad;
       }
       return quads;
     }
 
     static constexpr decltype(auto) getWeights() {
       const auto tot_nquad = getNbQuadraturePoints();
       const auto nquad = git_np::nb_points;
 
       Eigen::Matrix<Real, tot_nquad, 1> quads_weights;
       quads_weights.fill(1);
       Eigen::Map<const Eigen::Matrix<Real, nquad, 1>> weights(
           git_data::quad_weights);
 
       UInt offset = 1;
       for (UInt d = 0; d < dimension; ++d) {
         for (UInt n = 0, q = 0; n < tot_nquad; ++n, q += offset) {
           UInt rq = q % tot_nquad + q / tot_nquad;
           quads_weights(rq) *= weights(n % nquad);
         }
         offset *= nquad;
       }
       return quads_weights;
     }
   };
 
   /* ------------------------------------------------------------------------ */
   /* helper for _pentahedron                                                  */
   /* ------------------------------------------------------------------------ */
   template <UInt dimension, UInt dp>
   struct GaussIntegrationTypeDataHelper<_git_pentahedron, dimension, dp> {
     using git_info = GaussIntegrationNbPoints<_git_pentahedron, dp>;
     using git_np_seg =
         GaussIntegrationNbPoints<_git_segment, git_info::x_order>;
     using git_np_tri =
         GaussIntegrationNbPoints<_git_triangle, git_info::yz_order>;
     using git_data_seg =
         GaussIntegrationTypeData<_git_segment, git_np_seg::nb_points>;
     using git_data_tri =
         GaussIntegrationTypeData<_git_triangle, git_np_tri::nb_points>;
 
     static UInt getNbQuadraturePoints() {
       return git_np_seg::nb_points * git_np_tri::nb_points;
     }
 
     static Matrix<Real> getQuadraturePoints() {
       UInt tot_nquad = getNbQuadraturePoints();
       UInt nquad_seg = git_np_seg::nb_points;
       UInt nquad_tri = git_np_tri::nb_points;
 
       Matrix<Real> quads(dimension, tot_nquad);
       Matrix<Real> pos_seg_w(git_data_seg::quad_positions, 1, nquad_seg);
       Matrix<Real> pos_tri_w(git_data_tri::quad_positions, 2, nquad_tri);
 
       for (UInt ns = 0, q = 0; ns < nquad_seg; ++ns) {
         Vector<Real> pos_seg = pos_seg_w(ns);
         for (UInt nt = 0; nt < nquad_tri; ++nt, ++q) {
           Vector<Real> pos_tri = pos_tri_w(nt);
           Vector<Real> quad = quads(q);
           quad(_x) = pos_seg(_x);
           quad(_y) = pos_tri(_x);
           quad(_z) = pos_tri(_y);
         }
       }
       return quads;
     }
 
     static const Vector<Real> getWeights() {
       const auto tot_nquad = getNbQuadraturePoints();
       const auto nquad_seg = git_np_seg::nb_points;
       const auto nquad_tri = git_np_tri::nb_points;
 
       Eigen::Matrix<Real, tot_nquad, 1> quads_weights;
 
       Eigen::Map<const Eigen::Matrix<Real, nquad_seg, 1>> weight_seg(
           git_data_seg::quad_weights);
       Eigen::Map<const Eigen::Matrix<Real, nquad_tri, 1>> weight_tri(
           git_data_tri::quad_weights);
 
       for (UInt ns = 0, q = 0; ns < nquad_seg; ++ns) {
         for (UInt nt = 0; nt < nquad_tri; ++nt, ++q) {
           quads_weights(q) = weight_seg(ns) * weight_tri(nt);
         }
       }
       return quads_weights;
     }
   };
 #endif
 } // namespace _aka_gauss_helpers
 
-template <ElementType element_type, UInt n>
+template <ElementType element_type, Int n>
 constexpr decltype(auto)
 GaussIntegrationElement<element_type, n>::getQuadraturePoints() {
   const InterpolationType itp_type =
       ElementClassProperty<element_type>::interpolation_type;
   using interpolation_property = InterpolationProperty<itp_type>;
   using data_helper = _aka_gauss_helpers::GaussIntegrationTypeDataHelper<
       ElementClassProperty<element_type>::gauss_integration_type,
       interpolation_property::natural_space_dimension, n>;
   return data_helper::getQuadraturePoints();
 }
 
 /* -------------------------------------------------------------------------- */
-template <ElementType element_type, UInt n>
+template <ElementType element_type, Int n>
 constexpr decltype(auto)
 GaussIntegrationElement<element_type, n>::getWeights() {
   const InterpolationType itp_type =
       ElementClassProperty<element_type>::interpolation_type;
   using interpolation_property = InterpolationProperty<itp_type>;
   using data_helper = _aka_gauss_helpers::GaussIntegrationTypeDataHelper<
       ElementClassProperty<element_type>::gauss_integration_type,
       interpolation_property::natural_space_dimension, n>;
   return data_helper::getWeights();
 }
 
 /* -------------------------------------------------------------------------- */
-template <ElementType element_type, UInt n>
-constexpr UInt
+template <ElementType element_type, Int n>
+constexpr Int
 GaussIntegrationElement<element_type, n>::getNbQuadraturePoints() {
   const InterpolationType itp_type =
       ElementClassProperty<element_type>::interpolation_type;
   using interpolation_property = InterpolationProperty<itp_type>;
   using data_helper = _aka_gauss_helpers::GaussIntegrationTypeDataHelper<
       ElementClassProperty<element_type>::gauss_integration_type,
       interpolation_property::natural_space_dimension, n>;
   return data_helper::getNbQuadraturePoints();
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_GAUSS_INTEGRATION_TMPL_HH_ */
diff --git a/src/fe_engine/geometrical_element_property.cc b/src/fe_engine/geometrical_element_property.cc
index 07807498b..69e049d11 100644
--- a/src/fe_engine/geometrical_element_property.cc
+++ b/src/fe_engine/geometrical_element_property.cc
@@ -1,63 +1,63 @@
 /**
  * @file   geometrical_element_property.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 29 2017
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Specialization of the geometrical types
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_class.hh"
 /* -------------------------------------------------------------------------- */
 #include <boost/preprocessor.hpp>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #define AKANTU_INSTANTIATE_TYPES(r, data, type)                                \
-  constexpr std::array<UInt, ElementClass<type>::getNbFacetTypes()>            \
+  constexpr std::array<Int, ElementClass<type>::getNbFacetTypes()>             \
       GeometricalElementProperty<                                              \
           ElementClassProperty<type>::geometrical_type>::nb_facets;            \
-  constexpr std::array<UInt, ElementClass<type>::getNbFacetTypes()>            \
+  constexpr std::array<Int, ElementClass<type>::getNbFacetTypes()>             \
       GeometricalElementProperty<                                              \
           ElementClassProperty<type>::geometrical_type>::nb_nodes_per_facet;   \
   constexpr std::array<                                                        \
-      UInt, detail::sizeFacetConnectivity<GeometricalElementProperty<          \
-                ElementClassProperty<type>::geometrical_type>>()>              \
+      Int, detail::sizeFacetConnectivity<GeometricalElementProperty<           \
+               ElementClassProperty<type>::geometrical_type>>()>               \
       GeometricalElementProperty<ElementClassProperty<                         \
           type>::geometrical_type>::facet_connectivity_vect;                   \
   constexpr std::array<ElementType, ElementClass<type>::getNbFacetTypes()>     \
       ElementClassExtraGeometryProperties<type>::facet_type;
 
 BOOST_PP_SEQ_FOR_EACH(AKANTU_INSTANTIATE_TYPES, _,
                       (_not_defined)AKANTU_ek_regular_ELEMENT_TYPE)
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 BOOST_PP_SEQ_FOR_EACH(AKANTU_INSTANTIATE_TYPES, _,
                       AKANTU_ek_cohesive_ELEMENT_TYPE)
 #endif
 
 } // namespace akantu
diff --git a/src/fe_engine/geometrical_element_property.hh b/src/fe_engine/geometrical_element_property.hh
index a2b7c09dc..0739a9d88 100644
--- a/src/fe_engine/geometrical_element_property.hh
+++ b/src/fe_engine/geometrical_element_property.hh
@@ -1,481 +1,481 @@
 /**
  * @file   geometrical_element_property.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Thomas Menouillard <tmenouillard@stucky.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 29 2017
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Specialization of the geometrical types
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_class.hh"
+//#include "element_class.hh"
 /* -------------------------------------------------------------------------- */
 #include <array>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 namespace detail {
   template <typename properties> constexpr size_t sizeFacetConnectivity() {
     size_t s = 0;
     for (size_t n = 0; n < properties::nb_facet_types; ++n) {
       s += properties::nb_facets[n] * properties::nb_nodes_per_facet[n];
     }
     return s == 0 ? 1 : s;
   }
 } // namespace detail
 
 #if !defined(DOXYGEN)
 template <> struct GeometricalElementProperty<_gt_not_defined> {
-  static constexpr UInt spatial_dimension{0};
-  static constexpr UInt nb_nodes_per_element{0};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{0}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{0}};
-  static constexpr std::array<UInt, 1> facet_connectivity_vect{{0}};
+  static constexpr Int spatial_dimension{0};
+  static constexpr Int nb_nodes_per_element{0};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{0}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{0}};
+  static constexpr std::array<Int, 1> facet_connectivity_vect{{0}};
 };
 
 template <> struct GeometricalElementProperty<_gt_point> {
-  static constexpr UInt spatial_dimension{0};
-  static constexpr UInt nb_nodes_per_element{1};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{1}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{1}};
-  static constexpr std::array<UInt, 1> facet_connectivity_vect{{0}};
+  static constexpr Int spatial_dimension{0};
+  static constexpr Int nb_nodes_per_element{1};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{1}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{1}};
+  static constexpr std::array<Int, 1> facet_connectivity_vect{{0}};
 };
 
 template <> struct GeometricalElementProperty<_gt_segment_2> {
-  static constexpr UInt spatial_dimension{1};
-  static constexpr UInt nb_nodes_per_element{2};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{1}};
-  static constexpr std::array<UInt, 2> facet_connectivity_vect{{0, 1}};
+  static constexpr Int spatial_dimension{1};
+  static constexpr Int nb_nodes_per_element{2};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{1}};
+  static constexpr std::array<Int, 2> facet_connectivity_vect{{0, 1}};
 };
 
 template <> struct GeometricalElementProperty<_gt_segment_3> {
-  static constexpr UInt spatial_dimension{1};
-  static constexpr UInt nb_nodes_per_element{3};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{1}};
+  static constexpr Int spatial_dimension{1};
+  static constexpr Int nb_nodes_per_element{3};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{1}};
   // clang-format off
-  static constexpr std::array<UInt, 2> facet_connectivity_vect{{0, 1}};
+  static constexpr std::array<Int, 2> facet_connectivity_vect{{0, 1}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_triangle_3> {
-  static constexpr UInt spatial_dimension{2};
-  static constexpr UInt nb_nodes_per_element{3};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{3}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{2}};
+  static constexpr Int spatial_dimension{2};
+  static constexpr Int nb_nodes_per_element{3};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{3}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{2}};
   // clang-format off
-    static constexpr std::array<UInt, 6> facet_connectivity_vect{{
+    static constexpr std::array<Int, 6> facet_connectivity_vect{{
         0, 1, 2,
         1, 2, 0}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_triangle_6> {
-  static constexpr UInt spatial_dimension{2};
-  static constexpr UInt nb_nodes_per_element{6};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{3}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
+  static constexpr Int spatial_dimension{2};
+  static constexpr Int nb_nodes_per_element{6};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{3}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
-    static constexpr std::array<UInt, 9> facet_connectivity_vect{{
+    static constexpr std::array<Int, 9> facet_connectivity_vect{{
         0, 1, 2,
         1, 2, 0,
         3, 4, 5}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_tetrahedron_4> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{4};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{4}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{4};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{4}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
-    static constexpr std::array<UInt, 12> facet_connectivity_vect{{
+    static constexpr std::array<Int, 12> facet_connectivity_vect{{
         0, 1, 2, 0,
         2, 2, 0, 1,
         1, 3, 3, 3}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_tetrahedron_10> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{10};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{4}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{6}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{10};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{4}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{6}};
   // clang-format off
-  static constexpr std::array<UInt, 6*4> facet_connectivity_vect{{
+  static constexpr std::array<Int, 6*4> facet_connectivity_vect{{
       0, 1, 2, 0,
       2, 2, 0, 1,
       1, 3, 3, 3,
       6, 5, 6, 4,
       5, 9, 7, 8,
       4, 8, 9, 7}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_quadrangle_4> {
-  static constexpr UInt spatial_dimension{2};
-  static constexpr UInt nb_nodes_per_element{4};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{4}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{2}};
+  static constexpr Int spatial_dimension{2};
+  static constexpr Int nb_nodes_per_element{4};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{4}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{2}};
   // clang-format off
-  static constexpr std::array<UInt, 2*4> facet_connectivity_vect{{
+  static constexpr std::array<Int, 2*4> facet_connectivity_vect{{
       0, 1, 2, 3,
       1, 2, 3, 0}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_quadrangle_8> {
-  static constexpr UInt spatial_dimension{2};
-  static constexpr UInt nb_nodes_per_element{8};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{4}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
+  static constexpr Int spatial_dimension{2};
+  static constexpr Int nb_nodes_per_element{8};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{4}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
-  static constexpr std::array<UInt, 4*3> facet_connectivity_vect{{
+  static constexpr std::array<Int, 4*3> facet_connectivity_vect{{
       0, 1, 2, 3,
       1, 2, 3, 0,
       4, 5, 6, 7}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_hexahedron_8> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{8};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{6}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{4}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{8};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{6}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{4}};
   // clang-format off
-  static constexpr std::array<UInt, 4*6> facet_connectivity_vect{{
+  static constexpr std::array<Int, 4*6> facet_connectivity_vect{{
       0, 0, 1, 2, 3, 4,
       3, 1, 2, 3, 0, 5,
       2, 5, 6, 7, 4, 6,
       1, 4, 5, 6, 7, 7}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_hexahedron_20> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{20};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{6}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{8}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{20};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{6}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{8}};
   // clang-format off
-  static constexpr std::array<UInt, 8*6> facet_connectivity_vect{{
+  static constexpr std::array<Int, 8*6> facet_connectivity_vect{{
       0,  1,  2,  3,  0,  4,
       1,  2,  3,  0,  3,  5,
       5,  6,  7,  4,  2,  6,
       4,  5,  6,  7,  1,  7,
       8,  9, 10, 11, 11, 16,
       13, 14, 15, 12, 10, 17,
       16, 17, 18, 19,  9, 18,
       12, 13, 14, 15,  8, 19}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_pentahedron_6> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{6};
-  static constexpr UInt nb_facet_types{2};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2, 3}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3, 4}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{6};
+  static constexpr Int nb_facet_types{2};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2, 3}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{3, 4}};
   // clang-format off
-  static constexpr std::array<UInt, 3*2 + 4*3> facet_connectivity_vect{{
+  static constexpr std::array<Int, 3*2 + 4*3> facet_connectivity_vect{{
       // first type
       0, 3,
       2, 4,
       1, 5,
       // second type
       0, 0, 1,
       1, 3, 2,
       4, 5, 5,
       3, 2, 4}};
   // clang-format on
 };
 
 template <> struct GeometricalElementProperty<_gt_pentahedron_15> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{15};
-  static constexpr UInt nb_facet_types{2};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2, 3}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{6, 8}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{15};
+  static constexpr Int nb_facet_types{2};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2, 3}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{6, 8}};
   // clang-format off
-  static constexpr std::array<UInt, 6*2 + 8*3> facet_connectivity_vect{{
+  static constexpr std::array<Int, 6*2 + 8*3> facet_connectivity_vect{{
       // first type
       0, 3,
       2, 4,
       1, 5,
       8, 12,
       7, 13,
       6, 14,
       // second type
        0, 0, 1,
        1, 3, 2,
        4, 5, 5,
        3, 2, 4,
        6, 9, 7,
       10, 14, 11,
       12, 11, 13,
        9, 8, 10}};
   // clang-format on
 };
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 /* -------------------------------------------------------------------------- */
 template <> struct GeometricalElementProperty<_gt_cohesive_2d_4> {
-  static constexpr UInt spatial_dimension{2};
-  static constexpr UInt nb_nodes_per_element{4};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{2}};
+  static constexpr Int spatial_dimension{2};
+  static constexpr Int nb_nodes_per_element{4};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{2}};
   // clang-format off
-  static constexpr std::array<UInt, 2 * 2> facet_connectivity_vect{{
+  static constexpr std::array<Int, 2 * 2> facet_connectivity_vect{{
       0, 2,
       1, 3}};
   // clang-format on
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct GeometricalElementProperty<_gt_cohesive_2d_6> {
-  static constexpr UInt spatial_dimension{2};
-  static constexpr UInt nb_nodes_per_element{6};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
+  static constexpr Int spatial_dimension{2};
+  static constexpr Int nb_nodes_per_element{6};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
-  static constexpr std::array<UInt, 3*2> facet_connectivity_vect{{
+  static constexpr std::array<Int, 3*2> facet_connectivity_vect{{
       0, 3,
       1, 4,
       2, 5}};
   // clang-format on
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct GeometricalElementProperty<_gt_cohesive_1d_2> {
-  static constexpr UInt spatial_dimension{1};
-  static constexpr UInt nb_nodes_per_element{2};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{1}};
+  static constexpr Int spatial_dimension{1};
+  static constexpr Int nb_nodes_per_element{2};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{1}};
   // clang-format off
-  static constexpr std::array<UInt, 2> facet_connectivity_vect{{0, 1}};
+  static constexpr std::array<Int, 2> facet_connectivity_vect{{0, 1}};
   // clang-format on
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct GeometricalElementProperty<_gt_cohesive_3d_6> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{6};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{3}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{6};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{3}};
   // clang-format off
-  static constexpr std::array<UInt, 3*2> facet_connectivity_vect{{
+  static constexpr std::array<Int, 3*2> facet_connectivity_vect{{
       0, 3,
       1, 4,
       2, 5}};
   // clang-format on
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct GeometricalElementProperty<_gt_cohesive_3d_12> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{12};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{6}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{12};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{6}};
   // clang-format off
-  static constexpr std::array<UInt, 6*2> facet_connectivity_vect{{
+  static constexpr std::array<Int, 6*2> facet_connectivity_vect{{
       0, 6,
       1, 7,
       2, 8,
       3, 9,
       4, 10,
       5, 11}};
   // clang-format on
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct GeometricalElementProperty<_gt_cohesive_3d_8> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{8};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{4}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{8};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{4}};
   // clang-format off
-  static constexpr std::array<UInt, 4*2> facet_connectivity_vect{{
+  static constexpr std::array<Int, 4*2> facet_connectivity_vect{{
       0, 4,
       1, 5,
       2, 6,
       3, 7}};
   // clang-format on
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct GeometricalElementProperty<_gt_cohesive_3d_16> {
-  static constexpr UInt spatial_dimension{3};
-  static constexpr UInt nb_nodes_per_element{16};
-  static constexpr UInt nb_facet_types{1};
-  static constexpr std::array<UInt, nb_facet_types> nb_facets{{2}};
-  static constexpr std::array<UInt, nb_facet_types> nb_nodes_per_facet{{8}};
+  static constexpr Int spatial_dimension{3};
+  static constexpr Int nb_nodes_per_element{16};
+  static constexpr Int nb_facet_types{1};
+  static constexpr std::array<Int, nb_facet_types> nb_facets{{2}};
+  static constexpr std::array<Int, nb_facet_types> nb_nodes_per_facet{{8}};
   // clang-format off
-  static constexpr std::array<UInt, 8*2> facet_connectivity_vect{{
+  static constexpr std::array<Int, 8*2> facet_connectivity_vect{{
       0, 8,
       1, 9,
       2, 10,
       3, 11,
       4, 12,
       5, 13,
       6, 14,
       7, 15}};
   // clang-format on
 };
 #endif // AKANTU_COHESIVE_ELEMENT
 
 /* -------------------------------------------------------------------------- */
 template <> struct ElementClassExtraGeometryProperties<_not_defined> {
   static constexpr ElementType p1_type{_not_defined};
   static constexpr std::array<ElementType, 1> facet_type{{_not_defined}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_point_1> {
   static constexpr ElementType p1_type{_point_1};
   static constexpr std::array<ElementType, 1> facet_type{{_point_1}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_segment_2> {
   static constexpr ElementType p1_type{_segment_2};
   static constexpr std::array<ElementType, 1> facet_type{{_point_1}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_segment_3> {
   static constexpr ElementType p1_type{_segment_2};
   static constexpr std::array<ElementType, 1> facet_type{{_point_1}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_triangle_3> {
   static constexpr ElementType p1_type{_triangle_3};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_2}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_triangle_6> {
   static constexpr ElementType p1_type{_triangle_3};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_tetrahedron_4> {
   static constexpr ElementType p1_type{_tetrahedron_4};
   static constexpr std::array<ElementType, 1> facet_type{{_triangle_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_tetrahedron_10> {
   static constexpr ElementType p1_type{_tetrahedron_4};
   static constexpr std::array<ElementType, 1> facet_type{{_triangle_6}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_quadrangle_4> {
   static constexpr ElementType p1_type{_quadrangle_4};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_2}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_quadrangle_8> {
   static constexpr ElementType p1_type{_quadrangle_4};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_hexahedron_8> {
   static constexpr ElementType p1_type{_hexahedron_8};
   static constexpr std::array<ElementType, 1> facet_type{{_quadrangle_4}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_hexahedron_20> {
   static constexpr ElementType p1_type{_hexahedron_8};
   static constexpr std::array<ElementType, 1> facet_type{{_quadrangle_8}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_pentahedron_6> {
   static constexpr ElementType p1_type{_pentahedron_6};
   static constexpr std::array<ElementType, 2> facet_type{
       {_triangle_3, _quadrangle_4}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_pentahedron_15> {
   static constexpr ElementType p1_type{_pentahedron_6};
   static constexpr std::array<ElementType, 2> facet_type{
       {_triangle_6, _quadrangle_8}};
 };
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 template <> struct ElementClassExtraGeometryProperties<_cohesive_2d_4> {
   static constexpr ElementType p1_type{_cohesive_2d_4};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_2}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_2d_6> {
   static constexpr ElementType p1_type{_cohesive_2d_4};
   static constexpr std::array<ElementType, 1> facet_type{{_segment_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_1d_2> {
   static constexpr ElementType p1_type{_cohesive_1d_2};
   static constexpr std::array<ElementType, 1> facet_type{{_point_1}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_3d_6> {
   static constexpr ElementType p1_type{_cohesive_3d_6};
   static constexpr std::array<ElementType, 1> facet_type{{_triangle_3}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_3d_12> {
   static constexpr ElementType p1_type{_cohesive_3d_6};
   static constexpr std::array<ElementType, 1> facet_type{{_triangle_6}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_3d_8> {
   static constexpr ElementType p1_type{_cohesive_3d_8};
   static constexpr std::array<ElementType, 1> facet_type{{_quadrangle_4}};
 };
 
 template <> struct ElementClassExtraGeometryProperties<_cohesive_3d_16> {
   static constexpr ElementType p1_type{_cohesive_3d_8};
   static constexpr std::array<ElementType, 1> facet_type{{_quadrangle_8}};
 };
 #endif // AKANTU_COHESIVE_ELEMENT
 
 #endif // !defined(DOXYGEN)
 
 } // namespace akantu
diff --git a/src/fe_engine/integrator.hh b/src/fe_engine/integrator.hh
index c034272a0..11c1d1760 100644
--- a/src/fe_engine/integrator.hh
+++ b/src/fe_engine/integrator.hh
@@ -1,138 +1,138 @@
 /**
  * @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: Tue Sep 29 2020
  *
  * @brief  interface for integrator classes
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "mesh.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class Integrator {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Integrator(const Mesh & mesh, UInt spatial_dimension,
              const ID & id = "integrator")
       : mesh(mesh), _spatial_dimension(spatial_dimension),
         jacobians("jacobians", id) {
     AKANTU_DEBUG_IN();
 
     AKANTU_DEBUG_OUT();
   };
 
   virtual ~Integrator() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// empty method
   template <ElementType type>
   inline void precomputeJacobiansOnQuadraturePoints(__attribute__((unused))
                                                     GhostType ghost_type) {}
 
   /// empty method
   void integrateOnElement(const Array<Real> & /*f*/, Real * /*intf*/,
                           UInt /*nb_degree_of_freedom*/,
                           const Element & /*elem*/,
                           GhostType /*ghost_type*/) const {};
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const {
     std::string space;
     for (Int i = 0; i < indent; i++, space += AKANTU_INDENT) {
       ;
     }
     stream << space << "Integrator [" << std::endl;
     jacobians.printself(stream, indent + 1);
     stream << space << "]" << std::endl;
   };
 
   /* ------------------------------------------------------------------------ */
 public:
   virtual void onElementsAdded(const Array<Element> & /*unused*/) {}
   virtual void
-  onElementsRemoved(const Array<Element> & /*unused*/,
-                    const ElementTypeMapArray<UInt> & new_numbering) {
+  onElementsRemoved(const Array<Element> &,
+                    const ElementTypeMapArray<Idx> & new_numbering) {
     jacobians.onElementsRemoved(new_numbering);
   }
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// access to the jacobians
   Array<Real> & getJacobians(ElementType type,
                              GhostType ghost_type = _not_ghost) {
     return jacobians(type, ghost_type);
   };
 
   /// access to the jacobians const
   const Array<Real> & getJacobians(ElementType type,
                                    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;
 
   // spatial dimension of the elements to consider
   UInt _spatial_dimension;
 
   /// jacobians for all elements
   ElementTypeMapArray<Real> jacobians;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 //#include "integrator_inline_impl.hh"
 
 /// 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 ec7dabd37..f14f045ea 100644
--- a/src/fe_engine/integrator_gauss.hh
+++ b/src/fe_engine/integrator_gauss.hh
@@ -1,205 +1,204 @@
 /**
  * @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: Tue Sep 29 2020
  *
  * @brief  Gauss integration facilities
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 integrator
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 class IntegratorGauss : public Integrator {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
-  IntegratorGauss(const Mesh & mesh, UInt spatial_dimension,
+  IntegratorGauss(const Mesh & mesh, Int spatial_dimension,
                   const ID & id = "integrator_gauss");
 
   ~IntegratorGauss() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initIntegrator(const Array<Real> & nodes, ElementType type,
                       GhostType ghost_type);
 
   template <ElementType type>
   inline void initIntegrator(const Array<Real> & nodes,
                              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, UInt elem,
-                                 GhostType ghost_type) const;
+                                 Int nb_degree_of_freedom, const Idx 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, GhostType ghost_type,
-                 const Array<UInt> & filter_elements) const;
+                 Int nb_degree_of_freedom, const GhostType & ghost_type,
+                 const Array<Int> & filter_elements) const;
 
   /// integrate scalar field in_f
-  template <ElementType type, UInt polynomial_degree>
+  template <ElementType type, Int polynomial_degree>
   Real integrate(const Array<Real> & in_f,
                  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,
-                 GhostType ghost_type) const;
+  Real integrate(const Vector<Real> & in_f, Idx index,
+                 const GhostType & ghost_type) const;
 
   /// integrate scalar field in_f
   template <ElementType type>
-  Real integrate(const Array<Real> & in_f, GhostType ghost_type,
-                 const Array<UInt> & filter_elements) const;
+  Real integrate(const Array<Real> & in_f, const GhostType & ghost_type,
+                 const Array<Int> & filter_elements) const;
 
   /// integrate a field without using the pre-computed values
-  template <ElementType type, UInt polynomial_degree>
+  template <ElementType type, Int polynomial_degree>
   void integrate(const Array<Real> & in_f, Array<Real> & intf,
-                 UInt nb_degree_of_freedom, GhostType ghost_type) const;
+                 Int 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,
-                                    GhostType ghost_type,
-                                    const Array<UInt> & filter_elements) const;
+                                    Int nb_degree_of_freedom,
+                                    const GhostType & ghost_type,
+                                    const Array<Int> & filter_elements) const;
 
   /// return a matrix with quadrature points natural coordinates
   template <ElementType type>
   const Matrix<Real> & getIntegrationPoints(GhostType ghost_type) const;
 
   /// return number of quadrature points
   template <ElementType type>
-  UInt getNbIntegrationPoints(GhostType ghost_type) const;
+  Int getNbIntegrationPoints(const GhostType & ghost_type) const;
 
-  template <ElementType type, UInt n> Matrix<Real> getIntegrationPoints() const;
-  template <ElementType type, UInt n>
-  Vector<Real> getIntegrationWeights() const;
+  template <ElementType type, Int n> Matrix<Real> getIntegrationPoints() const;
+  template <ElementType type, Int 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, GhostType ghost_type,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      Array<Real> & jacobians, const GhostType & ghost_type,
+      const Array<Int> & filter_elements = empty_filter) const;
 
   void computeJacobiansOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & quad_points,
-      Array<Real> & jacobians, ElementType type,
-      GhostType ghost_type,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      Array<Real> & jacobians, const ElementType & type,
+      const GhostType & ghost_type,
+      const Array<Int> & filter_elements = empty_filter) const;
 
   /// precompute jacobians on elements of type "type"
   template <ElementType type>
   void precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
                                              GhostType ghost_type);
 
   // multiply the jacobians by the integration weights and stores the results in
   // jacobians
-  template <ElementType type, UInt polynomial_degree>
+  template <ElementType type, Int polynomial_degree>
   void multiplyJacobiansByWeights(
       Array<Real> & jacobians,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      const Array<Int> & filter_elements = empty_filter) const;
 
   /// compute the vector of quadrature points natural coordinates
   template <ElementType type>
   void computeQuadraturePoints(GhostType ghost_type);
 
   /// check that the jacobians are not negative
   template <ElementType type>
   void checkJacobians(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,
+                                    Int nb_degree_of_freedom,
                                     const Array<Real> & jacobians,
-                                    UInt nb_element) const;
+                                    Int 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;
+                 Int nb_degree_of_freedom, const Array<Real> & jacobians,
+                 Int 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> & quad,
                                             Vector<Real> & jacobians) const;
 
 public:
   void onElementsAdded(const Array<Element> & elements) override;
 
   template <ElementType type>
-  void onElementsAddedByType(const Array<UInt> & new_elements,
-                             GhostType ghost_type);
+  void onElementsAddedByType(const Array<Idx> & new_elements,
+                             const GhostType & ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* 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;
+                        Int nb_degree_of_freedom,
+                        Int nb_quadrature_points) const;
 
 private:
   /// ElementTypeMap of the quadrature points
   ElementTypeMap<Matrix<Real>> quadrature_points;
 };
 
 } // namespace akantu
 
 #include "integrator_gauss_inline_impl.hh"
 
 #endif /* AKANTU_INTEGRATOR_GAUSS_HH_ */
diff --git a/src/fe_engine/integrator_gauss_inline_impl.hh b/src/fe_engine/integrator_gauss_inline_impl.hh
index dcc1f17a7..7d82717dc 100644
--- a/src/fe_engine/integrator_gauss_inline_impl.hh
+++ b/src/fe_engine/integrator_gauss_inline_impl.hh
@@ -1,759 +1,752 @@
 /**
  * @file   integrator_gauss_inline_impl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Feb 15 2011
  * @date last modification: Tue Oct 27 2020
  *
  * @brief  inline function of gauss integrator
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "fe_engine.hh"
 #include "mesh_iterators.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace debug {
   struct IntegratorGaussException : public Exception {};
 } // namespace debug
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::integrateOnElement(
-    const Array<Real> & f, Real * intf, UInt nb_degree_of_freedom,
-    const UInt elem, GhostType ghost_type) const {
-  Array<Real> & jac_loc = jacobians(type, ghost_type);
+    const Array<Real> & f, Real * intf, Int nb_degree_of_freedom,
+    const Idx elem, const GhostType & ghost_type) const {
+  auto & jac_loc = jacobians(type, ghost_type);
 
-  UInt nb_quadrature_points = ElementClass<type>::getNbQuadraturePoints();
+  auto nb_quadrature_points = ElementClass<type>::getNbQuadraturePoints();
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
                       "The vector f do not have the good number of component.");
 
-  Real * f_val = f.data() + elem * f.getNbComponent();
-  Real * jac_val = jac_loc.data() + elem * nb_quadrature_points;
+  auto * f_val = f.data() + elem * f.getNbComponent();
+  auto * jac_val = jac_loc.data() + elem * nb_quadrature_points;
 
   integrate(f_val, jac_val, intf, nb_degree_of_freedom, nb_quadrature_points);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
-    const Vector<Real> & in_f, UInt index, GhostType ghost_type) const {
+    const Vector<Real> & in_f, Idx index, const GhostType & ghost_type) const {
   const Array<Real> & jac_loc = jacobians(type, ghost_type);
 
-  UInt nb_quadrature_points =
+  auto nb_quadrature_points =
       GaussIntegrationElement<type>::getNbQuadraturePoints();
   AKANTU_DEBUG_ASSERT(in_f.size() == nb_quadrature_points,
                       "The vector f do not have nb_quadrature_points entries.");
 
-  Real * jac_val = jac_loc.data() + index * nb_quadrature_points;
+  auto * jac_val = jac_loc.data() + index * nb_quadrature_points;
   Real intf;
 
   integrate(in_f.data(), jac_val, &intf, 1, nb_quadrature_points);
 
   return intf;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
-    Real * f, Real * jac, Real * inte, UInt nb_degree_of_freedom,
-    UInt nb_quadrature_points) const {
+    Real * f, Real * jac, Real * inte, Int nb_degree_of_freedom,
+    Int nb_quadrature_points) const {
   std::fill_n(inte, nb_degree_of_freedom, 0.);
 
-  Real * cjac = jac;
-  for (UInt q = 0; q < nb_quadrature_points; ++q) {
-    for (UInt dof = 0; dof < nb_degree_of_freedom; ++dof) {
+  auto * cjac = jac;
+  for (Int q = 0; q < nb_quadrature_points; ++q) {
+    for (Int dof = 0; dof < nb_degree_of_freedom; ++dof) {
       inte[dof] += *f * *cjac;
       ++f;
     }
     ++cjac;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline const Matrix<Real> &
 IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationPoints(
     GhostType ghost_type) const {
   AKANTU_DEBUG_ASSERT(
       quadrature_points.exists(type, ghost_type),
       "Quadrature points for type "
           << quadrature_points.printType(type, ghost_type)
           << " have not been initialized."
           << " Did you use 'computeQuadraturePoints' function ?");
   return quadrature_points(type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
-inline UInt
+inline Int
 IntegratorGauss<kind, IntegrationOrderFunctor>::getNbIntegrationPoints(
     GhostType ghost_type) const {
   AKANTU_DEBUG_ASSERT(
       quadrature_points.exists(type, ghost_type),
       "Quadrature points for type "
           << quadrature_points.printType(type, ghost_type)
           << " have not been initialized."
           << " Did you use 'computeQuadraturePoints' function ?");
   return quadrature_points(type, ghost_type).cols();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
-template <ElementType type, UInt polynomial_degree>
+template <ElementType type, Int polynomial_degree>
 inline Matrix<Real>
 IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationPoints() const {
   return GaussIntegrationElement<type,
                                  polynomial_degree>::getQuadraturePoints();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
-template <ElementType type, UInt polynomial_degree>
+template <ElementType type, Int polynomial_degree>
 inline Vector<Real>
 IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationWeights() const {
   return GaussIntegrationElement<type, polynomial_degree>::getWeights();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void
 IntegratorGauss<kind, IntegrationOrderFunctor>::computeQuadraturePoints(
     GhostType ghost_type) {
   Matrix<Real> & quads = quadrature_points(type, ghost_type);
-  const UInt polynomial_degree =
+  const Int polynomial_degree =
       IntegrationOrderFunctor::template getOrder<type>();
   quads =
       GaussIntegrationElement<type, polynomial_degree>::getQuadraturePoints();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::
     computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
                                          const Matrix<Real> & quad,
                                          Vector<Real> & jacobians) const {
   // jacobian
   ElementClass<type>::computeJacobian(quad, node_coords, jacobians);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 IntegratorGauss<kind, IntegrationOrderFunctor>::IntegratorGauss(
-    const Mesh & mesh, UInt spatial_dimension, const ID & id)
+    const Mesh & mesh, Int spatial_dimension, const ID & id)
     : Integrator(mesh, spatial_dimension, id) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::checkJacobians(
     GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
-  UInt nb_quadrature_points = this->quadrature_points(type, ghost_type).cols();
-
-  UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
-
+  Int nb_quadrature_points = this->quadrature_points(type, ghost_type).cols();
+  Int nb_element = mesh.getConnectivity(type, ghost_type).size();
   Real * jacobians_val = jacobians(type, ghost_type).data();
 
-  for (UInt i = 0; i < nb_element * nb_quadrature_points;
+  for (Idx i = 0; i < nb_element * nb_quadrature_points;
        ++i, ++jacobians_val) {
     if (*jacobians_val < 0) {
       AKANTU_CUSTOM_EXCEPTION_INFO(debug::IntegratorGaussException{},
                                    "Negative jacobian computed,"
                                        << " possible problem in the element "
                                           "node ordering (Quadrature Point "
                                        << i % nb_quadrature_points << ":"
                                        << i / nb_quadrature_points << ":"
                                        << type << ":" << ghost_type << ")");
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
         const Array<Real> & nodes, const Matrix<Real> & quad_points,
-        Array<Real> & jacobians, GhostType ghost_type,
-        const Array<UInt> & filter_elements) const {
+        Array<Real> & jacobians, const GhostType & ghost_type,
+        const Array<Idx> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
-  UInt spatial_dimension = mesh.getSpatialDimension();
-  UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
-  UInt nb_quadrature_points = quad_points.cols();
+  auto spatial_dimension = mesh.getSpatialDimension();
+  auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+  auto nb_quadrature_points = quad_points.cols();
+  auto nb_element = mesh.getNbElement(type, ghost_type);
 
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
   jacobians.resize(nb_element * nb_quadrature_points);
 
-  auto jacobians_it =
-      jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
+  auto jacobians_it = make_view(jacobians, nb_quadrature_points).begin();
   auto jacobians_begin = jacobians_it;
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
                                        filter_elements);
 
-  auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
+  auto x_it = make_view(x_el, spatial_dimension, nb_nodes_per_element).begin();
 
   nb_element = x_el.size();
 
   //  Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
-  for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
-    const Matrix<Real> & x = *x_it;
-
+  for (Idx elem = 0; elem < nb_element; ++elem, ++x_it) {
+    const auto & x = *x_it;
     if (filter_elements != empty_filter) {
       jacobians_it = jacobians_begin + filter_elements(elem);
     }
 
-    Vector<Real> & J = *jacobians_it;
+    auto & J = *jacobians_it;
     computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
 
     if (filter_elements == empty_filter) {
       ++jacobians_it;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 template <>
 template <ElementType type>
 void IntegratorGauss<_ek_structural, DefaultIntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
         const Array<Real> & nodes, const Matrix<Real> & quad_points,
-        Array<Real> & jacobians, GhostType ghost_type,
-        const Array<UInt> & filter_elements) const {
+        Array<Real> & jacobians, const GhostType & ghost_type,
+        const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
-  const UInt spatial_dimension = mesh.getSpatialDimension();
-  const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
-  const UInt nb_quadrature_points = quad_points.cols();
-  const UInt nb_dofs = ElementClass<type>::getNbDegreeOfFreedom();
+  const auto spatial_dimension = mesh.getSpatialDimension();
+  const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+  const auto nb_quadrature_points = quad_points.cols();
+  const auto nb_dofs = ElementClass<type>::getNbDegreeOfFreedom();
 
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
+  auto nb_element = mesh.getNbElement(type, ghost_type);
   jacobians.resize(nb_element * nb_quadrature_points);
 
-  auto jacobians_it =
-      jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
+  auto jacobians_it = make_view(jacobians, nb_quadrature_points).begin();
   auto jacobians_begin = jacobians_it;
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
                                        filter_elements);
 
-  auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
+  auto x_it = make_view(x_el, spatial_dimension, nb_nodes_per_element).begin();
 
   nb_element = x_el.size();
 
-  const bool has_extra_normal =
+  const auto has_extra_normal =
       mesh.hasData<Real>("extra_normal", type, ghost_type);
   Array<Real>::const_vector_iterator extra_normal;
   Array<Real>::const_vector_iterator extra_normal_begin;
   if (has_extra_normal) {
     extra_normal = mesh.getData<Real>("extra_normal", type, ghost_type)
                        .begin(spatial_dimension);
     extra_normal_begin = extra_normal;
   }
 
   //  Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
-  for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
+  for (Idx elem = 0; elem < nb_element; ++elem, ++x_it) {
     if (filter_elements != empty_filter) {
       jacobians_it = jacobians_begin + filter_elements(elem);
       extra_normal = extra_normal_begin + filter_elements(elem);
     }
 
-    const Matrix<Real> & X = *x_it;
-    Vector<Real> & J = *jacobians_it;
+    const auto & X = *x_it;
+    auto & J = *jacobians_it;
     Matrix<Real> R(nb_dofs, nb_dofs);
 
     if (has_extra_normal) {
       ElementClass<type>::computeRotationMatrix(R, X, *extra_normal);
     } else {
       ElementClass<type>::computeRotationMatrix(R, X, Vector<Real>(X.rows()));
     }
     // Extracting relevant lines
     auto x = (R.block(0, 0, spatial_dimension, spatial_dimension) * X)
                  .block(0, 0, ElementClass<type>::getNaturalSpaceDimension(),
                         ElementClass<type>::getNbNodesPerElement());
 
     computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
 
     if (filter_elements == empty_filter) {
       ++jacobians_it;
       ++extra_normal;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_COHESIVE_ELEMENT)
 template <>
 template <ElementType type>
 void IntegratorGauss<_ek_cohesive, DefaultIntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
         const Array<Real> & nodes, const Matrix<Real> & quad_points,
-        Array<Real> & jacobians, GhostType ghost_type,
-        const Array<UInt> & filter_elements) const {
+        Array<Real> & jacobians, const GhostType & ghost_type,
+        const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
-  UInt spatial_dimension = mesh.getSpatialDimension();
-  UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
-  UInt nb_quadrature_points = quad_points.cols();
+  auto spatial_dimension = mesh.getSpatialDimension();
+  auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+  auto nb_quadrature_points = quad_points.cols();
+  auto nb_element = mesh.getNbElement(type, ghost_type);
 
-  UInt nb_element = mesh.getNbElement(type, ghost_type);
   jacobians.resize(nb_element * nb_quadrature_points);
 
-  auto jacobians_begin =
-      jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
+  auto jacobians_begin = make_view(jacobians, nb_quadrature_points).begin();
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
                                        filter_elements);
 
-  auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
+  auto x_it = make_view(x_el, spatial_dimension, nb_nodes_per_element).begin();
 
-  UInt nb_nodes_per_subelement = nb_nodes_per_element / 2;
+  auto nb_nodes_per_subelement = nb_nodes_per_element / 2;
   Matrix<Real> x(spatial_dimension, nb_nodes_per_subelement);
 
   nb_element = x_el.size();
-  UInt l_el = 0;
+  Idx l_el = 0;
+
   auto compute = [&](const auto & el) {
-    Vector<Real> J(jacobians_begin[el]);
-    Matrix<Real> X(x_it[l_el]);
+    auto && J = jacobians_begin[el];
+    auto && X = x_it[l_el];
     ++l_el;
 
-    for (UInt n = 0; n < nb_nodes_per_subelement; ++n) {
-      Vector<Real>(x(n)) =
-          (Vector<Real>(X(n)) + Vector<Real>(X(n + nb_nodes_per_subelement))) /
-          2.;
-    }
+    for (Int n = 0; n < nb_nodes_per_subelement; ++n)
+      x(n) = (X(n) + X(n + nb_nodes_per_subelement)) / 2.;
 
     if (type == _cohesive_1d_2) {
       J(0) = 1;
     } else {
       this->computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
     }
   };
 
   for_each_element(nb_element, filter_elements, compute);
 
   AKANTU_DEBUG_OUT();
 }
 #endif
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
                                           GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & jacobians_tmp = jacobians.alloc(0, 1, type, ghost_type);
 
   this->computeJacobiansOnIntegrationPoints<type>(
       nodes, quadrature_points(type, ghost_type), jacobians_tmp, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
-template <ElementType type, UInt polynomial_degree>
+template <ElementType type, Int polynomial_degree>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::multiplyJacobiansByWeights(
-    Array<Real> & jacobians, const Array<UInt> & filter_elements) const {
+    Array<Real> & jacobians, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
-  UInt nb_quadrature_points =
+  auto nb_quadrature_points =
       GaussIntegrationElement<type, polynomial_degree>::getNbQuadraturePoints();
 
-  Vector<Real> weights =
-      GaussIntegrationElement<type, polynomial_degree>::getWeights();
+  auto weights = GaussIntegrationElement<type, polynomial_degree>::getWeights();
 
   auto && view = make_view(jacobians, nb_quadrature_points);
 
   if (filter_elements != empty_filter) {
     auto J_it = view.begin();
     for (auto el : filter_elements) {
-      Vector<Real> J(J_it[el]);
+      auto && J = J_it[el];
       J *= weights;
     }
   } else {
     for (auto & J : make_view(jacobians, nb_quadrature_points)) {
       J *= weights;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
-    const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
-    const Array<Real> & jacobians, UInt nb_element) const {
+    const Array<Real> & in_f, Array<Real> & intf, Int nb_degree_of_freedom,
+    const Array<Real> & jacobians, Int nb_element) const {
   AKANTU_DEBUG_IN();
 
   intf.resize(nb_element);
   if (nb_element == 0) {
     return;
   }
 
-  UInt nb_points = jacobians.size() / nb_element;
+  auto nb_points = jacobians.size() / nb_element;
 
   for (auto && data : zip(make_view(in_f, nb_degree_of_freedom, nb_points),
                           make_view(intf, nb_degree_of_freedom),
                           make_view(jacobians, nb_points))) {
     auto && inte_f = std::get<0>(data);
     auto && f = std::get<1>(data);
     auto && J = std::get<2>(data);
 
     inte_f = f * J;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
-    const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    const Array<Real> & in_f, Array<Real> & intf, Int nb_degree_of_freedom,
+    const GhostType & ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
                       "No jacobians for the type "
                           << jacobians.printType(type, ghost_type));
 
-  const Array<Real> & jac_loc = jacobians(type, ghost_type);
+  const auto & jac_loc = jacobians(type, ghost_type);
   if (filter_elements != empty_filter) {
-    UInt nb_element = filter_elements.size();
-    auto * filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
+    auto nb_element = filter_elements.size();
+    auto filtered_J =
+        std::make_shared<Array<Real>>(0, jac_loc.getNbComponent());
     FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
                                   filter_elements);
     this->integrate(in_f, intf, nb_degree_of_freedom, *filtered_J, nb_element);
-    delete filtered_J;
   } else {
-    UInt nb_element = mesh.getNbElement(type, ghost_type);
+    auto nb_element = mesh.getNbElement(type, ghost_type);
     this->integrate(in_f, intf, nb_degree_of_freedom, jac_loc, nb_element);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
-template <ElementType type, UInt polynomial_degree>
+template <ElementType type, Int polynomial_degree>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
-    const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
-    GhostType ghost_type) const {
+    const Array<Real> & in_f, Array<Real> & intf, Int nb_degree_of_freedom,
+    const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
-  Matrix<Real> quads = this->getIntegrationPoints<type, polynomial_degree>();
+  auto quads = this->getIntegrationPoints<type, polynomial_degree>();
 
   Array<Real> jacobians;
   this->computeJacobiansOnIntegrationPoints<type>(mesh.getNodes(), quads,
                                                   jacobians, ghost_type);
   this->multiplyJacobiansByWeights<type, polynomial_degree>(jacobians);
 
   this->integrate(in_f, intf, nb_degree_of_freedom, jacobians,
                   mesh.getNbElement(type, ghost_type));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
-template <ElementType type, UInt polynomial_degree>
+template <ElementType type, Int polynomial_degree>
 Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, GhostType ghost_type) const {
   AKANTU_DEBUG_IN();
 
   Array<Real> intfv(0, 1);
   integrate<type, polynomial_degree>(in_f, intfv, 1, ghost_type);
 
-  Real res = Math::reduce(intfv);
+  auto res = Math::reduce(intfv);
 
   AKANTU_DEBUG_OUT();
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
-    const Array<Real> & in_f, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const Array<Real> & in_f, const GhostType & ghost_type,
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
                       "No jacobians for the type "
                           << jacobians.printType(type, ghost_type));
 
   Array<Real> intfv(0, 1);
   integrate<type>(in_f, intfv, 1, ghost_type, filter_elements);
 
-  Real res = Math::reduce(intfv);
+  auto res = Math::reduce(intfv);
 
   AKANTU_DEBUG_OUT();
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     integrateOnIntegrationPoints(const Array<Real> & in_f, Array<Real> & intf,
-                                 UInt nb_degree_of_freedom,
+                                 Int nb_degree_of_freedom,
                                  const Array<Real> & jacobians,
-                                 UInt nb_element) const {
+                                 Int nb_element) const {
   AKANTU_DEBUG_IN();
 
-  UInt nb_points = jacobians.size() / nb_element;
+  auto nb_points = jacobians.size() / nb_element;
 
   intf.resize(nb_element * nb_points);
 
   auto J_it = jacobians.begin();
   auto f_it = in_f.begin(nb_degree_of_freedom);
   auto inte_it = intf.begin(nb_degree_of_freedom);
 
-  for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
-    const Real & J = *J_it;
-    const Vector<Real> & f = *f_it;
-    Vector<Real> & inte_f = *inte_it;
+  for (Idx el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
+    const auto & J = *J_it;
+    const auto & f = *f_it;
+    auto & inte_f = *inte_it;
 
     inte_f = f;
     inte_f *= J;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     integrateOnIntegrationPoints(const Array<Real> & in_f, Array<Real> & intf,
-                                 UInt nb_degree_of_freedom,
-                                 GhostType ghost_type,
-                                 const Array<UInt> & filter_elements) const {
+                                 Int nb_degree_of_freedom,
+                                 const GhostType & ghost_type,
+                                 const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
                       "No jacobians for the type "
                           << jacobians.printType(type, ghost_type));
 
-  const Array<Real> & jac_loc = this->jacobians(type, ghost_type);
+  const auto & jac_loc = this->jacobians(type, ghost_type);
 
   if (filter_elements != empty_filter) {
 
-    UInt nb_element = filter_elements.size();
-    auto * filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
+    auto nb_element = filter_elements.size();
+    auto filtered_J =
+        std::make_shared<Array<Real>>(0, jac_loc.getNbComponent());
     FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
                                   filter_elements);
 
     this->integrateOnIntegrationPoints(in_f, intf, nb_degree_of_freedom,
                                        *filtered_J, nb_element);
   } else {
-    UInt nb_element = mesh.getNbElement(type, ghost_type);
+    auto nb_element = mesh.getNbElement(type, ghost_type);
     this->integrateOnIntegrationPoints(in_f, intf, nb_degree_of_freedom,
                                        jac_loc, nb_element);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void
 IntegratorGauss<kind, IntegrationOrderFunctor>::onElementsAddedByType(
-    const Array<UInt> & elements, GhostType ghost_type) {
+    const Array<Idx> & elements, const GhostType & ghost_type) {
   const auto & nodes = mesh.getNodes();
 
   if (not quadrature_points.exists(type, ghost_type)) {
     computeQuadraturePoints<type>(ghost_type);
   }
 
   if (not jacobians.exists(type, ghost_type)) {
     jacobians.alloc(0, 1, type, ghost_type);
   }
 
   this->computeJacobiansOnIntegrationPoints(
       nodes, quadrature_points(type, ghost_type), jacobians(type, ghost_type),
       type, ghost_type, elements);
 
-  constexpr UInt polynomial_degree =
+  constexpr auto polynomial_degree =
       IntegrationOrderFunctor::template getOrder<type>();
 
   multiplyJacobiansByWeights<type, polynomial_degree>(
       this->jacobians(type, ghost_type), elements);
 }
 
 /* -------------------------------------------------------------------------- */
 namespace integrator {
   namespace details {
     template <ElementKind kind> struct IntegratorOnElementsAddedHelper {};
 
 #define ON_ELEMENT_ADDED(type)                                                 \
   integrator.template onElementsAddedByType<type>(elements, ghost_type);
 
 #define AKANTU_SPECIALIZE_ON_ELEMENT_ADDED_HELPER(kind)                        \
   template <> struct IntegratorOnElementsAddedHelper<kind> {                   \
     template <class I>                                                         \
-    static void call(I & integrator, const Array<UInt> & elements,             \
-                     ElementType type, GhostType ghost_type) {                 \
+    static void call(I & integrator, const Array<Idx> & elements,              \
+                     const ElementType & type, const GhostType & ghost_type) { \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(ON_ELEMENT_ADDED, kind);                \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_SPECIALIZE_ON_ELEMENT_ADDED_HELPER)
 
 #undef AKANTU_SPECIALIZE_ON_ELEMENT_ADDED_HELPER
 #undef ON_ELEMENT_ADDED
   } // namespace details
 } // namespace integrator
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::onElementsAdded(
     const Array<Element> & new_elements) {
   for (auto elements_range : MeshElementsByTypes(new_elements)) {
     auto type = elements_range.getType();
     auto ghost_type = elements_range.getGhostType();
 
     if (mesh.getSpatialDimension(type) != _spatial_dimension) {
       continue;
     }
 
     if (mesh.getKind(type) != kind) {
       continue;
     }
 
     integrator::details::IntegratorOnElementsAddedHelper<kind>::call(
         *this, elements_range.getElements(), type, ghost_type);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::initIntegrator(
     const Array<Real> & nodes, GhostType ghost_type) {
   computeQuadraturePoints<type>(ghost_type);
   precomputeJacobiansOnQuadraturePoints<type>(nodes, ghost_type);
   checkJacobians<type>(ghost_type);
-  constexpr UInt polynomial_degree =
+  constexpr auto polynomial_degree =
       IntegrationOrderFunctor::template getOrder<type>();
   multiplyJacobiansByWeights<type, polynomial_degree>(
       this->jacobians(type, ghost_type));
 }
 
 namespace integrator {
   namespace details {
     template <ElementKind kind> struct GaussIntegratorInitHelper {};
 
 #define INIT_INTEGRATOR(type)                                                  \
   _int.template initIntegrator<type>(nodes, ghost_type)
 
 #define AKANTU_GAUSS_INTERGRATOR_INIT_HELPER(kind)                             \
   template <> struct GaussIntegratorInitHelper<kind> {                         \
     template <ElementKind k, class IOF>                                        \
     static void call(IntegratorGauss<k, IOF> & _int,                           \
                      const Array<Real> & nodes, ElementType type,              \
                      GhostType ghost_type) {                                   \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INIT_INTEGRATOR, kind);                 \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_GAUSS_INTERGRATOR_INIT_HELPER)
 
 #undef AKANTU_GAUSS_INTERGRATOR_INIT_HELPER
 #undef INIT_INTEGRATOR
   } // namespace details
 } // namespace integrator
 
 template <ElementKind kind, class IntegrationOrderFunctor>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::initIntegrator(
     const Array<Real> & nodes, ElementType type, GhostType ghost_type) {
   integrator::details::GaussIntegratorInitHelper<kind>::call(*this, nodes, type,
                                                              ghost_type);
 }
 
 namespace integrator {
   namespace details {
     template <ElementKind kind> struct GaussIntegratorComputeJacobiansHelper {};
 
 #define AKANTU_COMPUTE_JACOBIANS(type)                                         \
   _int.template computeJacobiansOnIntegrationPoints<type>(                     \
       nodes, quad_points, jacobians, ghost_type, filter_elements);
 
 #define AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS(kind)                       \
   template <> struct GaussIntegratorComputeJacobiansHelper<kind> {             \
     template <ElementKind k, class IOF>                                        \
     static void                                                                \
     call(const IntegratorGauss<k, IOF> & _int, const Array<Real> & nodes,      \
          const Matrix<Real> & quad_points, Array<Real> & jacobians,            \
-         ElementType type, GhostType ghost_type,                               \
-         const Array<UInt> & filter_elements) {                                \
+         const ElementType & type, const GhostType & ghost_type,               \
+         const Array<Idx> & filter_elements) {                                 \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(AKANTU_COMPUTE_JACOBIANS, kind);        \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS)
 
 #undef AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS
 #undef AKANTU_COMPUTE_JACOBIANS
   } // namespace details
 } // namespace integrator
 
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
         const Array<Real> & nodes, const Matrix<Real> & quad_points,
-        Array<Real> & jacobians, ElementType type, GhostType ghost_type,
-        const Array<UInt> & filter_elements) const {
+        Array<Real> & jacobians, const ElementType & type,
+        const GhostType & ghost_type,
+        const Array<Idx> & filter_elements) const {
   integrator::details::GaussIntegratorComputeJacobiansHelper<kind>::call(
       *this, nodes, quad_points, jacobians, type, ghost_type, filter_elements);
 }
 
 } // namespace akantu
diff --git a/src/fe_engine/shape_cohesive.hh b/src/fe_engine/shape_cohesive.hh
index 94286adb2..7de18e8e2 100644
--- a/src/fe_engine/shape_cohesive.hh
+++ b/src/fe_engine/shape_cohesive.hh
@@ -1,193 +1,193 @@
 /**
  * @file   shape_cohesive.hh
  *
  * @author Mohit Pundir <mohit.pundir@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: Fri May 14 2021
  *
  * @brief  shape functions for cohesive elements description
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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, UInt spatial_dimension,
                 const ID & id = "shape_cohesive");
 
   ~ShapeLagrange() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   inline void initShapeFunctions(const Array<Real> & nodes,
                                  const Ref<const MatrixXr> & integration_points,
                                  ElementType type,
                                  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,
-      GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      const GhostType & ghost_type = _not_ghost,
+      const Array<Int> & filter_elements = empty_filter) const;
 
   /// computes the shape functions derivatives for given interpolation points
   template <ElementType type>
   void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
-      Array<Real> & shape_derivatives, GhostType ghost_type,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      Array<Real> & shape_derivatives, const GhostType & ghost_type,
+      const Array<Int> & filter_elements = empty_filter) const;
 
   void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
-      Array<Real> & shape_derivatives, ElementType type,
-      GhostType ghost_type,
-      const Array<UInt> & filter_elements) const override;
+      Array<Real> & shape_derivatives, const ElementType & type,
+      const GhostType & ghost_type,
+      const Array<Int> & 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,
-      GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      const GhostType ghost_type = _not_ghost,
+      const Array<Int> & filter_elements = empty_filter) const;
 
   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 {
+      const GhostType ghost_type = _not_ghost,
+      const Array<Int> & 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 {
+      const Array<Int> & filter_elements = empty_filter) const {
     variationOnIntegrationPoints<type, CohesiveReduceFunctionMean>(
         u, nablauq, nb_degree_of_freedom, ghost_type, filter_elements);
   }
 
   /* ------------------------------------------------------------------------ */
   template <ElementType type>
   void computeBtD(const Array<Real> & /*Ds*/, Array<Real> & /*BtDs*/,
                   GhostType /*ghost_type*/,
                   const Array<UInt> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   template <ElementType type>
   void computeBtDB(const Array<Real> & /*Ds*/, Array<Real> & /*BtDBs*/,
                    UInt /*order_d*/, GhostType /*ghost_type*/,
                    const Array<UInt> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// multiply a field by shape functions
   template <ElementType type>
   void
   computeNtb(const Array<Real> & /*bs*/, Array<Real> & /*Ntbs*/,
              GhostType /*ghost_type*/,
              const Array<UInt> & /*filter_elements*/ = empty_filter) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   template <ElementType type>
   void computeNtbN(const Array<Real> & /*bs*/, Array<Real> & /*NtbNs*/,
                    GhostType /*ghost_type*/,
                    const Array<UInt> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /* ------------------------------------------------------------------------ */
   /// compute the gradient of u on the integration points
   template <ElementType type, class ReduceFunction>
   void variationOnIntegrationPoints(
       const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
       GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      const Array<Int> & 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;
+      const Array<Int> & filter_elements = empty_filter) const;
 };
 
 /// 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.hh"
 
 #endif /* AKANTU_SHAPE_COHESIVE_HH_ */
diff --git a/src/fe_engine/shape_cohesive_inline_impl.hh b/src/fe_engine/shape_cohesive_inline_impl.hh
index ddc8b028d..f481b8d1d 100644
--- a/src/fe_engine/shape_cohesive_inline_impl.hh
+++ b/src/fe_engine/shape_cohesive_inline_impl.hh
@@ -1,333 +1,332 @@
 /**
  * @file   shape_cohesive_inline_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Feb 03 2012
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  ShapeCohesive inline implementation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_iterators.hh"
 //#include "shape_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SHAPE_COHESIVE_INLINE_IMPL_HH_
 #define AKANTU_SHAPE_COHESIVE_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline ShapeLagrange<_ek_cohesive>::ShapeLagrange(const Mesh & mesh,
                                                   UInt spatial_dimension,
                                                   const ID & id)
     : ShapeLagrangeBase(mesh, spatial_dimension, _ek_cohesive, id) {}
 
 #define INIT_SHAPE_FUNCTIONS(type)                                             \
   setIntegrationPointsByType<type>(integration_points, ghost_type);            \
   precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type);                \
   precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
 
 /* -------------------------------------------------------------------------- */
 inline void ShapeLagrange<_ek_cohesive>::initShapeFunctions(
     const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
     ElementType type, GhostType ghost_type) {
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
 }
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_cohesive>::computeShapeDerivativesOnIntegrationPoints(
     const Array<Real> &, const Ref<const MatrixXr> & integration_points,
-    Array<Real> & shape_derivatives, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    Array<Real> & shape_derivatives, const GhostType & ghost_type,
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
-  UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
-  UInt spatial_dimension = ElementClass<type>::getNaturalSpaceDimension();
-  UInt nb_nodes_per_element =
+  auto size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
+  auto spatial_dimension = ElementClass<type>::getNaturalSpaceDimension();
+  auto nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
-  UInt nb_points = integration_points.cols();
-  UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
+  auto nb_points = integration_points.cols();
+  auto nb_element = mesh.getConnectivity(type, ghost_type).size();
 
   AKANTU_DEBUG_ASSERT(shape_derivatives.getNbComponent() == size_of_shapesd,
                       "The shapes_derivatives array does not have the correct "
                           << "number of component");
 
   shape_derivatives.resize(nb_element * nb_points);
-  Real * shapesd_val = shape_derivatives.data();
+  auto * shapesd_val = shape_derivatives.data();
 
   auto compute = [&](const auto & el) {
     auto ptr = shapesd_val + el * nb_points * size_of_shapesd;
-    Tensor3Proxy<Real> B(ptr, spatial_dimension, nb_nodes_per_element, nb_points);
+    Tensor3Proxy<Real> B(ptr, spatial_dimension, nb_nodes_per_element,
+                         nb_points);
     ElementClass<type>::computeDNDS(integration_points, B);
   };
 
   for_each_element(nb_element, filter_elements, compute);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 ShapeLagrange<_ek_cohesive>::computeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
-    Array<Real> & shape_derivatives, ElementType type,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    Array<Real> & shape_derivatives, const ElementType & type,
+    const GhostType & ghost_type, const Array<Int> & filter_elements) const {
 #define AKANTU_COMPUTE_SHAPES(type)                                            \
   computeShapeDerivativesOnIntegrationPoints<type>(                            \
       nodes, integration_points, shape_derivatives, ghost_type,                \
       filter_elements);
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(AKANTU_COMPUTE_SHAPES);
 
 #undef AKANTU_COMPUTE_SHAPES
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_cohesive>::precomputeShapesOnIntegrationPoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   Matrix<Real> & natural_coords = integration_points(type, ghost_type);
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
 
   Array<Real> & shapes_tmp =
       shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
 
   this->computeShapesOnIntegrationPoints<type>(nodes, natural_coords,
                                                shapes_tmp, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrange<_ek_cohesive>::precomputeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   Matrix<Real> & natural_coords = integration_points(type, ghost_type);
   UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
 
   Array<Real> & shapes_derivatives_tmp =
       shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
 
   this->computeShapeDerivativesOnIntegrationPoints<type>(
       nodes, natural_coords, shapes_derivatives_tmp, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, class ReduceFunction>
 void ShapeLagrange<_ek_cohesive>::extractNodalToElementField(
     const Array<Real> & nodal_f, Array<Real> & elemental_f,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    const GhostType & ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes_per_itp_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   UInt nb_degree_of_freedom = nodal_f.getNbComponent();
   UInt nb_element = this->mesh.getNbElement(type, ghost_type);
 
   const auto & conn_array = this->mesh.getConnectivity(type, ghost_type);
   auto conn = conn_array.begin(conn_array.getNbComponent() / 2, 2);
 
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   elemental_f.resize(nb_element);
 
   Array<Real>::matrix_iterator u_it =
       elemental_f.begin(nb_degree_of_freedom, nb_nodes_per_itp_element);
 
   ReduceFunction reduce_function;
 
   auto compute = [&](const auto & el) {
-    Matrix<Real> & u = *u_it;
+    auto && u = *u_it;
     Matrix<UInt> el_conn(conn[el]);
 
     // compute the average/difference of the nodal field loaded from cohesive
     // element
-    for (UInt n = 0; n < el_conn.rows(); ++n) {
+    for (Int n = 0; n < el_conn.rows(); ++n) {
       UInt node_plus = el_conn(n, 0);
       UInt node_minus = el_conn(n, 1);
       for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
         Real u_plus = nodal_f(node_plus, d);
         Real u_minus = nodal_f(node_minus, d);
         u(d, n) = reduce_function(u_plus, u_minus);
       }
     }
 
     ++u_it;
   };
 
   for_each_element(nb_element, filter_elements, compute);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, class ReduceFunction>
 void ShapeLagrange<_ek_cohesive>::interpolateOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    GhostType ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
 
   AKANTU_DEBUG_ASSERT(this->shapes.exists(itp_type, ghost_type),
                       "No shapes for the type "
                           << this->shapes.printType(itp_type, ghost_type));
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   this->extractNodalToElementField<type, ReduceFunction>(in_u, u_el, ghost_type,
                                                          filter_elements);
 
   this->template interpolateElementalFieldOnIntegrationPoints<type>(
       u_el, out_uq, ghost_type, shapes(itp_type, ghost_type), filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, class ReduceFunction>
 void ShapeLagrange<_ek_cohesive>::variationOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    GhostType ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
 
   AKANTU_DEBUG_ASSERT(
       this->shapes_derivatives.exists(itp_type, ghost_type),
       "No shapes for the type "
           << this->shapes_derivatives.printType(itp_type, ghost_type));
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   this->extractNodalToElementField<type, ReduceFunction>(in_u, u_el, ghost_type,
                                                          filter_elements);
 
   this->template gradientElementalFieldOnIntegrationPoints<type>(
       u_el, nablauq, ghost_type, shapes_derivatives(itp_type, ghost_type),
       filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, class ReduceFunction>
 void ShapeLagrange<_ek_cohesive>::computeNormalsOnIntegrationPoints(
-    const Array<Real> & u, Array<Real> & normals_u,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    const Array<Real> & u, Array<Real> & normals_u, GhostType ghost_type,
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_element = this->mesh.getNbElement(type, ghost_type);
   UInt nb_points = this->integration_points(type, ghost_type).cols();
   UInt spatial_dimension = this->mesh.getSpatialDimension();
 
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   normals_u.resize(nb_points * nb_element);
 
   Array<Real> tangents_u(0, (spatial_dimension * (spatial_dimension - 1)));
 
   if (spatial_dimension > 1) {
     tangents_u.resize(nb_element * nb_points);
     this->template variationOnIntegrationPoints<type, ReduceFunction>(
         u, tangents_u, spatial_dimension, ghost_type, filter_elements);
   }
 
-  Real * tangent = tangents_u.data();
-
   if (spatial_dimension == 3) {
-    for (auto & normal : make_view(normals_u, spatial_dimension)) {
-      Math::vectorProduct3(tangent, tangent + spatial_dimension,
-                           normal.data());
+    for (auto && data :
+         zip(make_view<3>(normals_u), make_view<3, 2>(tangents_u))) {
+      auto && n = std::get<0>(data);
+      auto && ts = std::get<1>(data);
 
-      normal /= normal.norm();
-      tangent += spatial_dimension * 2;
+      n = (ts(0).cross(ts(1))).normalized();
     }
   } else if (spatial_dimension == 2) {
-    for (auto & normal : make_view(normals_u, spatial_dimension)) {
-      Vector<Real> a1(tangent, spatial_dimension);
-
-      normal(0) = -a1(1);
-      normal(1) = a1(0);
-      normal.normalize();
-
-      tangent += spatial_dimension;
+    for (auto && data :
+         zip(make_view<2>(normals_u), make_view<2>(tangents_u))) {
+      auto && n = std::get<0>(data);
+      auto && t = std::get<1>(data);
+
+      n(0) = -t(1);
+      n(1) = t(0);
+      n.normalize();
     }
   } else if (spatial_dimension == 1) {
     const auto facet_type = Mesh::getFacetType(type);
     const auto & mesh_facets = mesh.getMeshFacets();
     const auto & facets = mesh_facets.getSubelementToElement(type, ghost_type);
     const auto & segments =
         mesh_facets.getElementToSubelement(facet_type, ghost_type);
 
     Real values[2];
 
     for (auto el : arange(nb_element)) {
       if (filter_elements != empty_filter) {
         el = filter_elements(el);
       }
 
       for (UInt p = 0; p < 2; ++p) {
         Element facet = facets(el, p);
         Element segment = segments(facet.element)[0];
-        Vector<Real> barycenter(values + p, 1);
+        VectorProxy<Real> barycenter(values + p, 1);
         mesh.getBarycenter(segment, barycenter);
       }
 
       Real difference = values[0] - values[1];
 
       AKANTU_DEBUG_ASSERT(difference != 0.,
                           "Error in normal computation for cohesive elements");
 
       normals_u(el) = difference / std::abs(difference);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_SHAPE_COHESIVE_INLINE_IMPL_HH_ */
diff --git a/src/fe_engine/shape_functions.cc b/src/fe_engine/shape_functions.cc
index b09fcafc6..3fda21c5c 100644
--- a/src/fe_engine/shape_functions.cc
+++ b/src/fe_engine/shape_functions.cc
@@ -1,243 +1,238 @@
 /**
  * @file   shape_functions.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 09 2017
  * @date last modification: Tue Feb 09 2021
  *
  * @brief  implementation of th shape functions interface
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 ShapeFunctions::ShapeFunctions(const Mesh & mesh, UInt spatial_dimension,
                                const ID & id)
     : shapes("shapes_generic", id),
       shapes_derivatives("shapes_derivatives_generic", id),
       mesh(mesh), _spatial_dimension(spatial_dimension) {}
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 inline void
 ShapeFunctions::initElementalFieldInterpolationFromIntegrationPoints(
     const Array<Real> & interpolation_points_coordinates,
     ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
     ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
     const Array<Real> & quadrature_points_coordinates,
-    GhostType ghost_type, const Array<UInt> & element_filter) const {
+    const GhostType & ghost_type, const Array<Idx> & element_filter) const {
 
   AKANTU_DEBUG_IN();
 
-  UInt spatial_dimension = this->mesh.getSpatialDimension();
-  UInt nb_element = this->mesh.getNbElement(type, ghost_type);
-  UInt nb_element_filter;
+  auto spatial_dimension = this->mesh.getSpatialDimension();
+  auto nb_element = this->mesh.getNbElement(type, ghost_type);
+  decltype(nb_element) nb_element_filter;
 
   if (element_filter == empty_filter) {
     nb_element_filter = nb_element;
   } else {
     nb_element_filter = element_filter.size();
   }
 
-  auto nb_quad_per_element =
+  constexpr auto nb_quad_per_element =
       GaussIntegrationElement<type>::getNbQuadraturePoints();
   auto nb_interpolation_points_per_elem =
       interpolation_points_coordinates.size() / nb_element;
 
   AKANTU_DEBUG_ASSERT(interpolation_points_coordinates.size() % nb_element == 0,
                       "Number of interpolation points should be a multiple of "
                       "total number of elements");
 
   if (not quad_points_coordinates_inv_matrices.exists(type, ghost_type)) {
     quad_points_coordinates_inv_matrices.alloc(
         nb_element_filter, nb_quad_per_element * nb_quad_per_element, type,
         ghost_type);
   } else {
     quad_points_coordinates_inv_matrices(type, ghost_type)
         .resize(nb_element_filter);
   }
 
   if (!interpolation_points_coordinates_matrices.exists(type, ghost_type)) {
     interpolation_points_coordinates_matrices.alloc(
         nb_element_filter,
         nb_interpolation_points_per_elem * nb_quad_per_element, type,
         ghost_type);
   } else {
     interpolation_points_coordinates_matrices(type, ghost_type)
         .resize(nb_element_filter);
   }
 
-  Array<Real> & quad_inv_mat =
-      quad_points_coordinates_inv_matrices(type, ghost_type);
-  Array<Real> & interp_points_mat =
+  auto & quad_inv_mat = quad_points_coordinates_inv_matrices(type, ghost_type);
+  auto & interp_points_mat =
       interpolation_points_coordinates_matrices(type, ghost_type);
 
-  Matrix<Real> quad_coord_matrix(nb_quad_per_element, nb_quad_per_element);
+  Matrix<Real, nb_quad_per_element, nb_quad_per_element> quad_coord_matrix;
 
-  Array<Real>::const_matrix_iterator quad_coords_it =
-      quadrature_points_coordinates.begin_reinterpret(
-          spatial_dimension, nb_quad_per_element, nb_element_filter);
-
-  Array<Real>::const_matrix_iterator points_coords_begin =
-      interpolation_points_coordinates.begin_reinterpret(
-          spatial_dimension, nb_interpolation_points_per_elem, nb_element);
-
-  Array<Real>::matrix_iterator inv_quad_coord_it =
-      quad_inv_mat.begin(nb_quad_per_element, nb_quad_per_element);
-
-  Array<Real>::matrix_iterator int_points_mat_it = interp_points_mat.begin(
-      nb_interpolation_points_per_elem, nb_quad_per_element);
+  auto points_coords_begin =
+      make_view(interpolation_points_coordinates, spatial_dimension,
+                nb_interpolation_points_per_elem)
+          .begin();
 
   /// loop over the elements of the current material and element type
-  for (UInt el = 0; el < nb_element_filter;
-       ++el, ++inv_quad_coord_it, ++int_points_mat_it, ++quad_coords_it) {
-    /// matrix containing the quadrature points coordinates
-    const Matrix<Real> & quad_coords = *quad_coords_it;
+  for (auto && data :
+       zip(element_filter,
+           make_view<nb_quad_per_element, nb_quad_per_element>(quad_inv_mat),
+           make_view(interp_points_mat, nb_interpolation_points_per_elem,
+                     nb_quad_per_element),
+           make_view(quadrature_points_coordinates, spatial_dimension,
+                     nb_quad_per_element))) {
+
+    auto element = std::get<0>(data);
     /// matrix to store the matrix inversion result
-    Matrix<Real> & inv_quad_coord_matrix = *inv_quad_coord_it;
+    auto & inv_quad_coord_matrix = std::get<1>(data);
+    /// matrix to store the interpolation points coordinates
+    /// compatible with these functions
+    auto & inv_points_coord_matrix = std::get<2>(data);
+    /// matrix containing the quadrature points coordinates
+    auto & quad_coords = std::get<3>(data);
+    /// matrix containing the interpolation points coordinates
+    auto & points_coords = points_coords_begin[element];
 
     /// insert the quad coordinates in a matrix compatible with the
     /// interpolation
     buildElementalFieldInterpolationMatrix<type>(quad_coords,
                                                  quad_coord_matrix);
 
     /// invert the interpolation matrix
-    inv_quad_coord_matrix.inverse(quad_coord_matrix);
-
-    /// matrix containing the interpolation points coordinates
-    const Matrix<Real> & points_coords =
-        points_coords_begin[element_filter(el)];
-    /// matrix to store the interpolation points coordinates
-    /// compatible with these functions
-    Matrix<Real> & inv_points_coord_matrix = *int_points_mat_it;
+    inv_quad_coord_matrix = quad_coord_matrix.inverse();
 
     /// insert the quad coordinates in a matrix compatible with the
     /// interpolation
     buildElementalFieldInterpolationMatrix<type>(points_coords,
                                                  inv_points_coord_matrix);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeFunctions::initElementalFieldInterpolationFromIntegrationPoints(
     const ElementTypeMapArray<Real> & interpolation_points_coordinates,
     ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
     ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
     const ElementTypeMapArray<Real> & quadrature_points_coordinates,
-    const ElementTypeMapArray<UInt> * element_filter) const {
+    const ElementTypeMapArray<Idx> * element_filter) const {
 
   AKANTU_DEBUG_IN();
 
-  UInt spatial_dimension = this->mesh.getSpatialDimension();
+  auto spatial_dimension = this->mesh.getSpatialDimension();
 
   for (auto ghost_type : ghost_types) {
     auto types_iterable = mesh.elementTypes(spatial_dimension, ghost_type);
     if (element_filter != nullptr) {
       types_iterable =
           element_filter->elementTypes(spatial_dimension, ghost_type);
     }
 
     for (auto type : types_iterable) {
-      UInt nb_element = mesh.getNbElement(type, ghost_type);
+      auto nb_element = mesh.getNbElement(type, ghost_type);
       if (nb_element == 0) {
         continue;
       }
 
-      const Array<UInt> * elem_filter;
+      const Array<Idx> * elem_filter;
       if (element_filter != nullptr) {
         elem_filter = &((*element_filter)(type, ghost_type));
       } else {
         elem_filter = &(empty_filter);
       }
 
 #define AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS(type)          \
   this->initElementalFieldInterpolationFromIntegrationPoints<type>(            \
       interpolation_points_coordinates(type, ghost_type),                      \
       interpolation_points_coordinates_matrices,                               \
       quad_points_coordinates_inv_matrices,                                    \
       quadrature_points_coordinates(type, ghost_type), ghost_type,             \
       *elem_filter)
 
       AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(
           AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS);
 #undef AKANTU_INIT_ELEMENTAL_FIELD_INTERPOLATION_FROM_C_POINTS
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeFunctions::interpolateElementalFieldFromIntegrationPoints(
     const ElementTypeMapArray<Real> & field,
     const ElementTypeMapArray<Real> & interpolation_points_coordinates_matrices,
     const ElementTypeMapArray<Real> & quad_points_coordinates_inv_matrices,
-    ElementTypeMapArray<Real> & result, GhostType ghost_type,
-    const ElementTypeMapArray<UInt> * element_filter) const {
+    ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
+    const ElementTypeMapArray<Idx> * element_filter) const {
 
   AKANTU_DEBUG_IN();
 
-  UInt spatial_dimension = this->mesh.getSpatialDimension();
+  auto spatial_dimension = this->mesh.getSpatialDimension();
 
   auto types_iterable = mesh.elementTypes(spatial_dimension, ghost_type);
   if (element_filter != nullptr) {
     types_iterable =
         element_filter->elementTypes(spatial_dimension, ghost_type);
   }
 
   for (auto type : types_iterable) {
-    UInt nb_element = mesh.getNbElement(type, ghost_type);
+    auto nb_element = mesh.getNbElement(type, ghost_type);
     if (nb_element == 0) {
       continue;
     }
-    
-    const Array<UInt> * elem_filter;
+
+    const Array<Idx> * elem_filter;
     if (element_filter != nullptr) {
       elem_filter = &((*element_filter)(type, ghost_type));
     } else {
       elem_filter = &(empty_filter);
     }
 
 #define AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS(type)                 \
   interpolateElementalFieldFromIntegrationPoints<type>(                        \
       field(type, ghost_type),                                                 \
       interpolation_points_coordinates_matrices(type, ghost_type),             \
       quad_points_coordinates_inv_matrices(type, ghost_type), result,          \
       ghost_type, *elem_filter)
 
     AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(
         AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS);
 #undef AKANTU_INTERPOLATE_ELEMENTAL_FIELD_FROM_C_POINTS
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/fe_engine/shape_functions.hh b/src/fe_engine/shape_functions.hh
index b4ce221c1..0fbe1864b 100644
--- a/src/fe_engine/shape_functions.hh
+++ b/src/fe_engine/shape_functions.hh
@@ -1,216 +1,217 @@
 /**
  * @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: Tue Sep 29 2020
  *
  * @brief  shape function class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SHAPE_FUNCTIONS_HH_
 #define AKANTU_SHAPE_FUNCTIONS_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class ShapeFunctions  {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
-  ShapeFunctions(const Mesh & mesh, UInt spatial_dimension,
+  ShapeFunctions(const Mesh & mesh, Int spatial_dimension,
                  const ID & id = "shape");
-  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) {
-      ;
-    }
+    std::string space(indent, AKANTU_INDENT);
+
     stream << space << "Shapes [" << std::endl;
     integration_points.printself(stream, indent + 1);
     // shapes.printself(stream, indent + 1);
     // shapes_derivatives.printself(stream, indent + 1);
     stream << space << "]" << std::endl;
   }
 
   /// set the integration points for a given element
-  template <ElementType type>
-  void setIntegrationPointsByType(const Matrix<Real> & integration_points,
-                                  GhostType ghost_type);
+  template <ElementType type, class D1>
+  void setIntegrationPointsByType(const Eigen::MatrixBase<D1> & 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;
+      const ElementTypeMapArray<Idx> * 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, GhostType ghost_type,
-      const ElementTypeMapArray<UInt> * element_filter) const;
+      ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
+      const ElementTypeMapArray<Idx> * 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, GhostType ghost_type,
       const Array<Real> & shapes,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      const Array<Int> & 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,
-      GhostType ghost_type, const Array<Real> & shapes_derivatives,
-      const Array<UInt> & filter_elements) const;
+      const GhostType & ghost_type, const Array<Real> & shapes_derivatives,
+      const Array<Int> & 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, GhostType ghost_type,
-      const Array<UInt> & element_filter) const;
+      ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
+      const Array<Int> & 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,
-      GhostType ghost_type, const Array<UInt> & element_filter) const;
+      const GhostType & ghost_type, const Array<Int> & element_filter) const;
 
   /// build matrix for the interpolation of field form integration points
-  template <ElementType type>
+  template <ElementType type, typename D1, typename D2>
   inline void buildElementalFieldInterpolationMatrix(
-      const Matrix<Real> & coordinates, Matrix<Real> & coordMatrix,
-      UInt integration_order =
+      const Eigen::MatrixBase<D1> & coordinates,
+      Eigen::MatrixBase<D2> & coordMatrix,
+      Int 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)
-  static inline void buildInterpolationMatrix(const Matrix<Real> & coordinates,
-                                       Matrix<Real> & coordMatrix,
-                                       UInt integration_order);
+  template <typename D1, typename D2>
+  inline void
+  buildInterpolationMatrix(const Eigen::MatrixBase<D1> & coordinates,
+                           Eigen::MatrixBase<D2> & coordMatrix,
+                           Int integration_order) const;
 
 public:
   virtual void onElementsAdded(const Array<Element> & /*unused*/) {
     AKANTU_TO_IMPLEMENT();
   }
   virtual void onElementsRemoved(const Array<Element> & /*unused*/,
-                                 const ElementTypeMapArray<UInt> & /*unused*/) {
+                                 const ElementTypeMapArray<Idx> & /*unused*/) {
     AKANTU_TO_IMPLEMENT();
   }
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the size of the shapes returned by the element class
-  static inline UInt getShapeSize(ElementType type);
+  static inline Int getShapeSize(const ElementType & type);
 
   /// get the size of the shapes derivatives returned by the element class
-  static inline UInt getShapeDerivativesSize(ElementType type);
+  static inline Int getShapeDerivativesSize(const ElementType & type);
 
   inline const Matrix<Real> &
   getIntegrationPoints(ElementType type,
                        GhostType ghost_type) const {
     return integration_points(type, ghost_type);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get a the shapes vector
   inline const Array<Real> &
   getShapes(ElementType el_type,
             GhostType ghost_type = _not_ghost) const;
 
   /// get a the shapes derivatives vector
   inline const Array<Real> &
   getShapesDerivatives(ElementType el_type,
                        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;
 
   // spatial dimension of the elements to consider
-  UInt _spatial_dimension;
+  Int _spatial_dimension;
 
   /// 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.hh"
 
 #endif /* AKANTU_SHAPE_FUNCTIONS_HH_ */
diff --git a/src/fe_engine/shape_functions_inline_impl.hh b/src/fe_engine/shape_functions_inline_impl.hh
index ad56e8291..8ba35476d 100644
--- a/src/fe_engine/shape_functions_inline_impl.hh
+++ b/src/fe_engine/shape_functions_inline_impl.hh
@@ -1,414 +1,425 @@
 /**
  * @file   shape_functions_inline_impl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Oct 27 2010
  * @date last modification: Sat Dec 19 2020
  *
  * @brief  ShapeFunctions inline implementation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "fe_engine.hh"
-#include "shape_functions.hh"
+//#include "shape_functions.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_HH_
 #define AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Real> &
 ShapeFunctions::getShapes(ElementType el_type,
                           GhostType ghost_type) const {
   return shapes(FEEngine::getInterpolationType(el_type), ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Real> &
 ShapeFunctions::getShapesDerivatives(ElementType el_type,
                                      GhostType ghost_type) const {
   return shapes_derivatives(FEEngine::getInterpolationType(el_type),
                             ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt ShapeFunctions::getShapeSize(ElementType type) {
+inline Int ShapeFunctions::getShapeSize(const ElementType & type) {
   AKANTU_DEBUG_IN();
 
-  UInt shape_size = 0;
+  Int shape_size = 0;
 #define GET_SHAPE_SIZE(type) shape_size = ElementClass<type>::getShapeSize()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_SIZE); // ,
 
 #undef GET_SHAPE_SIZE
 
   AKANTU_DEBUG_OUT();
   return shape_size;
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt ShapeFunctions::getShapeDerivativesSize(ElementType type) {
+inline Int ShapeFunctions::getShapeDerivativesSize(const ElementType & type) {
   AKANTU_DEBUG_IN();
 
-  UInt shape_derivatives_size = 0;
+  Int shape_derivatives_size = 0;
 #define GET_SHAPE_DERIVATIVES_SIZE(type)                                       \
   shape_derivatives_size = ElementClass<type>::getShapeDerivativesSize()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SHAPE_DERIVATIVES_SIZE); // ,
 
 #undef GET_SHAPE_DERIVATIVES_SIZE
 
   AKANTU_DEBUG_OUT();
   return shape_derivatives_size;
 }
 
 /* -------------------------------------------------------------------------- */
-template <ElementType type>
-void ShapeFunctions::setIntegrationPointsByType(const Matrix<Real> & points,
-                                                GhostType ghost_type) {
+template <ElementType type, class D1>
+void ShapeFunctions::setIntegrationPointsByType(
+    const Eigen::MatrixBase<D1> & points, const GhostType & ghost_type) {
   if (not this->integration_points.exists(type, ghost_type))
     this->integration_points(type, ghost_type) = points;
 }
 
 /* -------------------------------------------------------------------------- */
-inline void
-ShapeFunctions::buildInterpolationMatrix(const Matrix<Real> & coordinates,
-                                         Matrix<Real> & coordMatrix,
-                                         UInt integration_order) {
+template <typename D1, typename D2>
+inline void ShapeFunctions::buildInterpolationMatrix(
+    const Eigen::MatrixBase<D1> & coordinates,
+    Eigen::MatrixBase<D2> & coordMatrix, Int integration_order) const {
   switch (integration_order) {
   case 1: {
     for (Int i = 0; i < coordinates.cols(); ++i)
       coordMatrix(i, 0) = 1;
     }
     break;
   }
   case 2: {
     auto nb_quadrature_points = coordMatrix.cols();
 
     for (Int i = 0; i < coordinates.cols(); ++i) {
       coordMatrix(i, 0) = 1;
       for (Int j = 1; j < nb_quadrature_points; ++j)
         coordMatrix(i, j) = coordinates(j - 1, i);
       }
     }
     break;
   }
   default: {
     AKANTU_TO_IMPLEMENT();
     break;
   }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <ElementType type>
-inline void ShapeFunctions::buildElementalFieldInterpolationMatrix(
-    const Matrix<Real> & /*unused*/, Matrix<Real> & /*unused*/,
-    UInt /*unused*/) const {
-  AKANTU_TO_IMPLEMENT();
-}
+template <ElementType type> class BuildElementalFieldInterpolationMatrix {
+  template <typename D1, typename D2>
+  inline void call(const Eigen::MatrixBase<D1> &, Eigen::MatrixBase<D2> &,
+                   Int) const {
+    AKANTU_TO_IMPLEMENT();
+  }
+};
 
 /* -------------------------------------------------------------------------- */
-template <>
-inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_2>(
-    const Matrix<Real> & /*unused*/ coordinates,
-    Matrix<Real> & /*unused*/ coordMatrix,
-    UInt /*unused*/ integration_order) const {
-  buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
-}
+template <> class BuildElementalFieldInterpolationMatrix<_segment_2> {
+  template <typename D1, typename D2>
+  inline void call(const Eigen::MatrixBase<D1> & coordinates,
+                   Eigen::MatrixBase<D2> & coordMatrix,
+                   Int integration_order) const {
+    buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
+  }
+};
 
 /* -------------------------------------------------------------------------- */
-template <>
-inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_segment_3>(
-    const Matrix<Real> & /*unused*/ coordinates,
-    Matrix<Real> & /*unused*/ coordMatrix,
-    UInt /*unused*/ integration_order) const {
-  buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
-}
+template <> class BuildElementalFieldInterpolationMatrix<_segment_3> {
+  template <typename D1, typename D2>
+  inline void call(const Eigen::MatrixBase<D1> & coordinates,
+                   Eigen::MatrixBase<D2> & coordMatrix,
+                   Int integration_order) const {
+    buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
+  }
+};
 
 /* -------------------------------------------------------------------------- */
-template <>
-inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_3>(
-    const Matrix<Real> & /*unused*/ coordinates,
-    Matrix<Real> & /*unused*/ coordMatrix,
-    UInt /*unused*/ integration_order) const {
-  buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
-}
+template <> class BuildElementalFieldInterpolationMatrix<_triangle_3> {
+  template <typename D1, typename D2>
+  inline void call(const Eigen::MatrixBase<D1> & coordinates,
+                   Eigen::MatrixBase<D2> & coordMatrix,
+                   Int integration_order) const {
+    buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
+  }
+};
 
 /* -------------------------------------------------------------------------- */
-template <>
-inline void ShapeFunctions::buildElementalFieldInterpolationMatrix<_triangle_6>(
-    const Matrix<Real> & /*unused*/ coordinates,
-    Matrix<Real> & /*unused*/ coordMatrix,
-    UInt /*unused*/ integration_order) const {
-  buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
-}
+template <> class BuildElementalFieldInterpolationMatrix<_triangle_6> {
+  template <typename D1, typename D2>
+  inline void call(const Eigen::MatrixBase<D1> & coordinates,
+                   Eigen::MatrixBase<D2> & coordMatrix,
+                   Int integration_order) const {
+    buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
+  }
+};
 
 /* -------------------------------------------------------------------------- */
-template <>
-inline void
-ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_4>(
-    const Matrix<Real> & /*unused*/ coordinates,
-    Matrix<Real> & /*unused*/ coordMatrix,
-    UInt /*unused*/ integration_order) const {
-  buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
-}
+template <> class BuildElementalFieldInterpolationMatrix<_tetrahedron_4> {
+  template <typename D1, typename D2>
+  inline void call(const Eigen::MatrixBase<D1> & coordinates,
+                   Eigen::MatrixBase<D2> & coordMatrix,
+                   Int integration_order) const {
+    buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
+  }
+};
 
 /* -------------------------------------------------------------------------- */
-template <>
-inline void
-ShapeFunctions::buildElementalFieldInterpolationMatrix<_tetrahedron_10>(
-    const Matrix<Real> & /*unused*/ coordinates,
-    Matrix<Real> & /*unused*/ coordMatrix,
-    UInt /*unused*/ integration_order) const {
-  buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
-}
+template <> class BuildElementalFieldInterpolationMatrix<_tetrahedron_10> {
+  template <typename D1, typename D2>
+  inline void call(const Eigen::MatrixBase<D1> & coordinates,
+                   Eigen::MatrixBase<D2> & coordMatrix,
+                   Int integration_order) const {
+    buildInterpolationMatrix(coordinates, coordMatrix, integration_order);
+  }
+};
 
 /**
  * @todo Write a more efficient interpolation for quadrangles by
  * dropping unnecessary quadrature points
  *
  */
-
 /* -------------------------------------------------------------------------- */
-template <>
-inline void
-ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_4>(
-    const Matrix<Real> & /*unused*/ coordinates,
-    Matrix<Real> & /*unused*/ coordMatrix,
-    UInt /*unused*/ integration_order) const {
-
-  if (integration_order !=
-      ElementClassProperty<_quadrangle_4>::polynomial_degree) {
-    AKANTU_TO_IMPLEMENT();
-  } else {
-    for (Int i = 0; i < coordinates.cols(); ++i) {
-      auto x = coordinates(0, i);
-      auto y = coordinates(1, i);
-
-      coordMatrix(i, 0) = 1;
-      coordMatrix(i, 1) = x;
-      coordMatrix(i, 2) = y;
-      coordMatrix(i, 3) = x * y;
+template <> class BuildElementalFieldInterpolationMatrix<_quadrangle_4> {
+  template <typename D1, typename D2>
+  inline void call(const Eigen::MatrixBase<D1> & coordinates,
+                   Eigen::MatrixBase<D2> & coordMatrix,
+                   Int integration_order) const {
+
+    if (integration_order !=
+        ElementClassProperty<_quadrangle_4>::polynomial_degree) {
+      AKANTU_TO_IMPLEMENT();
+    } else {
+      for (Int i = 0; i < coordinates.cols(); ++i) {
+        auto x = coordinates(0, i);
+        auto y = coordinates(1, i);
+
+        coordMatrix(i, 0) = 1;
+        coordMatrix(i, 1) = x;
+        coordMatrix(i, 2) = y;
+        coordMatrix(i, 3) = x * y;
+      }
     }
   }
-}
+};
 
 /* -------------------------------------------------------------------------- */
-template <>
-inline void
-ShapeFunctions::buildElementalFieldInterpolationMatrix<_quadrangle_8>(
-    const Matrix<Real> & /*unused*/ coordinates,
-    Matrix<Real> & /*unused*/ coordMatrix,
-    UInt /*unused*/ integration_order) const {
-
-  if (integration_order !=
-      ElementClassProperty<_quadrangle_8>::polynomial_degree) {
-    AKANTU_TO_IMPLEMENT();
-  } else {
-    for (Int i = 0; i < coordinates.cols(); ++i) {
-      // UInt j = 0;
-      auto x = coordinates(0, i);
-      auto y = coordinates(1, i);
-
-      coordMatrix(i, 0) = 1;
-      coordMatrix(i, 1) = x;
-      coordMatrix(i, 2) = y;
-      coordMatrix(i, 3) = x * y;
-      // for (UInt e = 0; e <= 2; ++e) {
-      //   for (UInt n = 0; n <= 2; ++n) {
-      //     coordMatrix(i, j) = std::pow(x, e) * std::pow(y, n);
-      //     ++j;
-      //   }
-      // }
+template <> class BuildElementalFieldInterpolationMatrix<_quadrangle_8> {
+  template <typename D1, typename D2>
+  inline void call(const Eigen::MatrixBase<D1> & coordinates,
+                   Eigen::MatrixBase<D2> & coordMatrix,
+                   Int integration_order) const {
+
+    if (integration_order !=
+        ElementClassProperty<_quadrangle_8>::polynomial_degree) {
+      AKANTU_TO_IMPLEMENT();
+    } else {
+      for (Int i = 0; i < coordinates.cols(); ++i) {
+        // Int j = 0;
+        auto x = coordinates(0, i);
+        auto y = coordinates(1, i);
+
+        coordMatrix(i, 0) = 1;
+        coordMatrix(i, 1) = x;
+        coordMatrix(i, 2) = y;
+        coordMatrix(i, 3) = x * y;
+        // for (Int e = 0; e <= 2; ++e) {
+        //   for (Int n = 0; n <= 2; ++n) {
+        //     coordMatrix(i, j) = std::pow(x, e) * std::pow(y, n);
+        //     ++j;
+        //   }
+        // }
+      }
     }
   }
+};
+
+/* -------------------------------------------------------------------------- */
+template <ElementType type, typename D1, typename D2>
+inline void ShapeFunctions::buildElementalFieldInterpolationMatrix(
+    const Eigen::MatrixBase<D1> & coordinates,
+    Eigen::MatrixBase<D2> & coordMatrix, Int integration_order) const {
+  BuildElementalFieldInterpolationMatrix<type>::call(coordinates, coordMatrix,
+                                                     integration_order);
 }
+
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 inline void ShapeFunctions::interpolateElementalFieldFromIntegrationPoints(
     const Array<Real> & field,
     const Array<Real> & interpolation_points_coordinates_matrices,
     const Array<Real> & quad_points_coordinates_inv_matrices,
-    ElementTypeMapArray<Real> & result, GhostType ghost_type,
-    const Array<UInt> & element_filter) const {
+    ElementTypeMapArray<Real> & result, const GhostType & ghost_type,
+    const Array<Int> & element_filter) const {
   AKANTU_DEBUG_IN();
 
   auto nb_element = this->mesh.getNbElement(type, ghost_type);
 
   auto nb_quad_per_element =
       GaussIntegrationElement<type>::getNbQuadraturePoints();
   auto nb_interpolation_points_per_elem =
       interpolation_points_coordinates_matrices.getNbComponent() /
       nb_quad_per_element;
 
   if (not result.exists(type, ghost_type)) {
     result.alloc(nb_element * nb_interpolation_points_per_elem,
                  field.getNbComponent(), type, ghost_type);
   }
 
   if (element_filter != empty_filter) {
     nb_element = element_filter.size();
   }
 
   Matrix<Real> coefficients(nb_quad_per_element, field.getNbComponent());
 
   auto & result_vec = result(type, ghost_type);
 
   auto field_it = field.begin_reinterpret(field.getNbComponent(),
                                           nb_quad_per_element, nb_element);
 
   auto interpolation_points_coordinates_it =
       interpolation_points_coordinates_matrices.begin(
           nb_interpolation_points_per_elem, nb_quad_per_element);
 
   auto result_begin = result_vec.begin_reinterpret(
       field.getNbComponent(), nb_interpolation_points_per_elem,
       result_vec.size() / nb_interpolation_points_per_elem);
 
   auto inv_quad_coord_it = quad_points_coordinates_inv_matrices.begin(
       nb_quad_per_element, nb_quad_per_element);
 
   /// loop over the elements of the current filter and element type
-  for (UInt el = 0; el < nb_element; ++el, ++field_it, ++inv_quad_coord_it,
-            ++interpolation_points_coordinates_it) {
+  for (Int el = 0; el < nb_element; ++el, ++field_it, ++inv_quad_coord_it,
+           ++interpolation_points_coordinates_it) {
     /**
      * matrix containing the inversion of the quadrature points'
      * coordinates
      */
     const auto & inv_quad_coord_matrix = *inv_quad_coord_it;
 
     /**
      * multiply it by the field values over quadrature points to get
      * the interpolation coefficients
      */
     coefficients = inv_quad_coord_matrix * *field_it->transpose();
 
     /// matrix containing the points' coordinates
     const auto & coord = *interpolation_points_coordinates_it;
 
     /// multiply the coordinates matrix by the coefficients matrix and store the
     /// result
-    result_begin[element_filter(el)] = coefficients.transpose() * coord.transpose();
+    result_begin[element_filter(el)] =
+        coefficients.transpose() * coord.transpose();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 inline void ShapeFunctions::interpolateElementalFieldOnIntegrationPoints(
-    const Array<Real> & u_el, Array<Real> & uq, GhostType ghost_type,
-    const Array<Real> & shapes, const Array<UInt> & filter_elements) const {
+    const Array<Real> & u_el, Array<Real> & uq, const GhostType & ghost_type,
+    const Array<Real> & shapes, const Array<Int> & filter_elements) const {
   auto nb_element = mesh.getNbElement(type, ghost_type);
   auto nb_nodes_per_element = ElementClass<type>::getShapeSize();
   auto nb_points = shapes.size() / mesh.getNbElement(type, ghost_type);
   auto nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element;
 
   Array<Real>::const_matrix_iterator N_it;
-  Array<Real> * filtered_N = nullptr;
+  std::unique_ptr<Array<Real>> filtered_N;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
-    filtered_N = new Array<Real>(0, shapes.getNbComponent());
+    filtered_N = std::make_unique<Array<Real>>(0, shapes.getNbComponent());
     FEEngine::filterElementalData(mesh, shapes, *filtered_N, type, ghost_type,
                                   filter_elements);
-    N_it = filtered_N->begin_reinterpret(nb_nodes_per_element, nb_points,
-                                         nb_element);
+    N_it = make_view(*filtered_N, nb_nodes_per_element, nb_points).begin();
   } else {
-    N_it =
-        shapes.begin_reinterpret(nb_nodes_per_element, nb_points, nb_element);
+    N_it = make_view(shapes, nb_nodes_per_element, nb_points).begin();
   }
 
   uq.resize(nb_element * nb_points);
 
-  auto u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element);
-  auto inter_u_it =
-      uq.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element);
+  auto u_it =
+      make_view(u_el, nb_degree_of_freedom, nb_nodes_per_element).begin();
+  auto uq_it = make_view(uq, nb_degree_of_freedom, nb_points).begin();
 
-  for (UInt el = 0; el < nb_element; ++el, ++N_it, ++u_it, ++inter_u_it) {
+  for (Int el = 0; el < nb_element; ++el, ++N_it, ++u_it, ++uq_it) {
     const auto & u = *u_it;
     const auto & N = *N_it;
-    auto & inter_u = *inter_u_it;
+    auto & uq = *uq_it;
 
-    inter_u.template mul<false, false>(u, N);
+    uq = u * N;
   }
-
-  delete filtered_N;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeFunctions::gradientElementalFieldOnIntegrationPoints(
     const Array<Real> & u_el, Array<Real> & out_nablauq,
-    GhostType ghost_type, const Array<Real> & shapes_derivatives,
-    const Array<UInt> & filter_elements) const {
+    const GhostType & ghost_type, const Array<Real> & shapes_derivatives,
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   auto nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
   auto nb_points = integration_points(type, ghost_type).cols();
   auto element_dimension = ElementClass<type>::getNaturalSpaceDimension();
   auto nb_degree_of_freedom = u_el.getNbComponent() / nb_nodes_per_element;
   auto nb_element = mesh.getNbElement(type, ghost_type);
 
   Array<Real>::const_matrix_iterator B_it;
 
   Array<Real> * filtered_B = nullptr;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
     filtered_B = new Array<Real>(0, shapes_derivatives.getNbComponent());
     FEEngine::filterElementalData(mesh, shapes_derivatives, *filtered_B, type,
                                   ghost_type, filter_elements);
     B_it = filtered_B->begin(element_dimension, nb_nodes_per_element);
   } else {
     B_it = shapes_derivatives.begin(element_dimension, nb_nodes_per_element);
   }
 
   out_nablauq.resize(nb_element * nb_points);
   auto u_it = u_el.begin(nb_degree_of_freedom, nb_nodes_per_element);
   auto nabla_u_it = out_nablauq.begin(nb_degree_of_freedom, element_dimension);
 
-  for (UInt el = 0; el < nb_element; ++el, ++u_it) {
+  for (Int el = 0; el < nb_element; ++el, ++u_it) {
     const auto & u = *u_it;
-    for (UInt q = 0; q < nb_points; ++q, ++B_it, ++nabla_u_it) {
+    for (Int q = 0; q < nb_points; ++q, ++B_it, ++nabla_u_it) {
       const auto & B = *B_it;
       auto & nabla_u = *nabla_u_it;
-      nabla_u.template mul<false, true>(u, B);
+      nabla_u = u * B.transpose();
     }
   }
 
   delete filtered_B;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #endif /* AKANTU_SHAPE_FUNCTIONS_INLINE_IMPL_HH_ */
diff --git a/src/fe_engine/shape_lagrange.hh b/src/fe_engine/shape_lagrange.hh
index d7d2e8479..e1750628b 100644
--- a/src/fe_engine/shape_lagrange.hh
+++ b/src/fe_engine/shape_lagrange.hh
@@ -1,180 +1,180 @@
 /**
  * @file   shape_lagrange.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Emil Gallyamov <emil.gallyamov@epfl.ch>
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Feb 15 2011
  * @date last modification: Fri May 14 2021
  *
  * @brief  lagrangian shape functions class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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, UInt spatial_dimension,
                 const ID & id = "shape_lagrange");
   ~ShapeLagrange() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialization function for structural elements not yet implemented
   inline void initShapeFunctions(const Array<Real> & nodes,
                                  const Ref<const MatrixXr> & integration_points,
                                  ElementType type,
                                  GhostType ghost_type);
 
   /// computes the shape functions derivatives for given interpolation points
   template <ElementType type>
   void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
-      Array<Real> & shape_derivatives, GhostType ghost_type,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      Array<Real> & shape_derivatives, const GhostType & ghost_type,
+      const Array<Int> & filter_elements = empty_filter) const;
 
   void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
-      Array<Real> & shape_derivatives, ElementType type,
-      GhostType ghost_type,
-      const Array<UInt> & filter_elements) const override;
+      Array<Real> & shape_derivatives, const ElementType & type,
+      const GhostType & ghost_type,
+      const Array<Int> & 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>
   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;
+      const Array<Int> & 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;
+      const Array<Int> & filter_elements = empty_filter) const;
 
   /// interpolate on physical point
   template <ElementType type>
   void interpolate(const Ref<const VectorXr> & real_coords, UInt elem,
                    const Ref<const MatrixXr> & nodal_values,
                    Ref<VectorXr> interpolated,
                    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;
+      const Array<Int> & filter_elements = empty_filter) const;
 
   template <ElementType type>
   void computeBtD(const Array<Real> & Ds, Array<Real> & BtDs,
                   GhostType ghost_type,
-                  const Array<UInt> & filter_elements) const;
+                  const Array<Int> & filter_elements) const;
 
   template <ElementType type>
   void computeBtDB(const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
                    GhostType ghost_type,
-                   const Array<UInt> & filter_elements) const;
+                   const Array<Int> & filter_elements) const;
 
   /// multiply a field by shape functions  @f$ fts_{ij} = f_i * \varphi_j @f$
   template <ElementType type>
   void computeNtb(const Array<Real> & bs, Array<Real> & Ntbs,
                   GhostType ghost_type,
-                  const Array<UInt> & filter_elements = empty_filter) const;
+                  const Array<Int> & filter_elements = empty_filter) const;
 
   template <ElementType type>
   void computeNtbN(const Array<Real> & bs, Array<Real> & NtbNs,
                    GhostType ghost_type,
                    const Array<UInt> & filter_elements) const;
 
   /// find natural coords from real coords provided an element
   template <ElementType type>
-  void inverseMap(const Ref<const VectorXr> & real_coords, UInt element,
+  void inverseMap(const Ref<const VectorXr> & real_coords, Int element,
                   Ref<VectorXr> natural_coords,
                   GhostType ghost_type = _not_ghost) const;
 
   /// return true if the coordinates provided are inside the element, false
   /// otherwise
   template <ElementType type>
   bool contains(const Ref<const VectorXr> & real_coords, UInt elem,
                 GhostType ghost_type) const;
 
   /// compute the shape on a provided point
   template <ElementType type>
   void computeShapes(const Ref<const VectorXr> & real_coords, UInt elem,
                      Ref<VectorXr> shapes, GhostType ghost_type) const;
 
   /// compute the shape derivatives on a provided point
   template <ElementType type>
   void computeShapeDerivatives(const Ref<const MatrixXr> & real_coords, UInt elem,
                                Tensor3<Real> & shapes,
                                GhostType ghost_type) const;
 
 protected:
   /// compute the shape derivatives on integration points for a given element
   template <ElementType type>
   inline void
   computeShapeDerivativesOnCPointsByElement(const Ref<const MatrixXr> & node_coords,
                                             const Ref<const MatrixXr> & natural_coords,
                                             Tensor3<Real> & shapesd) const;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "shape_lagrange_inline_impl.hh"
 
 #endif /* AKANTU_SHAPE_LAGRANGE_HH_ */
diff --git a/src/fe_engine/shape_lagrange_base.cc b/src/fe_engine/shape_lagrange_base.cc
index c30cd5d1f..2031f40b4 100644
--- a/src/fe_engine/shape_lagrange_base.cc
+++ b/src/fe_engine/shape_lagrange_base.cc
@@ -1,174 +1,174 @@
 /**
  * @file   shape_lagrange_base.cc
  *
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 09 2017
  * @date last modification: Wed Dec 09 2020
  *
  * @brief  common part for the shape lagrange
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 #include "mesh_iterators.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 ShapeLagrangeBase::ShapeLagrangeBase(const Mesh & mesh, UInt spatial_dimension,
                                      ElementKind kind, const ID & id)
     : ShapeFunctions(mesh, spatial_dimension, id), _kind(kind) {}
 
 /* -------------------------------------------------------------------------- */
 ShapeLagrangeBase::~ShapeLagrangeBase() = default;
 
 /* -------------------------------------------------------------------------- */
 #define AKANTU_COMPUTE_SHAPES(type)                                            \
   _this.template computeShapesOnIntegrationPoints<type>(                       \
       nodes, integration_points, shapes, ghost_type, filter_elements)
 
 namespace shape_lagrange {
   namespace details {
     template <ElementKind kind> struct Helper {
       template <class S>
       static void call(const S & /*unused*/, const Array<Real> & /*unused*/,
                        const Matrix<Real> & /*unused*/,
                        Array<Real> & /*unused*/, ElementType /*unused*/,
                        GhostType /*unused*/,
                        const Array<UInt> & /*unused*/) {
         AKANTU_TO_IMPLEMENT();
       }
     };
 
 #if !defined(DOXYGEN)
 #define AKANTU_COMPUTE_SHAPES_KIND(kind)                                       \
   template <> struct Helper<kind> {                                            \
     template <class S>                                                         \
     static void call(const S & _this, const Array<Real> & nodes,               \
                      const Matrix<Real> & integration_points,                  \
-                     Array<Real> & shapes, ElementType type,           \
-                     GhostType ghost_type,                             \
-                     const Array<UInt> & filter_elements) {                    \
+                     Array<Real> & shapes, const ElementType & type,           \
+                     const GhostType & ghost_type,                             \
+                     const Array<Int> & filter_elements) {                    \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(AKANTU_COMPUTE_SHAPES, kind);           \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND_LIST(AKANTU_COMPUTE_SHAPES_KIND,
                                AKANTU_FE_ENGINE_LIST_LAGRANGE_BASE)
 
   } // namespace details
 } // namespace shape_lagrange
 #endif
 
 /* -------------------------------------------------------------------------- */
 void ShapeLagrangeBase::computeShapesOnIntegrationPoints(
-    const Array<Real> & nodes, const Matrix<Real> & integration_points,
-    Array<Real> & shapes, ElementType type,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
+    Array<Real> & shapes, const ElementType & type,
+    const GhostType & ghost_type, const Array<Int> & filter_elements) const {
 
   auto kind = Mesh::getKind(type);
 
 #define AKANTU_COMPUTE_SHAPES_KIND_SWITCH(kind)                                \
   shape_lagrange::details::Helper<kind>::call(                                 \
       *this, nodes, integration_points, shapes, type, ghost_type,              \
       filter_elements);
 
   AKANTU_BOOST_LIST_SWITCH(
       AKANTU_COMPUTE_SHAPES_KIND_SWITCH,
       BOOST_PP_LIST_TO_SEQ(AKANTU_FE_ENGINE_LIST_LAGRANGE_BASE), kind);
 
 #undef AKANTU_COMPUTE_SHAPES
 #undef AKANTU_COMPUTE_SHAPES_KIND
 #undef AKANTU_COMPUTE_SHAPES_KIND_SWITCH
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeLagrangeBase::onElementsAdded(const Array<Element> & new_elements) {
   AKANTU_DEBUG_IN();
   const auto & nodes = mesh.getNodes();
 
   for (auto elements_range : MeshElementsByTypes(new_elements)) {
     auto type = elements_range.getType();
     auto ghost_type = elements_range.getGhostType();
 
     if (mesh.getSpatialDimension(type) != _spatial_dimension) {
       continue;
     }
 
     if (mesh.getKind(type) != _kind) {
       continue;
     }
 
     const auto & elements = elements_range.getElements();
 
     auto itp_type = FEEngine::getInterpolationType(type);
 
     if (not shapes.exists(itp_type, ghost_type)) {
       auto size_of_shapes = this->getShapeSize(type);
       this->shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
     }
 
     const auto & natural_coords = integration_points(type, ghost_type);
     computeShapesOnIntegrationPoints(nodes, natural_coords,
                                      shapes(itp_type, ghost_type), type,
                                      ghost_type, elements);
 
     if (_spatial_dimension != mesh.getSpatialDimension()) {
       continue;
     }
 
     if (not this->shapes_derivatives.exists(itp_type, ghost_type)) {
       auto size_of_shapesd = this->getShapeDerivativesSize(type);
       this->shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
     }
    
     computeShapeDerivativesOnIntegrationPoints(
         nodes, natural_coords, shapes_derivatives(itp_type, ghost_type), type,
         ghost_type, elements);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeLagrangeBase::onElementsRemoved(
     const Array<Element> & /*unused*/,
     const ElementTypeMapArray<UInt> & new_numbering) {
   this->shapes.onElementsRemoved(new_numbering);
   this->shapes_derivatives.onElementsRemoved(new_numbering);
 }
 
 /* -------------------------------------------------------------------------- */
 void ShapeLagrangeBase::printself(std::ostream & stream, int indent) const {
   std::string space(indent, AKANTU_INDENT);
 
   stream << space << "Shapes Lagrange [" << std::endl;
   ShapeFunctions::printself(stream, indent + 1);
   shapes.printself(stream, indent + 1);
   shapes_derivatives.printself(stream, indent + 1);
   stream << space << "]" << std::endl;
 }
 
 } // namespace akantu
diff --git a/src/fe_engine/shape_lagrange_base.hh b/src/fe_engine/shape_lagrange_base.hh
index 10a8c4c4a..a36fe6904 100644
--- a/src/fe_engine/shape_lagrange_base.hh
+++ b/src/fe_engine/shape_lagrange_base.hh
@@ -1,92 +1,92 @@
 /**
  * @file   shape_lagrange_base.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 09 2017
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  Base class for the shape lagrange
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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, UInt spatial_dimension, ElementKind kind,
                     const ID & id = "shape_lagrange");
   ~ShapeLagrangeBase() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// computes the shape functions for given interpolation points
   virtual void computeShapesOnIntegrationPoints(
       const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
-      Array<Real> & shapes, ElementType type,
-      GhostType ghost_type,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      Array<Real> & shapes, const ElementType & type,
+      const GhostType & ghost_type,
+      const Array<Int> & filter_elements = empty_filter) const;
 
   /// computes the shape functions derivatives for given interpolation points
   virtual void computeShapeDerivativesOnIntegrationPoints(
       const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
-      Array<Real> & shape_derivatives, ElementType type,
-      GhostType ghost_type,
-      const Array<UInt> & filter_elements = empty_filter) const = 0;
+      Array<Real> & shape_derivatives, const ElementType & type,
+      const GhostType & ghost_type,
+      const Array<Int> & 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 Ref<const MatrixXr> & integration_points,
-      Array<Real> & shapes, GhostType ghost_type,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      Array<Real> & shapes, const GhostType & ghost_type,
+      const Array<Int> & 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;
+                    const ElementTypeMapArray<Idx> & new_numbering) override;
 
 protected:
   /// The kind to consider
   ElementKind _kind;
 };
 
 } // namespace akantu
 
 #include "shape_lagrange_base_inline_impl.hh"
 
 #endif /* AKANTU_SHAPE_LAGRANGE_BASE_HH_ */
diff --git a/src/fe_engine/shape_lagrange_base_inline_impl.hh b/src/fe_engine/shape_lagrange_base_inline_impl.hh
index 64966ad92..b22d71b1a 100644
--- a/src/fe_engine/shape_lagrange_base_inline_impl.hh
+++ b/src/fe_engine/shape_lagrange_base_inline_impl.hh
@@ -1,87 +1,88 @@
 /**
  * @file   shape_lagrange_base_inline_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 09 2017
  * @date last modification: Tue Sep 29 2020
  *
  * @brief  common part for the shape lagrange
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
+//#include "shape_lagrange_base.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SHAPE_LAGRANGE_BASE_INLINE_IMPL_HH_
 #define AKANTU_SHAPE_LAGRANGE_BASE_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void ShapeLagrangeBase::computeShapesOnIntegrationPoints(
     const Array<Real> &, const Ref<const MatrixXr> & integration_points,
-    Array<Real> & shapes, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    Array<Real> & shapes, const GhostType & ghost_type,
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
-  UInt nb_points = integration_points.cols();
-  UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
+  auto nb_points = integration_points.cols();
+  auto nb_element = mesh.getConnectivity(type, ghost_type).size();
 
   shapes.resize(nb_element * nb_points);
 
 #if !defined(AKANTU_NDEBUG)
-  UInt size_of_shapes = ElementClass<type>::getShapeSize();
+  auto size_of_shapes = ElementClass<type>::getShapeSize();
   AKANTU_DEBUG_ASSERT(shapes.getNbComponent() == size_of_shapes,
                       "The shapes array does not have the correct "
                           << "number of component");
 #endif
 
-  auto shapes_it = shapes.begin_reinterpret(
-      ElementClass<type>::getNbNodesPerInterpolationElement(), nb_points,
-      nb_element);
+  auto shapes_it =
+      make_view(shapes, ElementClass<type>::getNbNodesPerInterpolationElement(),
+                nb_points)
+          .begin();
   auto shapes_begin = shapes_it;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
-  for (UInt elem = 0; elem < nb_element; ++elem) {
+  for (Int elem = 0; elem < nb_element; ++elem) {
     if (filter_elements != empty_filter) {
       shapes_it = shapes_begin + filter_elements(elem);
     }
 
     auto && N = *shapes_it;
     ElementClass<type>::computeShapes(integration_points, N);
 
     if (filter_elements == empty_filter) {
       ++shapes_it;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_SHAPE_LAGRANGE_BASE_INLINE_IMPL_HH_ */
diff --git a/src/fe_engine/shape_lagrange_inline_impl.hh b/src/fe_engine/shape_lagrange_inline_impl.hh
index 64d69b37c..9dbc971d7 100644
--- a/src/fe_engine/shape_lagrange_inline_impl.hh
+++ b/src/fe_engine/shape_lagrange_inline_impl.hh
@@ -1,580 +1,581 @@
 /**
  * @file   shape_lagrange_inline_impl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Mohit Pundir <mohit.pundir@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Oct 27 2010
  * @date last modification: Fri May 14 2021
  *
  * @brief  ShapeLagrange inline implementation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_voigthelper.hh"
 #include "fe_engine.hh"
 #include "shape_lagrange.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SHAPE_LAGRANGE_INLINE_IMPL_HH_
 #define AKANTU_SHAPE_LAGRANGE_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 #define INIT_SHAPE_FUNCTIONS(type)                                             \
   setIntegrationPointsByType<type>(integration_points, ghost_type);            \
   precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type);                \
   if (ElementClass<type>::getNaturalSpaceDimension() ==                        \
           mesh.getSpatialDimension() ||                                        \
       kind != _ek_regular)                                                     \
     precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
 
 template <ElementKind kind>
 inline void ShapeLagrange<kind>::initShapeFunctions(
     const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
     ElementType type, GhostType ghost_type) {
   AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
 }
 
 #undef INIT_SHAPE_FUNCTIONS
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 inline void ShapeLagrange<kind>::computeShapeDerivativesOnCPointsByElement(
-    const Ref<const MatrixXr> & node_coords, const Ref<const MatrixXr> & natural_coords,
-    Tensor3<Real> & shapesd) const {
+    const Ref<const MatrixXr> & node_coords,
+    const Ref<const MatrixXr> & natural_coords, Tensor3<Real> & shapesd) const {
   AKANTU_DEBUG_IN();
 
   // compute dnds
   Tensor3<Real> dnds(node_coords.rows(), node_coords.cols(),
                      natural_coords.cols());
   ElementClass<type>::computeDNDS(natural_coords, dnds);
   // compute jacobian
   Tensor3<Real> J(node_coords.rows(), natural_coords.rows(),
                   natural_coords.cols());
   ElementClass<type>::computeJMat(dnds, node_coords, J);
 
   // compute dndx
   ElementClass<type>::computeShapeDerivatives(J, dnds, shapesd);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::inverseMap(const Ref<const VectorXr> & real_coords,
-                                     UInt elem, Ref<VectorXr> natural_coords,
-                                     GhostType ghost_type) const {
+                                     Int elem, Ref<VectorXr> natural_coords,
+                                     const GhostType & ghost_type) const {
 
   AKANTU_DEBUG_IN();
 
-  UInt spatial_dimension = mesh.getSpatialDimension();
-  UInt nb_nodes_per_element =
+  Int spatial_dimension = mesh.getSpatialDimension();
+  Int nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
-  UInt * elem_val = mesh.getConnectivity(type, ghost_type).data();
+  auto * elem_val = mesh.getConnectivity(type, ghost_type).data();
   Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
 
   mesh.extractNodalValuesFromElement(mesh.getNodes(), nodes_coord.data(),
                                      elem_val + elem * nb_nodes_per_element,
                                      nb_nodes_per_element, spatial_dimension);
 
   ElementClass<type>::inverseMap(real_coords, nodes_coord, natural_coords);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
-bool ShapeLagrange<kind>::contains(const Ref<const VectorXr> & real_coords, UInt elem,
-                                   GhostType ghost_type) const {
+bool ShapeLagrange<kind>::contains(const Ref<const VectorXr> & real_coords,
+                                   UInt elem,
+                                   const GhostType & ghost_type) const {
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   Vector<Real> natural_coords(spatial_dimension);
 
   inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
   return ElementClass<type>::contains(natural_coords);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::interpolate(const Ref<const VectorXr> & real_coords,
                                       UInt elem,
                                       const Ref<const MatrixXr> & nodal_values,
                                       Ref<VectorXr> interpolated,
                                       GhostType ghost_type) const {
   UInt nb_shapes = ElementClass<type>::getShapeSize();
   Vector<Real> shapes(nb_shapes);
   computeShapes<type>(real_coords, elem, shapes, ghost_type);
   ElementClass<type>::interpolate(nodal_values, shapes, interpolated);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeShapes(const Ref<const VectorXr> & real_coords,
                                         UInt elem, Ref<VectorXr> shapes,
                                         GhostType ghost_type) const {
 
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   Vector<Real> natural_coords(spatial_dimension);
 
   inverseMap<type>(real_coords, elem, natural_coords, ghost_type);
   ElementClass<type>::computeShapes(natural_coords, shapes);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeShapeDerivatives(
     const Ref<const MatrixXr> & real_coords, UInt elem, Tensor3<Real> & shapesd,
     GhostType ghost_type) const {
 
   AKANTU_DEBUG_IN();
 
-  UInt spatial_dimension = mesh.getSpatialDimension();
-  UInt nb_points = real_coords.cols();
-  UInt nb_nodes_per_element =
+  auto spatial_dimension = mesh.getSpatialDimension();
+  auto nb_points = real_coords.cols();
+  auto nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   AKANTU_DEBUG_ASSERT(mesh.getSpatialDimension() == shapesd.size(0) &&
                           nb_nodes_per_element == shapesd.size(1),
                       "Shape size doesn't match");
   AKANTU_DEBUG_ASSERT(nb_points == shapesd.size(2),
                       "Number of points doesn't match shapes size");
 
   Matrix<Real> natural_coords(spatial_dimension, nb_points);
 
   // Creates the matrix of natural coordinates
-  for (UInt i = 0; i < nb_points; i++) {
+  for (Int i = 0; i < nb_points; i++) {
     Vector<Real> real_point = real_coords(i);
     Vector<Real> natural_point = natural_coords(i);
 
     inverseMap<type>(real_point, elem, natural_point, ghost_type);
   }
 
-  UInt * elem_val = mesh.getConnectivity(type, ghost_type).data();
+  Int * elem_val = mesh.getConnectivity(type, ghost_type).data();
   Matrix<Real> nodes_coord(spatial_dimension, nb_nodes_per_element);
 
   mesh.extractNodalValuesFromElement(mesh.getNodes(), nodes_coord.data(),
                                      elem_val + elem * nb_nodes_per_element,
                                      nb_nodes_per_element, spatial_dimension);
 
   computeShapeDerivativesOnCPointsByElement<type>(nodes_coord, natural_coords,
                                                   shapesd);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 ShapeLagrange<kind>::ShapeLagrange(const Mesh & mesh, UInt spatial_dimension,
                                    const ID & id)
     : ShapeLagrangeBase(mesh, spatial_dimension, kind, id) {}
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
-    Array<Real> & shape_derivatives, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    Array<Real> & shape_derivatives, const GhostType & ghost_type,
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   UInt nb_points = integration_points.cols();
   UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
 
   UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
   AKANTU_DEBUG_ASSERT(shape_derivatives.getNbComponent() == size_of_shapesd,
                       "The shapes_derivatives array does not have the correct "
                           << "number of component");
   shape_derivatives.resize(nb_element * nb_points);
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
                                        filter_elements);
 
   Real * shapesd_val = shape_derivatives.data();
   Array<Real>::matrix_iterator x_it =
       x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
     if (filter_elements != empty_filter) {
       shapesd_val = shape_derivatives.data() +
                     filter_elements(elem) * size_of_shapesd * nb_points;
     }
 
     Matrix<Real> & X = *x_it;
     Tensor3<Real> B(shapesd_val, spatial_dimension, nb_nodes_per_element,
                     nb_points);
     computeShapeDerivativesOnCPointsByElement<type>(X, integration_points, B);
 
     if (filter_elements == empty_filter) {
       shapesd_val += size_of_shapesd * nb_points;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 void ShapeLagrange<kind>::computeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, const Ref<const MatrixXr> & integration_points,
-    Array<Real> & shape_derivatives, ElementType type,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    Array<Real> & shape_derivatives, const ElementType & type,
+    const GhostType & ghost_type, const Array<Int> & filter_elements) const {
 #define AKANTU_COMPUTE_SHAPES(type)                                            \
   computeShapeDerivativesOnIntegrationPoints<type>(                            \
       nodes, integration_points, shape_derivatives, ghost_type,                \
       filter_elements);
 
   AKANTU_BOOST_REGULAR_ELEMENT_SWITCH(AKANTU_COMPUTE_SHAPES);
 
 #undef AKANTU_COMPUTE_SHAPES
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::precomputeShapesOnIntegrationPoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   Matrix<Real> & natural_coords = integration_points(type, ghost_type);
   UInt size_of_shapes = ElementClass<type>::getShapeSize();
 
   Array<Real> & shapes_tmp =
       shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
 
   this->computeShapesOnIntegrationPoints<type>(nodes, natural_coords,
                                                shapes_tmp, ghost_type);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::precomputeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   Matrix<Real> & natural_coords = integration_points(type, ghost_type);
   UInt size_of_shapesd = ElementClass<type>::getShapeDerivativesSize();
 
   Array<Real> & shapes_derivatives_tmp =
       shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
 
   this->computeShapeDerivativesOnIntegrationPoints<type>(
       nodes, natural_coords, shapes_derivatives_tmp, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::interpolateOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
     const Array<Real> & shapes, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   this->interpolateElementalFieldOnIntegrationPoints<type>(
       u_el, out_uq, ghost_type, shapes, filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::interpolateOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_degree_of_freedom,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    GhostType ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   AKANTU_DEBUG_ASSERT(shapes.exists(itp_type, ghost_type),
                       "No shapes for the type "
                           << shapes.printType(itp_type, ghost_type));
 
   this->interpolateOnIntegrationPoints<type>(in_u, out_uq, nb_degree_of_freedom,
                                              shapes(itp_type, ghost_type),
                                              ghost_type, filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::gradientOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_nablauq,
     UInt nb_degree_of_freedom, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   InterpolationType itp_type = ElementClassProperty<type>::interpolation_type;
   AKANTU_DEBUG_ASSERT(
       shapes_derivatives.exists(itp_type, ghost_type),
       "No shapes derivatives for the type "
           << shapes_derivatives.printType(itp_type, ghost_type));
 
   UInt nb_nodes_per_element =
       ElementClass<type>::getNbNodesPerInterpolationElement();
 
   Array<Real> u_el(0, nb_degree_of_freedom * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   this->gradientElementalFieldOnIntegrationPoints<type>(
       u_el, out_nablauq, ghost_type, shapes_derivatives(itp_type, ghost_type),
       filter_elements);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
-void ShapeLagrange<kind>::computeBtD(
-    const Array<Real> & Ds, Array<Real> & BtDs, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+void ShapeLagrange<kind>::computeBtD(const Array<Real> & Ds, Array<Real> & BtDs,
+                                     GhostType ghost_type,
+                                     const Array<Int> & filter_elements) const {
   auto itp_type = ElementClassProperty<type>::interpolation_type;
   const auto & shapes_derivatives =
       this->shapes_derivatives(itp_type, ghost_type);
 
   auto spatial_dimension = mesh.getSpatialDimension();
   auto nb_nodes_per_element = mesh.getNbNodesPerElement(type);
 
   Array<Real> shapes_derivatives_filtered(0,
                                           shapes_derivatives.getNbComponent());
   auto && view =
       make_view(shapes_derivatives, spatial_dimension, nb_nodes_per_element);
   auto B_it = view.begin();
   auto B_end = view.end();
 
   if (filter_elements != empty_filter) {
     FEEngine::filterElementalData(this->mesh, shapes_derivatives,
                                   shapes_derivatives_filtered, type, ghost_type,
                                   filter_elements);
     auto && view = make_view(shapes_derivatives_filtered, spatial_dimension,
                              nb_nodes_per_element);
     B_it = view.begin();
     B_end = view.end();
   }
 
   for (auto && values :
        zip(range(B_it, B_end),
            make_view(Ds, Ds.getNbComponent() / spatial_dimension,
                      spatial_dimension),
            make_view(BtDs, BtDs.getNbComponent() / nb_nodes_per_element,
                      nb_nodes_per_element))) {
     const auto & B = std::get<0>(values);
     const auto & D = std::get<1>(values);
     auto & Bt_D = std::get<2>(values);
     // transposed due to the storage layout of B
     Bt_D.template mul<false, false>(D, B);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeBtDB(
     const Array<Real> & Ds, Array<Real> & BtDBs, UInt order_d,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    GhostType ghost_type, const Array<Int> & filter_elements) const {
   auto itp_type = ElementClassProperty<type>::interpolation_type;
   const auto & shapes_derivatives =
       this->shapes_derivatives(itp_type, ghost_type);
 
   constexpr auto dim = ElementClass<type>::getSpatialDimension();
   auto nb_nodes_per_element = mesh.getNbNodesPerElement(type);
 
   Array<Real> shapes_derivatives_filtered(0,
                                           shapes_derivatives.getNbComponent());
   auto && view = make_view(shapes_derivatives, dim, nb_nodes_per_element);
   auto B_it = view.begin();
   auto B_end = view.end();
 
   if (filter_elements != empty_filter) {
     FEEngine::filterElementalData(this->mesh, shapes_derivatives,
                                   shapes_derivatives_filtered, type, ghost_type,
                                   filter_elements);
     auto && view =
         make_view(shapes_derivatives_filtered, dim, nb_nodes_per_element);
     B_it = view.begin();
     B_end = view.end();
   }
 
   if (order_d == 4) {
     UInt tangent_size = VoigtHelper<dim>::size;
     Matrix<Real> B(tangent_size, dim * nb_nodes_per_element);
     Matrix<Real> Bt_D(dim * nb_nodes_per_element, tangent_size);
 
     for (auto && values :
          zip(range(B_it, B_end), make_view(Ds, tangent_size, tangent_size),
              make_view(BtDBs, dim * nb_nodes_per_element,
                        dim * nb_nodes_per_element))) {
       const auto & Bfull = std::get<0>(values);
       const auto & D = std::get<1>(values);
       auto & Bt_D_B = std::get<2>(values);
 
       VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(Bfull, B,
                                                          nb_nodes_per_element);
       Bt_D_B = B.transpose() * D * B;
     }
   } else if (order_d == 2) {
     Matrix<Real> Bt_D(nb_nodes_per_element, dim);
     for (auto && values :
          zip(range(B_it, B_end), make_view(Ds, dim, dim),
              make_view(BtDBs, nb_nodes_per_element, nb_nodes_per_element))) {
       const auto & B = std::get<0>(values);
       const auto & D = std::get<1>(values);
       auto & Bt_D_B = std::get<2>(values);
       Bt_D_B = B.transpose() * D * B;
     }
   }
 }
 
 template <>
 template <>
 inline void ShapeLagrange<_ek_regular>::computeBtDB<_point_1>(
     const Array<Real> & /*Ds*/, Array<Real> & /*BtDBs*/, UInt /*order_d*/,
-    GhostType /*ghost_type*/, const Array<UInt> & /*filter_elements*/) const {
+    GhostType /*ghost_type*/, const Array<Int> & /*filter_elements*/) const {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeNtbN(
     const Array<Real> & bs, Array<Real> & NtbNs, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const Array<Int> & filter_elements) const {
 
   auto itp_type = ElementClassProperty<type>::interpolation_type;
   auto size_of_shapes = ElementClass<type>::getShapeSize();
   auto nb_degree_of_freedom = bs.getNbComponent();
 
   auto nb_nodes_per_element = mesh.getNbNodesPerElement(type);
   Array<Real> shapes_filtered(0, size_of_shapes);
 
   auto && view = make_view(shapes(itp_type, ghost_type), 1, size_of_shapes);
   auto N_it = view.begin();
   auto N_end = view.end();
 
   if (filter_elements != empty_filter) {
     FEEngine::filterElementalData(this->mesh, shapes(itp_type, ghost_type),
                                   shapes_filtered, type, ghost_type,
                                   filter_elements);
     auto && view = make_view(shapes_filtered, 1, size_of_shapes);
     N_it = view.begin();
     N_end = view.end();
   }
 
   Matrix<Real> Nt_b(nb_nodes_per_element, nb_degree_of_freedom);
   for (auto && values :
        zip(range(N_it, N_end), make_view(bs, nb_degree_of_freedom, 1),
            make_view(NtbNs, nb_nodes_per_element, nb_nodes_per_element))) {
     const auto & N = std::get<0>(values);
     const auto & b = std::get<1>(values);
     auto & Nt_b_N = std::get<2>(values);
     Nt_b.template mul<true, false>(N, b);
     Nt_b_N.template mul<false, false>(Nt_b, N);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeLagrange<kind>::computeNtb(
     const Array<Real> & bs, Array<Real> & Ntbs, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   Ntbs.resize(bs.size());
 
   auto size_of_shapes = ElementClass<type>::getShapeSize();
   auto itp_type = ElementClassProperty<type>::interpolation_type;
   auto nb_degree_of_freedom = bs.getNbComponent();
 
   Array<Real> shapes_filtered(0, size_of_shapes);
   auto && view = make_view(shapes(itp_type, ghost_type), 1, size_of_shapes);
   auto N_it = view.begin();
   auto N_end = view.end();
 
   if (filter_elements != empty_filter) {
     FEEngine::filterElementalData(this->mesh, shapes(itp_type, ghost_type),
                                   shapes_filtered, type, ghost_type,
                                   filter_elements);
     auto && view = make_view(shapes_filtered, 1, size_of_shapes);
     N_it = view.begin();
     N_end = view.end();
   }
 
   for (auto && values :
        zip(make_view(bs, nb_degree_of_freedom, 1), range(N_it, N_end),
            make_view(Ntbs, nb_degree_of_freedom, size_of_shapes))) {
     const auto & b = std::get<0>(values);
     const auto & N = std::get<1>(values);
     auto & Ntb = std::get<2>(values);
 
     Ntb = b * N;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_SHAPE_LAGRANGE_INLINE_IMPL_HH_ */
diff --git a/src/fe_engine/shape_structural.hh b/src/fe_engine/shape_structural.hh
index e2668d85e..96ab70638 100644
--- a/src/fe_engine/shape_structural.hh
+++ b/src/fe_engine/shape_structural.hh
@@ -1,201 +1,201 @@
 /**
  * @file   shape_structural.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Feb 15 2011
  * @date last modification: Fri May 14 2021
  *
  * @brief  shape class for element with different set of shapes functions
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_STRUCTURAL_HH_
 #define AKANTU_SHAPE_STRUCTURAL_HH_
 
 namespace akantu {
 
 template <ElementKind kind> class ShapeStructural : public ShapeFunctions {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   // Ctors/Dtors should be explicitely implemented for _ek_structural
 public:
   ShapeStructural(Mesh & mesh, UInt spatial_dimension,
                   const ID & id = "shape_structural");
   ~ShapeStructural() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override {
     std::string space(indent, AKANTU_INDENT);
     stream << space << "ShapesStructural [" << std::endl;
     rotation_matrices.printself(stream, indent + 1);
     ShapeFunctions::printself(stream, indent + 1);
     stream << space << "]" << std::endl;
   }
 
 private:
   template <ElementType type>
   void computeShapesOnIntegrationPointsInternal(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shapes, GhostType ghost_type,
       const Array<UInt> & filter_elements = empty_filter,
       bool mass = false) const;
 
 public:
   /// compute shape functions on given integration points
   template <ElementType type>
   void computeShapesOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shapes, GhostType ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const {
     this->template computeShapesOnIntegrationPointsInternal<type>(
         nodes, integration_points, shapes, ghost_type, filter_elements, false);
   }
 
   template <ElementType type>
   void computeShapesMassOnIntegrationPoints(
       const Array<Real> & nodes, const Matrix<Real> & integration_points,
       Array<Real> & shapes, GhostType ghost_type,
       const Array<UInt> & filter_elements = empty_filter) const {
     this->template computeShapesOnIntegrationPointsInternal<type>(
         nodes, integration_points, shapes, ghost_type, filter_elements, true);
   }
 
   /// initialization function for structural elements
   inline void initShapeFunctions(const Array<Real> & nodes,
                                  const Matrix<Real> & integration_points,
                                  ElementType type, GhostType ghost_type);
 
   /// precompute the rotation matrices for the elements dofs
   template <ElementType type>
   void precomputeRotationMatrices(const Array<Real> & nodes,
                                   GhostType ghost_type);
 
   /// 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 shapes 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>
   void interpolateOnIntegrationPoints(
-      const Array<Real> & u, Array<Real> & uq, UInt nb_dof,
-      GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      const Array<Real> & u, Array<Real> & uq, UInt nb_degree_of_freedom,
+      const GhostType & ghost_type = _not_ghost,
+      const Array<Int> & filter_elements = empty_filter) const;
 
   /// compute the gradient of u on the integration points
   template <ElementType type>
   void gradientOnIntegrationPoints(
-      const Array<Real> & u, Array<Real> & nablauq, UInt nb_dof,
-      GhostType ghost_type = _not_ghost,
-      const Array<UInt> & filter_elements = empty_filter) const;
+      const Array<Real> & u, Array<Real> & nablauq, UInt nb_degree_of_freedom,
+      const GhostType & ghost_type = _not_ghost,
+      const Array<Int> & 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*/,
                    GhostType /*ghost_type*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the shapes on a provided point
   template <ElementType type>
   void computeShapes(const Vector<Real> & /*real_coords*/, UInt /*elem*/,
                      Vector<Real> & /*shapes*/,
                      GhostType /*ghost_type*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the shape derivatives on a provided point
   template <ElementType type>
   void computeShapeDerivatives(const Matrix<Real> & /*real_coords*/,
                                UInt /*elem*/, Tensor3<Real> & /*shapes*/,
                                GhostType /*ghost_type*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// get the rotations vector
   inline const Array<Real> &
   getRotations(ElementType el_type, __attribute__((unused))
                                     GhostType ghost_type = _not_ghost) const {
     return rotation_matrices(el_type);
   }
 
   /* ------------------------------------------------------------------------ */
   template <ElementType type>
   void computeBtD(const Array<Real> & /*Ds*/, Array<Real> & /*BtDs*/,
                   GhostType /*ghost_type*/,
-                  const Array<UInt> & /*filter_elements*/) const {
+                  const Array<Int> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   template <ElementType type>
   void computeBtDB(const Array<Real> & /*Ds*/, Array<Real> & /*BtDBs*/,
                    UInt /*order_d*/, GhostType /*ghost_type*/,
-                   const Array<UInt> & /*filter_elements*/) const {
+                   const Array<Int> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   template <ElementType type>
   void computeNtbN(const Array<Real> & /*bs*/, Array<Real> & /*NtbNs*/,
                    GhostType /*ghost_type*/,
                    const Array<UInt> & /*filter_elements*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// multiply a field by shape functions
   template <ElementType type>
   void
   computeNtb(const Array<Real> & /*bs*/, Array<Real> & /*Ntbs*/,
-             GhostType /*ghost_type*/,
-             const Array<UInt> & /*filter_elements*/ = empty_filter) const {
+             const GhostType & /*ghost_type*/,
+             const Array<Int> & /*filter_elements*/ = empty_filter) const {
     AKANTU_TO_IMPLEMENT();
   }
 
 protected:
   ElementTypeMapArray<Real> rotation_matrices;
 };
 
 } // namespace akantu
 
 #include "shape_structural_inline_impl.hh"
 
 #endif /* AKANTU_SHAPE_STRUCTURAL_HH_ */
diff --git a/src/fe_engine/shape_structural_inline_impl.hh b/src/fe_engine/shape_structural_inline_impl.hh
index 8b7f422fe..6dba6fbd8 100644
--- a/src/fe_engine/shape_structural_inline_impl.hh
+++ b/src/fe_engine/shape_structural_inline_impl.hh
@@ -1,504 +1,506 @@
 /**
  * @file   shape_structural_inline_impl.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Oct 11 2017
  * @date last modification: Mon Feb 01 2021
  *
  * @brief  ShapeStructural inline implementation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_iterators.hh"
 //#include "shape_structural.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_HH_
 #define AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_HH_
 
 namespace akantu {
 
 namespace {
   /// Extract nodal coordinates per elements
   template <ElementType type>
   std::unique_ptr<Array<Real>> getNodesPerElement(const Mesh & mesh,
                                                   const Array<Real> & nodes,
                                                   GhostType ghost_type) {
     const auto dim = ElementClass<type>::getSpatialDimension();
     const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     auto nodes_per_element =
         std::make_unique<Array<Real>>(0, dim * nb_nodes_per_element);
     FEEngine::extractNodalToElementField(mesh, nodes, *nodes_per_element, type,
                                          ghost_type);
     return nodes_per_element;
   }
 } // namespace
 
 template <ElementKind kind>
 inline void ShapeStructural<kind>::initShapeFunctions(
     const Array<Real> & /* unused */, const Matrix<Real> & /* unused */,
     ElementType /* unused */, GhostType /* unused */) {
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 #define INIT_SHAPE_FUNCTIONS(type)                                             \
   setIntegrationPointsByType<type>(integration_points, ghost_type);            \
   precomputeRotationMatrices<type>(nodes, ghost_type);                         \
   precomputeShapesOnIntegrationPoints<type>(nodes, ghost_type);                \
   precomputeShapeDerivativesOnIntegrationPoints<type>(nodes, ghost_type);
 
 template <>
 inline void ShapeStructural<_ek_structural>::initShapeFunctions(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
     ElementType type, GhostType ghost_type) {
   AKANTU_BOOST_STRUCTURAL_ELEMENT_SWITCH(INIT_SHAPE_FUNCTIONS);
 }
 
 #undef INIT_SHAPE_FUNCTIONS
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::computeShapesOnIntegrationPointsInternal(
     const Array<Real> & nodes, const Matrix<Real> & integration_points,
-    Array<Real> & shapes, GhostType ghost_type,
-    const Array<UInt> & filter_elements, bool mass) const {
+    Array<Real> & shapes, const GhostType & ghost_type,
+    const Array<Int> & filter_elements) const {
 
   auto nb_points = integration_points.cols();
   auto nb_element = mesh.getConnectivity(type, ghost_type).size();
   auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
 
   shapes.resize(nb_element * nb_points);
 
   auto nb_dofs = ElementClass<type>::getNbDegreeOfFreedom();
   auto nb_rows = nb_dofs;
   if (mass) {
     nb_rows = ElementClass<type>::getNbStressComponents();
   }
 
 #if !defined(AKANTU_NDEBUG)
   UInt size_of_shapes = nb_rows * nb_dofs * nb_nodes_per_element;
   AKANTU_DEBUG_ASSERT(shapes.getNbComponent() == size_of_shapes,
                       "The shapes array does not have the correct "
                           << "number of component");
 #endif
 
 
   auto shapes_it = shapes.begin_reinterpret(
       nb_rows, ElementClass<type>::getNbNodesPerInterpolationElement() * nb_dofs,
       nb_points, nb_element);
   auto shapes_begin = shapes_it;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
   }
 
   auto nodes_per_element = getNodesPerElement<type>(mesh, nodes, ghost_type);
   auto nodes_it = nodes_per_element->begin(mesh.getSpatialDimension(),
                                            Mesh::getNbNodesPerElement(type));
   auto nodes_begin = nodes_it;
   auto rot_matrix_it =
       make_view(rotation_matrices(type, ghost_type), nb_dofs, nb_dofs).begin();
   auto rot_matrix_begin = rot_matrix_it;
 
   for (UInt elem = 0; elem < nb_element; ++elem) {
     if (filter_elements != empty_filter) {
       shapes_it = shapes_begin + filter_elements(elem);
       nodes_it = nodes_begin + filter_elements(elem);
       rot_matrix_it = rot_matrix_begin + filter_elements(elem);
     }
 
     Tensor3<Real> & N = *shapes_it;
     auto & real_coord = *nodes_it;
 
     auto & RDOFs = *rot_matrix_it;
 
     Matrix<Real> T(N.size(1), N.size(1), 0);
 
     for (UInt i = 0; i < nb_nodes_per_element; ++i) {
       T.block(RDOFs, i * RDOFs.rows(), i * RDOFs.rows());
     }
 
     if (not mass) {
       ElementClass<type>::computeShapes(integration_points, real_coord, T, N);
     } else {
       ElementClass<type>::computeShapesMass(integration_points, real_coord, T,
                                             N);
     }
     if (filter_elements == empty_filter) {
       ++shapes_it;
       ++nodes_it;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::precomputeRotationMatrices(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   const auto spatial_dimension = mesh.getSpatialDimension();
   const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   const auto nb_element = mesh.getNbElement(type, ghost_type);
   const auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
 
   if (not this->rotation_matrices.exists(type, ghost_type)) {
     this->rotation_matrices.alloc(0, nb_dof * nb_dof, type, ghost_type);
   }
 
   auto & rot_matrices = this->rotation_matrices(type, ghost_type);
   rot_matrices.resize(nb_element);
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
 
   bool has_extra_normal = mesh.hasData<Real>("extra_normal", type, ghost_type);
   Array<Real>::const_vector_iterator extra_normal;
   if (has_extra_normal) {
     extra_normal = mesh.getData<Real>("extra_normal", type, ghost_type)
                        .begin(spatial_dimension);
   }
 
   for (auto && tuple :
        zip(make_view(x_el, spatial_dimension, nb_nodes_per_element),
            make_view(rot_matrices, nb_dof, nb_dof))) {
     // compute shape derivatives
     auto & X = std::get<0>(tuple);
     auto & R = std::get<1>(tuple);
 
     if (has_extra_normal) {
       ElementClass<type>::computeRotationMatrix(R, X, *extra_normal);
       ++extra_normal;
     } else {
       ElementClass<type>::computeRotationMatrix(
           R, X, Vector<Real>(spatial_dimension));
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::precomputeShapesOnIntegrationPoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   const auto & natural_coords = integration_points(type, ghost_type);
   auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   auto nb_points = integration_points(type, ghost_type).cols();
   auto nb_element = mesh.getNbElement(type, ghost_type);
   auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
   const auto dim = ElementClass<type>::getSpatialDimension();
   const auto spatial_dimension = mesh.getSpatialDimension();
   const auto natural_spatial_dimension =
       ElementClass<type>::getNaturalSpaceDimension();
 
   auto itp_type = FEEngine::getInterpolationType(type);
   if (not shapes.exists(itp_type, ghost_type)) {
     auto size_of_shapes = this->getShapeSize(type);
     this->shapes.alloc(0, size_of_shapes, itp_type, ghost_type);
   }
 
   auto & rot_matrices = this->rotation_matrices(type, ghost_type);
   auto & shapes_ = this->shapes(itp_type, ghost_type);
   shapes_.resize(nb_element * nb_points);
 
   auto nodes_per_element = getNodesPerElement<type>(mesh, nodes, ghost_type);
 
   for (auto && tuple :
        zip(make_view(shapes_, nb_dof, nb_dof * nb_nodes_per_element, nb_points),
            make_view(*nodes_per_element, dim, nb_nodes_per_element),
            make_view(rot_matrices, nb_dof, nb_dof))) {
     auto & N = std::get<0>(tuple);
     auto & X = std::get<1>(tuple);
     auto & RDOFs = std::get<2>(tuple);
 
     Matrix<Real> T(N.size(1), N.size(1), 0);
 
     for (UInt i = 0; i < nb_nodes_per_element; ++i) {
       T.block(RDOFs, i * RDOFs.rows(), i * RDOFs.rows());
     }
 
     auto R = RDOFs.block(0, 0, spatial_dimension, spatial_dimension);
     // Rotate to local basis
     auto x =
         (R * X).block(0, 0, natural_spatial_dimension, nb_nodes_per_element);
 
     ElementClass<type>::computeShapes(natural_coords, x, T, N);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::precomputeShapeDerivativesOnIntegrationPoints(
     const Array<Real> & nodes, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   const auto & natural_coords = integration_points(type, ghost_type);
   const auto spatial_dimension = mesh.getSpatialDimension();
   const auto natural_spatial_dimension =
       ElementClass<type>::getNaturalSpaceDimension();
   const auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   const auto nb_points = natural_coords.cols();
   const auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
   const auto nb_element = mesh.getNbElement(type, ghost_type);
   const auto nb_stress_components = ElementClass<type>::getNbStressComponents();
 
   auto itp_type = FEEngine::getInterpolationType(type);
   if (not this->shapes_derivatives.exists(itp_type, ghost_type)) {
     auto size_of_shapesd = this->getShapeDerivativesSize(type);
     this->shapes_derivatives.alloc(0, size_of_shapesd, itp_type, ghost_type);
   }
 
   auto & rot_matrices = this->rotation_matrices(type, ghost_type);
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type);
 
   auto & shapesd = this->shapes_derivatives(itp_type, ghost_type);
   shapesd.resize(nb_element * nb_points);
 
   for (auto && tuple :
        zip(make_view(x_el, spatial_dimension, nb_nodes_per_element),
            make_view(shapesd, nb_stress_components,
                      nb_nodes_per_element * nb_dof, nb_points),
            make_view(rot_matrices, nb_dof, nb_dof))) {
     // compute shape derivatives
     auto & x = std::get<0>(tuple);
     auto & B = std::get<1>(tuple);
     auto & RDOFs = std::get<2>(tuple);
 
     Tensor3<Real> dnds(natural_spatial_dimension,
                        ElementClass<type>::interpolation_property::dnds_columns,
                        B.size(2));
     ElementClass<type>::computeDNDS(natural_coords, x, dnds);
 
     Tensor3<Real> J(natural_spatial_dimension, natural_spatial_dimension,
                     natural_coords.cols());
 
     // Computing the coordinates of the element in the natural space
     auto && R = RDOFs.block(0, 0, spatial_dimension, spatial_dimension);
     Matrix<Real> T(B.size(1), B.size(1));
     T.fill(0);
 
-    for (UInt i = 0; i < nb_nodes_per_element; ++i) {
-      T.block(i * RDOFs.rows(), i * RDOFs.rows(), RDOFs.rows(), RDOFs.cols()) = RDOFs;
+    for (Int i = 0; i < nb_nodes_per_element; ++i) {
+      T.block(i * RDOFs.rows(), i * RDOFs.rows(), RDOFs.rows(), RDOFs.cols()) =
+          RDOFs;
     }
 
     // Rotate to local basis
     auto && rx =
         (R * x).block(0, 0, natural_spatial_dimension, nb_nodes_per_element);
 
     ElementClass<type>::computeJMat(natural_coords, rx, J);
     ElementClass<type>::computeShapeDerivatives(J, dnds, T, B);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::interpolateOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_uq, UInt nb_dof,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    const GhostType & ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(out_uq.getNbComponent() == nb_dof,
                       "The output array shape is not correct");
 
   auto itp_type = FEEngine::getInterpolationType(type);
   const auto & shapes_ = shapes(itp_type, ghost_type);
 
   auto nb_element = mesh.getNbElement(type, ghost_type);
   auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
   auto nb_quad_points_per_element = integration_points(type, ghost_type).cols();
 
   Array<Real> u_el(0, nb_nodes_per_element * nb_dof);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   auto nb_quad_points = nb_quad_points_per_element * u_el.size();
   out_uq.resize(nb_quad_points);
 
-  auto out_it = out_uq.begin_reinterpret(nb_dof, 1, nb_quad_points_per_element,
-                                         u_el.size());
-  auto shapes_it =
-      shapes_.begin_reinterpret(nb_dof, nb_dof * nb_nodes_per_element,
-                                nb_quad_points_per_element, nb_element);
-  auto u_it = u_el.begin_reinterpret(nb_dof * nb_nodes_per_element, 1,
-                                     nb_quad_points_per_element, u_el.size());
+  auto out_it =
+      make_view(out_uq, nb_dof, 1, nb_quad_points_per_element).begin();
+  auto shapes_it = make_view(shapes_, nb_dof, nb_dof * nb_nodes_per_element,
+                             nb_quad_points_per_element)
+                       .begin();
+  auto u_it = make_view(u_el, nb_dof * nb_nodes_per_element, 1,
+                        nb_quad_points_per_element)
+                  .begin();
 
   for_each_element(nb_element, filter_elements, [&](auto && el) {
     auto & uq = *out_it;
     const auto & u = *u_it;
     auto && N = shapes_it[el];
 
     for (auto && q : arange(uq.size(2))) {
       uq(q) = N(q) * u(q);
     }
 
     ++out_it;
     ++u_it;
   });
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind>
 template <ElementType type>
 void ShapeStructural<kind>::gradientOnIntegrationPoints(
     const Array<Real> & in_u, Array<Real> & out_nablauq, UInt nb_dof,
-    GhostType ghost_type, const Array<UInt> & filter_elements) const {
+    const GhostType & ghost_type, const Array<Int> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   auto itp_type = FEEngine::getInterpolationType(type);
   const auto & shapesd = shapes_derivatives(itp_type, ghost_type);
 
   auto nb_element = mesh.getNbElement(type, ghost_type);
   auto element_dimension = ElementClass<type>::getSpatialDimension();
   auto nb_quad_points_per_element = integration_points(type, ghost_type).cols();
   auto nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement();
 
   Array<Real> u_el(0, nb_nodes_per_element * nb_dof);
   FEEngine::extractNodalToElementField(mesh, in_u, u_el, type, ghost_type,
                                        filter_elements);
 
   auto nb_quad_points = nb_quad_points_per_element * u_el.size();
   out_nablauq.resize(nb_quad_points);
 
   auto out_it = out_nablauq.begin_reinterpret(
       element_dimension, 1, nb_quad_points_per_element, u_el.size());
   auto shapesd_it = shapesd.begin_reinterpret(
       element_dimension, nb_dof * nb_nodes_per_element,
       nb_quad_points_per_element, nb_element);
   auto u_it = u_el.begin_reinterpret(nb_dof * nb_nodes_per_element, 1,
                                      nb_quad_points_per_element, u_el.size());
 
   for_each_element(nb_element, filter_elements, [&](auto && el) {
     auto & nablau = *out_it;
     const auto & u = *u_it;
     auto B = Tensor3<Real>(shapesd_it[el]);
 
     for (auto && q : arange(nablau.size(2))) {
       nablau(q) = B(q) * u(q);
     }
 
     ++out_it;
     ++u_it;
   });
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <ElementType type>
 void ShapeStructural<_ek_structural>::computeBtD(
     const Array<Real> & Ds, Array<Real> & BtDs, GhostType ghost_type,
-    const Array<UInt> & filter_elements) const {
+    const Array<Int> & filter_elements) const {
   auto itp_type = ElementClassProperty<type>::interpolation_type;
 
   auto nb_stress = ElementClass<type>::getNbStressComponents();
   auto nb_dof_per_element = ElementClass<type>::getNbDegreeOfFreedom() *
                             mesh.getNbNodesPerElement(type);
 
   const auto & shapes_derivatives =
       this->shapes_derivatives(itp_type, ghost_type);
 
   Array<Real> shapes_derivatives_filtered(0,
                                           shapes_derivatives.getNbComponent());
   auto && view = make_view(shapes_derivatives, nb_stress, nb_dof_per_element);
   auto B_it = view.begin();
   auto B_end = view.end();
 
   if (filter_elements != empty_filter) {
     FEEngine::filterElementalData(this->mesh, shapes_derivatives,
                                   shapes_derivatives_filtered, type, ghost_type,
                                   filter_elements);
     auto && view =
         make_view(shapes_derivatives_filtered, nb_stress, nb_dof_per_element);
     B_it = view.begin();
     B_end = view.end();
   }
 
   for (auto && values : zip(range(B_it, B_end), make_view(Ds, nb_stress),
                             make_view(BtDs, BtDs.getNbComponent()))) {
     const auto & B = std::get<0>(values);
     const auto & D = std::get<1>(values);
     auto & Bt_D = std::get<2>(values);
     Bt_D.template mul<true>(B, D);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 template <ElementType type>
 void ShapeStructural<_ek_structural>::computeNtb(
     const Array<Real> & bs, Array<Real> & Ntbs, GhostType ghost_type,
     const Array<UInt> & filter_elements) const {
   auto itp_type = ElementClassProperty<type>::interpolation_type;
 
   auto nb_dof = ElementClass<type>::getNbDegreeOfFreedom();
   auto nb_nodes_per_element = mesh.getNbNodesPerElement(type);
 
   const auto & shapes = this->shapes(itp_type, ghost_type);
 
   Array<Real> shapes_filtered(0, shapes.getNbComponent());
   auto && view = make_view(shapes, nb_dof, nb_dof * nb_nodes_per_element);
   auto N_it = view.begin();
   auto N_end = view.end();
 
   if (filter_elements != empty_filter) {
     FEEngine::filterElementalData(this->mesh, shapes, shapes_filtered, type,
                                   ghost_type, filter_elements);
     auto && view =
         make_view(shapes_filtered, nb_dof, nb_dof * nb_nodes_per_element);
     N_it = view.begin();
     N_end = view.end();
   }
 
   for (auto && values : zip(range(N_it, N_end), make_view(bs, nb_dof),
                             make_view(Ntbs, nb_dof * nb_nodes_per_element))) {
     const auto & N = std::get<0>(values);
     const auto & b = std::get<1>(values);
     auto & Nt_b = std::get<2>(values);
     Nt_b.template mul<true>(N, b);
   }
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_SHAPE_STRUCTURAL_INLINE_IMPL_HH_ */
diff --git a/src/io/dumper/dumpable_dummy.hh b/src/io/dumper/dumpable_dummy.hh
index 8faf9f80c..3a6a1bd54 100644
--- a/src/io/dumper/dumpable_dummy.hh
+++ b/src/io/dumper/dumpable_dummy.hh
@@ -1,270 +1,270 @@
 /**
  * @file   dumpable_dummy.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Oct 26 2012
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Interface for object who wants to dump themselves
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 /* -------------------------------------------------------------------------- */
 
 #if !defined(DOXYGEN)
 #ifndef AKANTU_DUMPABLE_DUMMY_HH_
 #define AKANTU_DUMPABLE_DUMMY_HH_
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused"
 
 namespace dumpers {
   class Field;
 }
 
 class DumperIOHelper;
 class Mesh;
 
 /* -------------------------------------------------------------------------- */
 class Dumpable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Dumpable(){};
   virtual ~Dumpable(){};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   template <class T>
   inline void registerDumper(const std::string & dumper_name,
                              const std::string & file_name = "",
                              const bool is_default = false) {}
 
   void registerExternalDumper(std::shared_ptr<DumperIOHelper> dumper,
                               const std::string & dumper_name,
                               const bool is_default = false) {}
 
-  void addDumpMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
-                   GhostType ghost_type = _not_ghost,
-                   ElementKind element_kind = _ek_not_defined) {}
+  void addDumpMesh(const Mesh & mesh, Int spatial_dimension = _all_dimensions,
+                   const GhostType & ghost_type = _not_ghost,
+                   const ElementKind & element_kind = _ek_not_defined) {}
 
   void addDumpMeshToDumper(const std::string & dumper_name, const Mesh & mesh,
-                           UInt spatial_dimension = _all_dimensions,
-                           GhostType ghost_type = _not_ghost,
-                           ElementKind element_kind = _ek_not_defined) {
+                           Int spatial_dimension = _all_dimensions,
+                           const GhostType & ghost_type = _not_ghost,
+                           const ElementKind & element_kind = _ek_not_defined) {
   }
 
   void addDumpFilteredMesh(const Mesh & mesh,
-                           const ElementTypeMapArray<UInt> & elements_filter,
-                           const Array<UInt> & nodes_filter,
-                           UInt spatial_dimension = _all_dimensions,
-                           GhostType ghost_type = _not_ghost,
-                           ElementKind element_kind = _ek_not_defined) {
+                           const ElementTypeMapArray<Idx> & elements_filter,
+                           const Array<Idx> & nodes_filter,
+                           Int spatial_dimension = _all_dimensions,
+                           const GhostType & ghost_type = _not_ghost,
+                           const ElementKind & element_kind = _ek_not_defined) {
   }
 
   void addDumpFilteredMeshToDumper(
       const std::string & dumper_name, const Mesh & mesh,
-      const ElementTypeMapArray<UInt> & elements_filter,
-      const Array<UInt> & nodes_filter,
-      UInt spatial_dimension = _all_dimensions,
-      GhostType ghost_type = _not_ghost,
-      ElementKind element_kind = _ek_not_defined) {}
+      const ElementTypeMapArray<Idx> & elements_filter,
+      const Array<Idx> & nodes_filter,
+      Int spatial_dimension = _all_dimensions,
+      const GhostType & ghost_type = _not_ghost,
+      const ElementKind & element_kind = _ek_not_defined) {}
 
   virtual void addDumpField(const std::string & field_id) {
     AKANTU_TO_IMPLEMENT();
   }
   virtual void addDumpFieldToDumper(const std::string & dumper_name,
                                     const std::string & field_id) {
     AKANTU_TO_IMPLEMENT();
   }
 
   virtual void addDumpFieldExternal(const std::string & field_id,
                                     std::shared_ptr<dumpers::Field> field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   virtual void
   addDumpFieldExternalToDumper(const std::string & dumper_name,
                                const std::string & field_id,
                                std::shared_ptr<dumpers::Field> field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   template <typename T>
   void addDumpFieldExternal(const std::string & field_id,
                             const Array<T> & field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   template <typename T>
   void addDumpFieldExternalToDumper(const std::string & dumper_name,
                                     const std::string & field_id,
                                     const Array<T> & field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   template <typename T>
   void
   addDumpFieldExternal(const std::string & field_id,
                        const ElementTypeMapArray<T> & field,
-                       UInt spatial_dimension = _all_dimensions,
-                       GhostType ghost_type = _not_ghost,
-                       ElementKind element_kind = _ek_not_defined) {
+                       Int spatial_dimension = _all_dimensions,
+                       const GhostType & ghost_type = _not_ghost,
+                       const ElementKind & element_kind = _ek_not_defined) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   template <typename T>
   void addDumpFieldExternalToDumper(
       const std::string & dumper_name, const std::string & field_id,
       const ElementTypeMapArray<T> & field,
-      UInt spatial_dimension = _all_dimensions,
-      GhostType ghost_type = _not_ghost,
-      ElementKind element_kind = _ek_not_defined) {
+      Int spatial_dimension = _all_dimensions,
+      const GhostType & ghost_type = _not_ghost,
+      const ElementKind & element_kind = _ek_not_defined) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void removeDumpField(const std::string & field_id) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void removeDumpFieldFromDumper(const std::string & dumper_name,
                                  const std::string & field_id) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void setDirecory(const std::string & directory) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void setDirectoryToDumper(const std::string & dumper_name,
                             const std::string & directory) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void setBaseName(const std::string & basename) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void setBaseNameToDumper(const std::string & dumper_name,
                            const std::string & basename) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void setTextModeToDumper(const std::string & dumper_name) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void setTextModeToDumper() {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
   void dump() {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
   void dump(const std::string & dumper_name) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
-  void dump(UInt step) {
+  void dump(Int step) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
-  void dump(const std::string & dumper_name, UInt step) {
+  void dump(const std::string & dumper_name, Int step) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
-  void dump(Real current_time, UInt step) {
+  void dump(Real current_time, Int step) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
-  void dump(const std::string & dumper_name, Real current_time, UInt step) {
+  void dump(const std::string & dumper_name, Real current_time, Int step) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
 protected:
   void internalAddDumpFieldToDumper(const std::string & dumper_name,
                                     const std::string & field_id,
                                     std::shared_ptr<dumpers::Field> field) {
     AKANTU_DEBUG_WARNING("No dumper activated at compilation, turn on "
                          "AKANTU_USE_IOHELPER in cmake.");
   }
 
 protected:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   DumperIOHelper & getDumper() {
     AKANTU_ERROR("No dumper activated at compilation, turn on "
                  "AKANTU_USE_IOHELPER in cmake.");
   }
 
   DumperIOHelper & getDumper(const std::string & dumper_name) {
     AKANTU_ERROR("No dumper activated at compilation, turn on "
                  "AKANTU_USE_IOHELPER in cmake.");
   }
 
   template <class T> T & getDumper(const std::string & dumper_name) {
     AKANTU_ERROR("No dumper activated at compilation, turn on "
                  "AKANTU_USE_IOHELPER in cmake.");
   }
 
   std::string getDefaultDumperName() {
     AKANTU_ERROR("No dumper activated at compilation, turn on "
                  "AKANTU_USE_IOHELPER in cmake.");
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 #pragma GCC diagnostic pop
 
 } // namespace akantu
 
 #endif /* AKANTU_DUMPABLE_DUMMY_HH_ */
 #endif // DOXYGEN
diff --git a/src/io/dumper/dumpable_inline_impl.hh b/src/io/dumper/dumpable_inline_impl.hh
index 0fd69200c..ebc3c8cb9 100644
--- a/src/io/dumper/dumpable_inline_impl.hh
+++ b/src/io/dumper/dumpable_inline_impl.hh
@@ -1,137 +1,141 @@
 /**
  * @file   dumpable_inline_impl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Implementation of the Dumpable class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+/* -------------------------------------------------------------------------- */
+#include "aka_config.hh"
+/* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_DUMPABLE_INLINE_IMPL_HH_
 #define AKANTU_DUMPABLE_INLINE_IMPL_HH_
 
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
+
 #include "dumper_elemental_field.hh"
 #include "dumper_nodal_field.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 inline void Dumpable::registerDumper(const std::string & dumper_name,
                                      const std::string & file_name,
                                      const bool is_default) {
 
   if (this->dumpers.find(dumper_name) != this->dumpers.end()) {
     AKANTU_DEBUG_INFO("Dumper " + dumper_name + "is already registered.");
   }
 
   std::string name = file_name;
   if (name.empty()) {
     name = dumper_name;
   }
 
   this->dumpers[dumper_name] = std::make_shared<T>(name);
 
   if (is_default) {
     this->default_dumper = dumper_name;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Dumpable::addDumpFieldExternal(const std::string & field_id,
                                            const Array<T> & field) {
   this->addDumpFieldExternalToDumper<T>(this->default_dumper, field_id, field);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void
 Dumpable::addDumpFieldExternalToDumper(const std::string & dumper_name,
                                        const std::string & field_id,
                                        const Array<T> & field) {
   auto field_cont = std::make_shared<dumpers::NodalField<T>>(field);
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.registerField(field_id, field_cont);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Dumpable::addDumpFieldExternal(const std::string & field_id,
                                            const ElementTypeMapArray<T> & field,
-                                           UInt spatial_dimension,
-                                           GhostType ghost_type,
-                                           ElementKind element_kind) {
+                                           Int spatial_dimension,
+                                           const GhostType & ghost_type,
+                                           const ElementKind & element_kind) {
   this->addDumpFieldExternalToDumper(this->default_dumper, field_id, field,
                                      spatial_dimension, ghost_type,
                                      element_kind);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Dumpable::addDumpFieldExternalToDumper(
     const std::string & dumper_name, const std::string & field_id,
-    const ElementTypeMapArray<T> & field, UInt spatial_dimension,
-    GhostType ghost_type, ElementKind element_kind) {
+    const ElementTypeMapArray<T> & field, Int spatial_dimension,
+    const GhostType & ghost_type, const ElementKind & element_kind) {
 
   std::shared_ptr<dumpers::Field> field_cont;
 #if defined(AKANTU_IGFEM)
   if (element_kind == _ek_igfem) {
     field_cont = std::make_shared<dumpers::IGFEMElementalField<T>>(
         field, spatial_dimension, ghost_type, element_kind);
   } else
 #endif
     field_cont = std::make_shared<dumpers::ElementalField<T>>(
         field, spatial_dimension, ghost_type, element_kind);
   DumperIOHelper & dumper = this->getDumper(dumper_name);
   dumper.registerField(field_id, field_cont);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 inline T & Dumpable::getDumper(const std::string & dumper_name) {
   DumperIOHelper & dumper = this->getDumper(dumper_name);
 
   try {
     auto & templated_dumper = aka::as_type<T>(dumper);
     return templated_dumper;
   } catch (std::bad_cast &) {
     AKANTU_EXCEPTION("Dumper " << dumper_name << " is not of type: "
                                << debug::demangle(typeid(T).name()));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif
 
 #endif /* AKANTU_DUMPABLE_INLINE_IMPL_HH_ */
diff --git a/src/io/dumper/dumpable_iohelper.hh b/src/io/dumper/dumpable_iohelper.hh
index 381044d06..5e8d4a1a5 100644
--- a/src/io/dumper/dumpable_iohelper.hh
+++ b/src/io/dumper/dumpable_iohelper.hh
@@ -1,194 +1,194 @@
 /**
  * @file   dumpable_iohelper.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jan 06 2015
  * @date last modification: Fri Feb 28 2020
  *
  * @brief  Interface for object who wants to dump themselves
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_iohelper.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_DUMPABLE_IOHELPER_HH_
 #define AKANTU_DUMPABLE_IOHELPER_HH_
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class Dumpable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Dumpable();
   virtual ~Dumpable();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// create a new dumper (of templated type T) and register it under
   /// dumper_name. file_name is used for construction of T. is default states if
   /// this dumper is the default dumper.
   template <class T>
   inline void registerDumper(const std::string & dumper_name,
                              const std::string & file_name = "",
                              bool is_default = false);
 
   /// register an externally created dumper
   void registerExternalDumper(std::shared_ptr<DumperIOHelper> dumper,
                               const std::string & dumper_name,
                               bool is_default = false);
 
   /// register a mesh to the default dumper
-  void addDumpMesh(const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
-                   GhostType ghost_type = _not_ghost,
-                   ElementKind element_kind = _ek_not_defined);
+  void addDumpMesh(const Mesh & mesh, Int spatial_dimension = _all_dimensions,
+                   const GhostType & ghost_type = _not_ghost,
+                   const ElementKind & element_kind = _ek_not_defined);
 
   /// register a mesh to the default identified by its name
   void addDumpMeshToDumper(const std::string & dumper_name, const Mesh & mesh,
-                           UInt spatial_dimension = _all_dimensions,
-                           GhostType ghost_type = _not_ghost,
-                           ElementKind element_kind = _ek_not_defined);
+                           Int spatial_dimension = _all_dimensions,
+                           const GhostType & ghost_type = _not_ghost,
+                           const ElementKind & element_kind = _ek_not_defined);
 
   /// register a filtered mesh as the default dumper
   void addDumpFilteredMesh(const Mesh & mesh,
-                           const ElementTypeMapArray<UInt> & elements_filter,
-                           const Array<UInt> & nodes_filter,
+                           const ElementTypeMapArray<Idx> & elements_filter,
+                           const Array<Idx> & nodes_filter,
                            UInt spatial_dimension = _all_dimensions,
                            GhostType ghost_type = _not_ghost,
                            ElementKind element_kind = _ek_not_defined);
 
   /// register a filtered mesh and provides a name
   void addDumpFilteredMeshToDumper(
       const std::string & dumper_name, const Mesh & mesh,
-      const ElementTypeMapArray<UInt> & elements_filter,
-      const Array<UInt> & nodes_filter,
-      UInt spatial_dimension = _all_dimensions,
-      GhostType ghost_type = _not_ghost,
-      ElementKind element_kind = _ek_not_defined);
+      const ElementTypeMapArray<Idx> & elements_filter,
+      const Array<Idx> & nodes_filter,
+      Int spatial_dimension = _all_dimensions,
+      const GhostType & ghost_type = _not_ghost,
+      const ElementKind & element_kind = _ek_not_defined);
 
   /// to implement
   virtual void addDumpField(const std::string & field_id);
   /// to implement
   virtual void addDumpFieldToDumper(const std::string & dumper_name,
                                     const std::string & field_id);
   /// add a field
   virtual void addDumpFieldExternal(const std::string & field_id,
                                     std::shared_ptr<dumpers::Field> field);
   virtual void
   addDumpFieldExternalToDumper(const std::string & dumper_name,
                                const std::string & field_id,
                                std::shared_ptr<dumpers::Field> field);
 
   template <typename T>
   inline void addDumpFieldExternal(const std::string & field_id,
                                    const Array<T> & field);
   template <typename T>
   inline void addDumpFieldExternalToDumper(const std::string & dumper_name,
                                            const std::string & field_id,
                                            const Array<T> & field);
   template <typename T>
   inline void
   addDumpFieldExternal(const std::string & field_id,
                        const ElementTypeMapArray<T> & field,
-                       UInt spatial_dimension = _all_dimensions,
-                       GhostType ghost_type = _not_ghost,
-                       ElementKind element_kind = _ek_not_defined);
+                       Int spatial_dimension = _all_dimensions,
+                       const GhostType & ghost_type = _not_ghost,
+                       const ElementKind & element_kind = _ek_not_defined);
   template <typename T>
   inline void addDumpFieldExternalToDumper(
       const std::string & dumper_name, const std::string & field_id,
       const ElementTypeMapArray<T> & field,
-      UInt spatial_dimension = _all_dimensions,
-      GhostType ghost_type = _not_ghost,
-      ElementKind element_kind = _ek_not_defined);
+      Int spatial_dimension = _all_dimensions,
+      const GhostType & ghost_type = _not_ghost,
+      const ElementKind & element_kind = _ek_not_defined);
 
   void removeDumpField(const std::string & field_id);
   void removeDumpFieldFromDumper(const std::string & dumper_name,
                                  const std::string & field_id);
 
   virtual void addDumpFieldVector(const std::string & field_id);
   virtual void addDumpFieldVectorToDumper(const std::string & dumper_name,
                                           const std::string & field_id);
 
   virtual void addDumpFieldTensor(const std::string & field_id);
   virtual void addDumpFieldTensorToDumper(const std::string & dumper_name,
                                           const std::string & field_id);
 
   void setDirectory(const std::string & directory);
   void setDirectoryToDumper(const std::string & dumper_name,
                             const std::string & directory);
 
   void setBaseName(const std::string & basename);
 
   void setBaseNameToDumper(const std::string & dumper_name,
                            const std::string & basename);
   void setTimeStepToDumper(Real time_step);
   void setTimeStepToDumper(const std::string & dumper_name, Real time_step);
 
   void setTextModeToDumper(const std::string & dumper_name);
   void setTextModeToDumper();
 
   virtual void dump();
-  virtual void dump(UInt step);
-  virtual void dump(Real time, UInt step);
+  virtual void dump(Int step);
+  virtual void dump(Real time, Int step);
   virtual void dump(const std::string & dumper_name);
-  virtual void dump(const std::string & dumper_name, UInt step);
-  virtual void dump(const std::string & dumper_name, Real time, UInt step);
+  virtual void dump(const std::string & dumper_name, Int step);
+  virtual void dump(const std::string & dumper_name, Real time, Int step);
 
 public:
   void internalAddDumpFieldToDumper(const std::string & dumper_name,
                                     const std::string & field_id,
                                     std::shared_ptr<dumpers::Field> field);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   DumperIOHelper & getDumper();
   DumperIOHelper & getDumper(const std::string & dumper_name);
 
   template <class T> T & getDumper(const std::string & dumper_name);
   std::string getDefaultDumperName() const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   using DumperMap = std::map<std::string, std::shared_ptr<DumperIOHelper>>;
   using DumperSet = std::set<std::string>;
 
   DumperMap dumpers;
   std::string default_dumper;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_DUMPABLE_IOHELPER_HH_ */
diff --git a/src/io/dumper/dumper_elemental_field.hh b/src/io/dumper/dumper_elemental_field.hh
index 29c201308..8a4434e7b 100644
--- a/src/io/dumper/dumper_elemental_field.hh
+++ b/src/io/dumper/dumper_elemental_field.hh
@@ -1,77 +1,77 @@
 /**
  * @file   dumper_elemental_field.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  description of elemental fields
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_ELEMENTAL_FIELD_HH_
 #define AKANTU_DUMPER_ELEMENTAL_FIELD_HH_
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 #include "dumper_field.hh"
 #include "dumper_generic_elemental_field.hh"
 #ifdef AKANTU_IGFEM
 #include "dumper_igfem_elemental_field.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 namespace dumpers {
 /* -------------------------------------------------------------------------- */
 
-template <typename T, template <class> class ret = Vector,
+template <typename T, class ret = Vector<T>,
           bool filtered = false>
 class ElementalField
     : public GenericElementalField<SingleType<T, ret, filtered>,
                                    elemental_field_iterator> {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using types = SingleType<T, ret, filtered>;
   using field_type = typename types::field_type;
   using iterator = elemental_field_iterator<types>;
   using support_type = Element;
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ElementalField(const field_type & field,
-                 UInt spatial_dimension = _all_dimensions,
+                 Int spatial_dimension = _all_dimensions,
                  GhostType ghost_type = _not_ghost,
                  ElementKind element_kind = _ek_not_defined)
       : GenericElementalField<types, elemental_field_iterator>(
             field, spatial_dimension, ghost_type, element_kind) {}
 };
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace dumpers
 } // namespace akantu
 
 #endif /* AKANTU_DUMPER_ELEMENTAL_FIELD_HH_ */
diff --git a/src/io/dumper/dumper_generic_elemental_field.hh b/src/io/dumper/dumper_generic_elemental_field.hh
index 0b9c0dd89..53dfadeb7 100644
--- a/src/io/dumper/dumper_generic_elemental_field.hh
+++ b/src/io/dumper/dumper_generic_elemental_field.hh
@@ -1,231 +1,231 @@
 /**
  * @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: Fri Jul 24 2020
  *
  * @brief  Generic interface for elemental fields
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #ifndef AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH_
 #define AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH_
 /* -------------------------------------------------------------------------- */
 #include "dumper_element_iterator.hh"
 #include "dumper_field.hh"
 #include "dumper_homogenizing_field.hh"
 #include "element_type_map_filter.hh"
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 namespace dumpers {
 /* -------------------------------------------------------------------------- */
 
 template <class _types, template <class> class iterator_type>
 class GenericElementalField : public Field {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   // check dumper_type_traits.hh for additional information over these types
   using types = _types;
   using data_type = typename types::data_type;
   using it_type = typename types::it_type;
   using field_type = typename types::field_type;
   using array_type = typename types::array_type;
   using array_iterator = typename types::array_iterator;
   using field_type_iterator = typename field_type::type_iterator;
   using iterator = iterator_type<types>;
   using support_type = Element;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   GenericElementalField(const field_type & field,
-                        UInt spatial_dimension = _all_dimensions,
+                        Int spatial_dimension = _all_dimensions,
                         GhostType ghost_type = _not_ghost,
                         ElementKind element_kind = _ek_not_defined)
       : field(field), spatial_dimension(spatial_dimension),
         ghost_type(ghost_type), element_kind(element_kind) {
     this->checkHomogeneity();
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the number of components of the hosted field
-  ElementTypeMap<UInt>
-  getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
+  ElementTypeMap<Int>
+  getNbComponents(Int dim = _all_dimensions, GhostType ghost_type = _not_ghost,
                   ElementKind kind = _ek_not_defined) override {
     return this->field.getNbComponents(dim, ghost_type, kind);
   };
 
   /// return the size of the contained data: i.e. the number of elements ?
-  virtual UInt size() {
+  virtual Int size() {
     checkHomogeneity();
     return this->nb_total_element;
   }
 
   /// return the iohelper datatype to be dumped
     template <class T1 = data_type,
               std::enable_if_t<std::is_enum<T1>::value> * = nullptr>
     iohelper::DataType getDataType() {
       return iohelper::getDataType<UInt>();
     }
 
     template <class T1 = data_type,
               std::enable_if_t<not std::is_enum<T1>::value> * = nullptr>
     iohelper::DataType getDataType() {
       return iohelper::getDataType<data_type>();
     }
 
 protected:
   /// return the number of entries per element
-  UInt getNbDataPerElem(ElementType type,
-                        GhostType ghost_type = _not_ghost) const {
-    if (!nb_data_per_elem.exists(type, ghost_type)) {
+  Int getNbDataPerElem(const ElementType & type,
+                        const GhostType & ghost_type = _not_ghost) const {
+    if (!nb_data_per_elem.exists(type, ghost_type))
       return field(type, ghost_type).getNbComponent();
     }
 
     return nb_data_per_elem(type, this->ghost_type);
   }
 
   /// check if the same quantity of data for all element types
   void checkHomogeneity() override;
 
 public:
   void registerToDumper(const std::string & id,
                         iohelper::Dumper & dumper) override {
     dumper.addElemDataField(id, *this);
   }
 
   /// for connection to a FieldCompute
   inline std::shared_ptr<Field> connect(FieldComputeProxy & proxy) override {
     return proxy.connectToField(this);
   }
 
   /// for connection to a Homogenizer
   inline std::unique_ptr<ComputeFunctorInterface>
   connect(HomogenizerProxy & proxy) override {
     return proxy.connectToField(this);
   }
 
   virtual iterator begin() {
     /// type iterators on the elemental field
     auto types = this->field.elementTypes(this->spatial_dimension,
                                           this->ghost_type, this->element_kind);
     auto tit = types.begin();
     auto end = types.end();
 
     /// skip all types without data
     for (; tit != end and this->field(*tit, this->ghost_type).empty();
          ++tit) {
     }
 
     auto type = *tit;
 
     if (tit == end) {
       return this->end();
     }
 
     /// getting information for the field of the given type
     const auto & vect = this->field(type, this->ghost_type);
-    UInt nb_data_per_elem = this->getNbDataPerElem(type);
+    auto nb_data_per_elem = this->getNbDataPerElem(type);
 
     /// define element-wise iterator
     auto view = make_view(vect, nb_data_per_elem);
     auto it = view.begin();
     auto it_end = view.end();
     /// define data iterator
     iterator rit =
         iterator(this->field, tit, end, it, it_end, this->ghost_type);
     rit.setNbDataPerElem(this->nb_data_per_elem);
     return rit;
   }
 
   virtual iterator end() {
     auto types = this->field.elementTypes(this->spatial_dimension,
                                           this->ghost_type, this->element_kind);
     auto tit = types.begin();
     auto end = types.end();
 
     auto type = *tit;
     for (; tit != end; ++tit) {
       type = *tit;
     }
 
     const array_type & vect = this->field(type, this->ghost_type);
-    UInt nb_data = this->getNbDataPerElem(type);
+    auto nb_data = this->getNbDataPerElem(type);
     auto it = make_view(vect, nb_data).end();
     auto rit = iterator(this->field, end, end, it, it, this->ghost_type);
     rit.setNbDataPerElem(this->nb_data_per_elem);
 
     return rit;
   }
 
-  virtual UInt getDim() {
+  virtual Int getDim() {
     if (this->homogeneous) {
       auto tit = this->field
                      .elementTypes(this->spatial_dimension, this->ghost_type,
                                    this->element_kind)
                      .begin();
       return this->getNbDataPerElem(*tit);
     }
 
     throw;
     return 0;
   }
 
   void setNbDataPerElem(const ElementTypeMap<UInt> & nb_data) override {
     nb_data_per_elem = nb_data;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the ElementTypeMapArray embedded in the field
   const field_type & field;
   /// total number of elements
   UInt nb_total_element;
   /// the spatial dimension of the problem
   UInt spatial_dimension;
   /// whether this is a ghost field or not (for type selection)
   GhostType ghost_type;
   /// The element kind to operate on
   ElementKind element_kind;
   /// The number of data per element type
   ElementTypeMap<UInt> nb_data_per_elem;
 };
 
 } // namespace dumpers
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #include "dumper_generic_elemental_field_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 
 #endif /* AKANTU_DUMPER_GENERIC_ELEMENTAL_FIELD_HH_ */
diff --git a/src/io/dumper/dumper_iohelper.hh b/src/io/dumper/dumper_iohelper.hh
index 038deacc5..558f161d4 100644
--- a/src/io/dumper/dumper_iohelper.hh
+++ b/src/io/dumper/dumper_iohelper.hh
@@ -1,162 +1,162 @@
 /**
  * @file   dumper_iohelper.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Oct 26 2012
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Define the akantu dumper interface for IOhelper dumpers
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_types.hh"
 #include "element_type_map.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_DUMPER_IOHELPER_HH_
 #define AKANTU_DUMPER_IOHELPER_HH_
 /* -------------------------------------------------------------------------- */
 
 namespace iohelper {
 class Dumper;
 }
 
 namespace akantu {
 
 UInt getIOHelperType(ElementType type);
 
 namespace dumpers {
   class Field;
   class VariableBase;
 } // namespace dumper
 
 class Mesh;
 
 class DumperIOHelper : public std::enable_shared_from_this<DumperIOHelper> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DumperIOHelper();
   virtual ~DumperIOHelper();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// register a given Mesh for the current dumper
   virtual void registerMesh(const Mesh & mesh,
-                            UInt spatial_dimension = _all_dimensions,
-                            GhostType ghost_type = _not_ghost,
-                            ElementKind element_kind = _ek_not_defined);
+                            Int spatial_dimension = _all_dimensions,
+                            const GhostType & ghost_type = _not_ghost,
+                            const ElementKind & element_kind = _ek_not_defined);
 
   /// register a filtered Mesh (provided filter lists) for the current dumper
   virtual void
   registerFilteredMesh(const Mesh & mesh,
-                       const ElementTypeMapArray<UInt> & elements_filter,
-                       const Array<UInt> & nodes_filter,
-                       UInt spatial_dimension = _all_dimensions,
-                       GhostType ghost_type = _not_ghost,
-                       ElementKind element_kind = _ek_not_defined);
+                       const ElementTypeMapArray<Idx> & elements_filter,
+                       const Array<Idx> & nodes_filter,
+                       Int spatial_dimension = _all_dimensions,
+                       const GhostType & ghost_type = _not_ghost,
+                       const ElementKind & element_kind = _ek_not_defined);
 
   /// register a Field object identified by name and provided by pointer
   void registerField(const std::string & field_id,
                      std::shared_ptr<dumpers::Field> field);
   /// remove the Field identified by name from managed fields
   void unRegisterField(const std::string & field_id);
   /// register a VariableBase object identified by name and provided by pointer
   void registerVariable(const std::string & variable_id,
                         std::shared_ptr<dumpers::VariableBase> variable);
   /// remove a VariableBase identified by name from managed fields
   void unRegisterVariable(const std::string & variable_id);
 
   /// request dump: this calls IOHelper dump routine
   virtual void dump();
   /// request dump: this first set the current step and then calls IOHelper dump
   /// routine
-  virtual void dump(UInt step);
+  virtual void dump(Int step);
   /// request dump: this first set the current step and current time and then
   /// calls IOHelper dump routine
-  virtual void dump(Real current_time, UInt step);
+  virtual void dump(Real current_time, Int step);
   /// set the parallel context for IOHeper
   virtual void setParallelContext(bool is_parallel);
   /// set the directory where to generate the dumped files
   virtual void setDirectory(const std::string & directory);
   /// set the base name (needed by most IOHelper dumpers)
   virtual void setBaseName(const std::string & basename);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// direct access to the iohelper::Dumper object
   AKANTU_GET_MACRO(Dumper, *dumper, iohelper::Dumper &)
 
   /// set the timestep of the iohelper::Dumper
   void setTimeStep(Real time_step);
 
 public:
   /* ------------------------------------------------------------------------ */
   /* Variable wrapper */
   template <typename T, bool is_scal = std::is_arithmetic<T>::value>
   class Variable;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// internal iohelper::Dumper
   std::unique_ptr<iohelper::Dumper> dumper;
 
   using Fields = std::map<std::string, std::shared_ptr<dumpers::Field>>;
   using Variables =
       std::map<std::string, std::shared_ptr<dumpers::VariableBase>>;
 
   /// list of registered fields to dump
   Fields fields;
   Variables variables;
 
   /// dump counter
-  UInt count{0};
+  Int count{0};
 
   /// directory name
   std::string directory;
 
   /// filename prefix
   std::string filename;
 
   /// is time tracking activated in the dumper
   bool time_activated{false};
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_DUMPER_IOHELPER_HH_ */
diff --git a/src/mesh/element_group.hh b/src/mesh/element_group.hh
index db4f69e57..22c9532ec 100644
--- a/src/mesh/element_group.hh
+++ b/src/mesh/element_group.hh
@@ -1,205 +1,208 @@
 /**
  * @file   element_group.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri May 03 2013
  * @date last modification: Mon Mar 08 2021
  *
  * @brief  Stores information relevent to the notion of domain boundary and
  * surfaces.
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "dumpable.hh"
 #include "element_type_map.hh"
 #include "node_group.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_ELEMENT_GROUP_HH_
 #define AKANTU_ELEMENT_GROUP_HH_
 
 namespace akantu {
 class Mesh;
 class Element;
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class ElementGroup : public Dumpable {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ElementGroup(const std::string & name, const Mesh & mesh,
-               NodeGroup & node_group, UInt dimension = _all_dimensions,
+               NodeGroup & node_group, Int dimension = _all_dimensions,
                const std::string & id = "element_group");
 
   ElementGroup(const ElementGroup & /*unused*/);
 
   /* ------------------------------------------------------------------------ */
   /* Type definitions                                                         */
   /* ------------------------------------------------------------------------ */
 public:
-  using ElementList = ElementTypeMapArray<UInt>;
-  using NodeList = Array<UInt>;
+  using ElementList = ElementTypeMapArray<Idx>;
+  using NodeList = Array<Idx>;
 
   /* ------------------------------------------------------------------------ */
   /* Element iterator                                                         */
   /* ------------------------------------------------------------------------ */
-
   using type_iterator = ElementList::type_iterator;
-  [[deprecated("Use elementTypes instead")]] inline type_iterator
-  firstType(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
-            ElementKind kind = _ek_regular) const;
 
-  [[deprecated("Use elementTypes instead")]] inline type_iterator
-  lastType(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
-           ElementKind kind = _ek_regular) const;
+  [[deprecated("Use elementTypes instead")]] inline auto
+  firstType(Int dim = _all_dimensions,
+            const GhostType & ghost_type = _not_ghost,
+            const ElementKind & kind = _ek_regular) const;
+
+  [[deprecated("Use elementTypes instead")]] inline auto
+  lastType(Int dim = _all_dimensions,
+           const GhostType & ghost_type = _not_ghost,
+           const ElementKind & kind = _ek_regular) const;
 
   template <typename... pack>
   inline decltype(auto) elementTypes(pack &&... _pack) const {
     return elements.elementTypes(_pack...);
   }
 
   using const_element_iterator = Array<UInt>::const_scalar_iterator;
 
   inline const_element_iterator begin(ElementType type,
                                       GhostType ghost_type = _not_ghost) const;
   inline const_element_iterator end(ElementType type,
                                     GhostType ghost_type = _not_ghost) const;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// empty the element group
   void clear();
   void clear(ElementType type, GhostType ghost_type = _not_ghost);
 
   bool empty() const __attribute__((warn_unused_result));
 
   /// append another group to this group
   /// BE CAREFUL: it doesn't conserve the element order
   void append(const ElementGroup & other_group);
 
   /// add an element to the group. By default the it does not add the nodes to
   /// the group
   inline void add(const Element & el, bool add_nodes = false,
                   bool check_for_duplicate = true);
 
   /// \todo fix the default for add_nodes : make it coherent with the other
   /// method
-  inline void add(ElementType type, UInt element,
-                  GhostType ghost_type = _not_ghost, bool add_nodes = true,
-                  bool check_for_duplicate = true);
+  inline void add(const ElementType & type, Idx element,
+                  const GhostType & ghost_type = _not_ghost,
+                  bool add_nodes = true, bool check_for_duplicate = true);
 
-  inline void addNode(UInt node_id, bool check_for_duplicate = true);
+  inline void addNode(Idx node_id, bool check_for_duplicate = true);
 
-  inline void removeNode(UInt node_id);
+  inline void removeNode(Idx node_id);
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// fill the elements based on the underlying node group.
   virtual void fillFromNodeGroup();
 
   // sort and remove duplicated values
   void optimize();
 
   /// change the dimension if needed
-  void addDimension(UInt dimension);
+  void addDimension(Int dimension);
 
 private:
-  inline void addElement(ElementType elem_type, UInt elem_id,
-                         GhostType ghost_type);
+  inline void addElement(const ElementType & elem_type, Idx elem_id,
+                         const GhostType & ghost_type);
 
   friend class GroupManager;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
-  const Array<UInt> & getElements(ElementType type,
-                                  GhostType ghost_type = _not_ghost) const;
-  AKANTU_GET_MACRO(Elements, elements, const ElementTypeMapArray<UInt> &);
-  AKANTU_GET_MACRO_NOT_CONST(Elements, elements, ElementTypeMapArray<UInt> &);
+  const Array<Idx> &
+  getElements(const ElementType & type,
+              const GhostType & ghost_type = _not_ghost) const;
+  AKANTU_GET_MACRO(Elements, elements, const ElementTypeMapArray<Idx> &);
+  AKANTU_GET_MACRO_NOT_CONST(Elements, elements, ElementTypeMapArray<Idx> &);
 
   template <class... Args> auto size(Args &&... pack) const {
     return elements.size(std::forward<Args>(pack)...);
   }
 
   decltype(auto) getElementsIterable(ElementType type,
                                      GhostType ghost_type = _not_ghost) const;
 
   //  AKANTU_GET_MACRO(Nodes, node_group.getNodes(), const Array<UInt> &);
 
   AKANTU_GET_MACRO(NodeGroup, node_group, const NodeGroup &);
   AKANTU_GET_MACRO_NOT_CONST(NodeGroup, node_group, NodeGroup &);
 
   AKANTU_GET_MACRO(Dimension, dimension, UInt);
   AKANTU_GET_MACRO(Name, name, std::string);
-  inline UInt getNbNodes() const;
+  inline Int getNbNodes() const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// Mesh to which this group belongs
   const Mesh & mesh;
 
   /// name of the group
   std::string name;
 
   /// list of elements composing the group
   ElementList elements;
 
   /// sub list of nodes which are composing the elements
   NodeGroup & node_group;
 
   /// group dimension
-  UInt dimension{_all_dimensions};
+    Int dimension{_all_dimensions};
 
   /// empty arry for the iterator to work when an element type not present
-  Array<UInt> empty_elements;
+  Array<Idx> empty_elements;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const ElementGroup & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "element.hh"
 #include "element_group_inline_impl.hh"
 
 #endif /* AKANTU_ELEMENT_GROUP_HH_ */
diff --git a/src/mesh/element_group_inline_impl.hh b/src/mesh/element_group_inline_impl.hh
index 8f0a2bccf..c02e5a41e 100644
--- a/src/mesh/element_group_inline_impl.hh
+++ b/src/mesh/element_group_inline_impl.hh
@@ -1,148 +1,149 @@
 /**
  * @file   element_group_inline_impl.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
  * @date last modification: Tue Mar 09 2021
  *
  * @brief  Stores information relevent to the notion of domain boundary and
  * surfaces.
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_group.hh"
 #include "mesh.hh"
 #include "aka_iterators.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_ELEMENT_GROUP_INLINE_IMPL_HH_
 #define AKANTU_ELEMENT_GROUP_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline void ElementGroup::add(const Element & el, bool add_nodes,
                               bool check_for_duplicate) {
   this->add(el.type, el.element, el.ghost_type, add_nodes, check_for_duplicate);
 }
 
 /* -------------------------------------------------------------------------- */
-
-inline void ElementGroup::add(ElementType type, UInt element,
-                              GhostType ghost_type, bool add_nodes,
+inline void ElementGroup::add(const ElementType & type, Idx element,
+                              const GhostType & ghost_type, bool add_nodes,
                               bool check_for_duplicate) {
-
   addElement(type, element, ghost_type);
 
   if (add_nodes) {
     auto it =
         mesh.getConnectivity(type, ghost_type)
             .begin(mesh.getNbNodesPerElement(type)) +
         element;
     const auto & conn = *it;
     for (Idx i = 0; i < conn.size(); ++i)
       addNode(conn[i], check_for_duplicate);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-inline void ElementGroup::addNode(UInt node_id, bool check_for_duplicate) {
+inline void ElementGroup::addNode(Idx node_id, bool check_for_duplicate) {
   node_group.add(node_id, check_for_duplicate);
 }
 
 /* -------------------------------------------------------------------------- */
-inline void ElementGroup::removeNode(UInt node_id) {
+inline void ElementGroup::removeNode(Idx node_id) {
   node_group.remove(node_id);
 }
 
 /* -------------------------------------------------------------------------- */
-inline void ElementGroup::addElement(ElementType elem_type, UInt elem_id,
-                                     GhostType ghost_type) {
+inline void ElementGroup::addElement(const ElementType & elem_type,
+                                     Idx elem_id,
+                                     const GhostType & ghost_type) {
   if (!(elements.exists(elem_type, ghost_type))) {
     elements.alloc(0, 1, elem_type, ghost_type);
   }
 
   elements(elem_type, ghost_type).push_back(elem_id);
-  this->dimension = UInt(
+  this->dimension = Int(
       std::max(Int(this->dimension), Int(mesh.getSpatialDimension(elem_type))));
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt ElementGroup::getNbNodes() const { return node_group.size(); }
+inline Int ElementGroup::getNbNodes() const { return node_group.size(); }
 
 /* -------------------------------------------------------------------------- */
-inline ElementGroup::type_iterator
-ElementGroup::firstType(UInt dim, GhostType ghost_type,
-                        ElementKind kind) const {
+inline auto
+ElementGroup::firstType(Int dim, const GhostType & ghost_type,
+                        const ElementKind & kind) const {
   return elements.elementTypes(dim, ghost_type, kind).begin();
 }
 
 /* -------------------------------------------------------------------------- */
-inline ElementGroup::type_iterator
-ElementGroup::lastType(UInt dim, GhostType ghost_type, ElementKind kind) const {
+inline auto
+ElementGroup::lastType(Int dim, const GhostType & ghost_type,
+                       const ElementKind & kind) const {
   return elements.elementTypes(dim, ghost_type, kind).end();
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementGroup::const_element_iterator
 ElementGroup::begin(ElementType type, GhostType ghost_type) const {
   if (elements.exists(type, ghost_type)) {
     return elements(type, ghost_type).begin();
   }
   return empty_elements.begin();
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementGroup::const_element_iterator
 ElementGroup::end(ElementType type, GhostType ghost_type) const {
   if (elements.exists(type, ghost_type)) {
     return elements(type, ghost_type).end();
   }
   return empty_elements.end();
 }
 
 /* -------------------------------------------------------------------------- */
-inline const Array<UInt> &
-ElementGroup::getElements(ElementType type, GhostType ghost_type) const {
+inline const Array<Idx> &
+ElementGroup::getElements(const ElementType & type,
+                          const GhostType & ghost_type) const {
   if (elements.exists(type, ghost_type)) {
     return elements(type, ghost_type);
   }
   return empty_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto)
 ElementGroup::getElementsIterable(ElementType type,
                                   GhostType ghost_type) const {
   return make_transform_adaptor(this->elements(type, ghost_type),
                                 [type, ghost_type](auto && el) {
                                   return Element{type, el, ghost_type};
                                 });
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_ELEMENT_GROUP_INLINE_IMPL_HH_ */
diff --git a/src/mesh/element_type_map.hh b/src/mesh/element_type_map.hh
index 8df2e43bb..9344d3850 100644
--- a/src/mesh/element_type_map.hh
+++ b/src/mesh/element_type_map.hh
@@ -1,492 +1,492 @@
 /**
  * @file   element_type_map.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 31 2011
  * @date last modification: Thu Mar 11 2021
  *
  * @brief  storage class by element type
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_named_argument.hh"
 #include "element.hh"
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_ELEMENT_TYPE_MAP_HH_
 #define AKANTU_ELEMENT_TYPE_MAP_HH_
 
 namespace akantu {
 class FEEngine;
 } // namespace akantu
 
 namespace akantu {
 
 namespace {
   DECLARE_NAMED_ARGUMENT(all_ghost_types);
   DECLARE_NAMED_ARGUMENT(default_value);
   DECLARE_NAMED_ARGUMENT(element_kind);
   DECLARE_NAMED_ARGUMENT(ghost_type);
   DECLARE_NAMED_ARGUMENT(nb_component);
   DECLARE_NAMED_ARGUMENT(nb_component_functor);
   DECLARE_NAMED_ARGUMENT(with_nb_element);
   DECLARE_NAMED_ARGUMENT(with_nb_nodes_per_element);
   DECLARE_NAMED_ARGUMENT(spatial_dimension);
   DECLARE_NAMED_ARGUMENT(do_not_default);
   DECLARE_NAMED_ARGUMENT(element_filter);
 } // namespace
 
 template <class Stored, typename SupportType = ElementType>
 class ElementTypeMap;
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMapBase */
 /* -------------------------------------------------------------------------- */
 /// Common non templated base class for the ElementTypeMap class
 class ElementTypeMapBase {
 public:
   virtual ~ElementTypeMapBase() = default;
 };
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMap */
 /* -------------------------------------------------------------------------- */
 
 template <class Stored, typename SupportType>
 class ElementTypeMap : public ElementTypeMapBase {
 
 public:
   ElementTypeMap();
   ~ElementTypeMap() override;
 
   inline static std::string printType(const SupportType & type,
                                       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,
                      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,
                                    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,
                              GhostType ghost_type = _not_ghost);
 
   /*! insert data of a new type (not yet present) into the map. THIS METHOD IS
    *  NOT ARRAY SAFE, when using ElementTypeMapArray, use setArray instead
    *  @param data to insert
    *  @param type type of data (if this type is already present in the map,
    *         an exception is thrown).
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @return stored data corresponding to type. */
   template <typename U>
   inline Stored & operator()(U && insertee, const SupportType & type,
                              GhostType ghost_type = _not_ghost);
 
 public:
   /// print helper
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Element type Iterator                                                    */
   /* ------------------------------------------------------------------------ */
   /*! iterator allows to iterate over type-data pairs of the map. The interface
    *  expects the SupportType to be ElementType. */
   using DataMap = std::map<SupportType, Stored>;
 
   /// helper class to use in range for constructions
   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);
+                  Int dim, ElementKind ek);
 
     type_iterator(const type_iterator & it);
     type_iterator() = default;
 
     inline reference operator*();
     inline reference operator*() const;
     inline type_iterator & operator++();
     type_iterator operator++(int);
     inline bool operator==(const type_iterator & other) const;
     inline bool operator!=(const type_iterator & other) const;
     type_iterator & operator=(const type_iterator & it);
 
   private:
     DataMapIterator list_begin;
     DataMapIterator list_end;
-    UInt dim;
+    Int 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,
+    ElementTypesIteratorHelper(const Container & container, Int 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 /*unused*/, pack &&... _pack)
         : ElementTypesIteratorHelper(
               container, OPTIONAL_NAMED_ARG(spatial_dimension, _all_dimensions),
               OPTIONAL_NAMED_ARG(ghost_type, _not_ghost),
               OPTIONAL_NAMED_ARG(element_kind, _ek_not_defined)) {}
 
     ElementTypesIteratorHelper(const ElementTypesIteratorHelper &) = default;
     ElementTypesIteratorHelper &
     operator=(const ElementTypesIteratorHelper &) = default;
     ElementTypesIteratorHelper &
     operator=(ElementTypesIteratorHelper &&) noexcept = default;
 
     iterator begin();
     iterator end();
 
   private:
     std::reference_wrapper<const Container> container;
-    UInt dim;
+    Int dim;
     GhostType ghost_type;
     ElementKind kind;
   };
 
 private:
   ElementTypesIteratorHelper
-  elementTypesImpl(UInt dim = _all_dimensions,
+  elementTypesImpl(Int dim = _all_dimensions,
                    GhostType ghost_type = _not_ghost,
                    ElementKind kind = _ek_not_defined) const;
 
   template <typename... pack>
   ElementTypesIteratorHelper
   elementTypesImpl(const use_named_args_t & /*unused*/, pack &&... _pack) const;
 
 public:
   /*!
    * \param _pack
    * \parblock
    *  represent optional parameters:
    * \li \c _spatial_dimension filter for elements of given spatial
    * dimension
    * \li \c _ghost_type filter for a certain ghost_type
    * \li \c _element_kind filter for elements of given kind
    * \endparblock
    */
   template <typename... pack>
   std::enable_if_t<are_named_argument<pack...>::value,
                    ElementTypesIteratorHelper>
   elementTypes(pack &&... _pack) const {
     return elementTypesImpl(use_named_args,
                             std::forward<decltype(_pack)>(_pack)...);
   }
 
   template <typename... pack>
   std::enable_if_t<not are_named_argument<pack...>::value,
                    ElementTypesIteratorHelper>
   elementTypes(pack &&... _pack) const {
     return elementTypesImpl(std::forward<decltype(_pack)>(_pack)...);
   }
 
   /*! 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*/
   [[deprecated("Use elementTypes instead")]] inline type_iterator
-  firstType(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
+  firstType(Int 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 */
   [[deprecated("Use elementTypes instead")]] inline type_iterator
-  lastType(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
+  lastType(Int dim = _all_dimensions, GhostType ghost_type = _not_ghost,
            ElementKind kind = _ek_not_defined) const;
 
   /*! 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<std::unique_ptr<Array<T>>, SupportType> {
 public:
   using value_type = T;
   using array_type = Array<T>;
 
 protected:
   using parent = ElementTypeMap<std::unique_ptr<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 & /*other*/);
 
   /// explicit copy
   void copy(const ElementTypeMapArray & other);
 
   /*! Constructor
    *  @param id optional: identifier (string)
    *  @param parent_id optional: parent identifier. for organizational purposes
    *         only
    */
   ElementTypeMapArray(const ID & id = "by_element_type_array",
                       const ID & parent_id = "no_parent")
       : parent(), id(parent_id + ":" + 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
    *  @param default_value the default value to use to fill the array
    *  @return a reference to the allocated array */
-  inline Array<T> & alloc(UInt size, UInt nb_component,
-                          const SupportType & type, GhostType ghost_type,
+  inline Array<T> & alloc(Int size, Int 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
-   *  @param default_value the default value to use to fill the array
-   */
-  inline void alloc(UInt size, UInt nb_component, const SupportType & type,
+   *  @param type the type under which the array is indexed in the map*/
+  inline void alloc(Int size, Int 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,
                                      GhostType ghost_type = _not_ghost) const;
 
   /// access the data of an element, this combine the map and array accessor
   inline const T & operator()(const Element & element,
-                              UInt component = 0) const;
+                              Int component = 0) const;
 
   /// access the data of an element, this combine the map and array accessor
-  inline T & operator()(const Element & element, UInt component = 0);
+  inline T & operator()(const Element & element, Int component = 0);
 
   /// access the data of an element, this combine the map and array accessor
   inline decltype(auto) get(const Element & element);
   inline decltype(auto) get(const Element & element) const;
 
   /* 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,
                                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, GhostType ghost_type,
                        const Array<T> & vect);
   /*! frees all memory related to the data*/
   inline void free();
 
   inline void clear();
 
   inline bool empty() const __attribute__((warn_unused_result));
 
   /*! set all values in the ElementTypeMap to zero*/
   inline void zero() { this->set(T()); }
 
   /*! set all values in the ElementTypeMap to value */
   template <typename ST> inline void set(const ST & value);
 
   /*! deletes and reorders entries in the stored arrays
    *  @param new_numbering a ElementTypeMapArray of new indices. UInt(-1)
    * indicates
    *         deleted entries. */
   inline void
-  onElementsRemoved(const ElementTypeMapArray<UInt> & new_numbering);
+  onElementsRemoved(const ElementTypeMapArray<Int> & new_numbering);
 
   /// text output helper
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /*! set the id
    *  @param id the new name
    */
   inline void setID(const ID & id) { this->id = id; }
 
   /// return the id
   inline auto getID() const -> ID { return this->id; }
 
-  ElementTypeMap<UInt>
-  getNbComponents(UInt dim = _all_dimensions,
-                  GhostType requested_ghost_type = _not_ghost,
+  ElementTypeMap<Int>
+  getNbComponents(Int dim = _all_dimensions, GhostType ghost_type = _not_ghost,
                   ElementKind kind = _ek_not_defined) const {
     ElementTypeMap<UInt> nb_components;
-    bool all_ghost_types = requested_ghost_type == _casper;
+    auto all_ghost_types = requested_ghost_type == _casper;
     for (auto ghost_type : ghost_types) {
       if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types)) {
         continue;
       }
 
       for (auto & type : this->elementTypes(dim, ghost_type, kind)) {
-        UInt nb_comp = (*this)(type, ghost_type).getNbComponent();
+        auto 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);
 
   /**
    * get the size of the ElementTypeMapArray<T>
    * @param[in] _pack
    * \parblock
    * optional arguments can be any of:
    * \li \c _spatial_dimension the dimension to consider (default:
    * _all_dimensions)
    * \li \c _ghost_type  (default: _not_ghost)
    * \li \c _element_kind (default: _ek_not_defined)
    * \li \c _all_ghost_types (default: false)
    * \endparblock
    **/
-  template <typename... pack> UInt size(pack &&... _pack) const;
+  template <typename... pack> Int size(pack &&... _pack) const;
 
   bool isNodal() const { return is_nodal; }
   void isNodal(bool is_nodal) { this->is_nodal = is_nodal; }
 
 private:
-  UInt sizeImpl(UInt spatial_dimension, GhostType ghost_type,
-                ElementKind kind) const;
+  Int sizeImpl(Int spatial_dimension, const GhostType & ghost_type,
+                const ElementKind & kind) const;
 
 private:
   ID id;
 
 protected:
   /// name of the element type map: e.g. connectivity, grad_u
   ID name;
 
   /// Is the data stored by node of the element
   bool is_nodal{false};
 };
 
 /// 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>;
+/// to store data Array<Idx> by element type
+using ElementTypeMapIdx = ElementTypeMapArray<Idx>;
 
 } // namespace akantu
 
 #endif /* AKANTU_ELEMENT_TYPE_MAP_HH_ */
diff --git a/src/mesh/element_type_map_filter.hh b/src/mesh/element_type_map_filter.hh
index 8713d0300..e46fc4084 100644
--- a/src/mesh/element_type_map_filter.hh
+++ b/src/mesh/element_type_map_filter.hh
@@ -1,130 +1,130 @@
 /**
  * @file   element_type_map_filter.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Filtered version based on a an akantu::ElementGroup of a
  * akantu::ElementTypeMap
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_filter.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_BY_ELEMENT_TYPE_FILTER_HH_
 #define AKANTU_BY_ELEMENT_TYPE_FILTER_HH_
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMapFilter */
 /* -------------------------------------------------------------------------- */
 
 template <class T, typename SupportType = ElementType>
 class ElementTypeMapArrayFilter {
 
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 
 public:
   using array_type = ArrayFilter<T>;
   using value_type = typename array_type::value_type;
 
   using type_iterator =
       typename ElementTypeMapArray<UInt, SupportType>::type_iterator;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ElementTypeMapArrayFilter(
       const ElementTypeMapArray<T, SupportType> & array,
       const ElementTypeMapArray<UInt, SupportType> & filter,
       const ElementTypeMap<UInt, SupportType> & nb_data_per_elem)
       : array(array), filter(filter), nb_data_per_elem(nb_data_per_elem) {}
 
   ElementTypeMapArrayFilter(
       const ElementTypeMapArray<T, SupportType> & array,
       const ElementTypeMapArray<UInt, SupportType> & filter)
       : array(array), filter(filter) {}
 
   ~ElementTypeMapArrayFilter() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
   inline ArrayFilter<T> operator()(const SupportType & type,
                                    GhostType ghost_type = _not_ghost) const {
     if (filter.exists(type, ghost_type)) {
       if (nb_data_per_elem.exists(type, ghost_type)) {
         return ArrayFilter<T>(array(type, ghost_type), filter(type, ghost_type),
                               nb_data_per_elem(type, ghost_type) /
                                   array(type, ghost_type).getNbComponent());
       }
       return ArrayFilter<T>(array(type, ghost_type), filter(type, ghost_type),
                             1);
     }
     return ArrayFilter<T>(empty_array, empty_filter, 1);
   };
 
   template <typename... Args>
   decltype(auto) elementTypes(Args &&... args) const {
     return filter.elementTypes(std::forward<decltype(args)>(args)...);
   }
 
   decltype(auto) getNbComponents(UInt dim = _all_dimensions,
                                  GhostType ghost_type = _not_ghost,
                                  ElementKind kind = _ek_not_defined) const {
     return this->array.getNbComponents(dim, ghost_type, kind);
   };
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 
   std::string getID() {
     return std::string("filtered:" + this->array().getID());
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 
 protected:
   const ElementTypeMapArray<T, SupportType> & array;
   const ElementTypeMapArray<UInt, SupportType> & filter;
   ElementTypeMap<UInt> nb_data_per_elem;
 
   /// Empty array to be able to return consistent filtered arrays
   Array<T> empty_array;
-  Array<UInt> empty_filter;
+  Array<Int> empty_filter;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_BY_ELEMENT_TYPE_FILTER_HH_ */
diff --git a/src/mesh/element_type_map_tmpl.hh b/src/mesh/element_type_map_tmpl.hh
index 3050f4430..c53713876 100644
--- a/src/mesh/element_type_map_tmpl.hh
+++ b/src/mesh/element_type_map_tmpl.hh
@@ -1,852 +1,851 @@
 /**
  * @file   element_type_map_tmpl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 31 2011
  * @date last modification: Thu Mar 11 2021
  *
  * @brief  implementation of template functions of the ElementTypeMap and
  * ElementTypeMapArray classes
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_static_if.hh"
-#include "element_type_map.hh"
-#include "mesh.hh"
+//#include "element_type_map.hh"
+//#include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_type_conversion.hh"
 /* -------------------------------------------------------------------------- */
 #include <functional>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_ELEMENT_TYPE_MAP_TMPL_HH_
 #define AKANTU_ELEMENT_TYPE_MAP_TMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMap                                                             */
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline std::string
 ElementTypeMap<Stored, SupportType>::printType(const SupportType & type,
                                                GhostType ghost_type) {
   std::stringstream sstr;
   sstr << "(" << ghost_type << ":" << type << ")";
   return sstr.str();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline bool
 ElementTypeMap<Stored, SupportType>::exists(const SupportType & type,
                                             GhostType ghost_type) const {
   return this->getData(ghost_type).find(type) !=
          this->getData(ghost_type).end();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline const Stored &
 ElementTypeMap<Stored, SupportType>::operator()(const SupportType & type,
                                                 GhostType ghost_type) const {
   auto it = this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end()) {
     AKANTU_SILENT_EXCEPTION("No element of type "
                             << ElementTypeMap::printType(type, ghost_type)
                             << " in this ElementTypeMap<"
                             << debug::demangle(typeid(Stored).name())
                             << "> class");
   }
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline Stored &
 ElementTypeMap<Stored, SupportType>::operator()(const SupportType & type,
                                                 GhostType ghost_type) {
   return this->getData(ghost_type)[type];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 template <typename U>
 inline Stored & ElementTypeMap<Stored, SupportType>::operator()(
     U && insertee, const SupportType & type, GhostType ghost_type) {
   auto it = this->getData(ghost_type).find(type);
 
   if (it != this->getData(ghost_type).end()) {
     AKANTU_SILENT_EXCEPTION("Element of type "
                             << ElementTypeMap::printType(type, ghost_type)
                             << " already in this ElementTypeMap<"
                             << debug::demangle(typeid(Stored).name())
                             << "> class");
   } else {
     auto & data = this->getData(ghost_type);
     const auto & res =
         data.insert(std::make_pair(type, std::forward<U>(insertee)));
     it = res.first;
   }
 
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::DataMap &
 ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) {
   if (ghost_type == _not_ghost) {
     return data;
   }
 
   return ghost_data;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline const typename ElementTypeMap<Stored, SupportType>::DataMap &
 ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) const {
   if (ghost_type == _not_ghost) {
     return data;
   }
 
   return ghost_data;
 }
 
 /* -------------------------------------------------------------------------- */
 /// Works only if stored is a pointer to a class with a printself method
 template <class Stored, typename SupportType>
 void ElementTypeMap<Stored, SupportType>::printself(std::ostream & stream,
                                                     int indent) const {
   std::string space(indent, AKANTU_INDENT);
 
   stream << space << "ElementTypeMap<" << debug::demangle(typeid(Stored).name())
          << "> [" << std::endl;
   for (auto && gt : ghost_types) {
     const DataMap & data = getData(gt);
     for (auto & pair : data) {
       stream << space << space << ElementTypeMap::printType(pair.first, gt)
              << std::endl;
     }
   }
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::ElementTypeMap() = default;
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::~ElementTypeMap() = default;
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMapArray                                                        */
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 void ElementTypeMapArray<T, SupportType>::copy(
     const ElementTypeMapArray & other) {
   for (auto ghost_type : ghost_types) {
     for (auto type :
          this->elementTypes(_all_dimensions, ghost_type, _ek_not_defined)) {
       const auto & array_to_copy = other(type, ghost_type);
       auto & array =
           this->alloc(0, array_to_copy.getNbComponent(), type, ghost_type);
       array.copy(array_to_copy);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 ElementTypeMapArray<T, SupportType>::ElementTypeMapArray(
     const ElementTypeMapArray & other)
     : parent(), id(other.id + "_copy"), name(other.name + "_copy") {
   this->copy(other);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline Array<T> & ElementTypeMapArray<T, SupportType>::alloc(
-    UInt size, UInt nb_component, const SupportType & type,
-    GhostType ghost_type, const T & default_value) {
+    Int size, Int nb_component, const SupportType & type,
+    const GhostType & ghost_type, const T & default_value) {
   std::string ghost_id;
-  if (ghost_type == _ghost) {
+  if (ghost_type == _ghost)
     ghost_id = ":ghost";
   }
 
   auto it = this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end()) {
     auto id = this->id + ":" + std::to_string(type) + ghost_id;
 
     this->getData(ghost_type)[type] =
         std::make_unique<Array<T>>(size, nb_component, default_value, id);
     return *(this->getData(ghost_type)[type]);
   }
 
   AKANTU_DEBUG_INFO("The vector "
                     << this->id << this->printType(type, ghost_type)
                     << " already exists, it is resized instead of allocated.");
   auto && array = *(it->second);
   array.resize(size);
   return array;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void
-ElementTypeMapArray<T, SupportType>::alloc(UInt size, UInt nb_component,
+ElementTypeMapArray<T, SupportType>::alloc(Int size, Int nb_component,
                                            const SupportType & type,
                                            const T & default_value) {
   this->alloc(size, nb_component, type, _not_ghost, default_value);
   this->alloc(size, nb_component, type, _ghost, default_value);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::free() {
   AKANTU_DEBUG_IN();
 
   for (auto gt : ghost_types) {
     auto & data = this->getData(gt);
     data.clear();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::clear() {
   for (auto gt : ghost_types) {
     auto & data = this->getData(gt);
     for (auto & vect : data) {
       vect.second->clear();
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline bool ElementTypeMapArray<T, SupportType>::empty() const {
   bool is_empty = true;
   for (auto gt : ghost_types) {
     auto & data = this->getData(gt);
     for (auto & vect : data) {
       is_empty &= vect.second->empty();
       if (not is_empty) {
         return false;
       }
     }
   }
   return is_empty;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 template <typename ST>
 inline void ElementTypeMapArray<T, SupportType>::set(const ST & value) {
   for (auto gt : ghost_types) {
     auto & data = this->getData(gt);
     for (auto & vect : data) {
       vect.second->set(value);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline const Array<T> &
 ElementTypeMapArray<T, SupportType>::operator()(const SupportType & type,
                                                 GhostType ghost_type) const {
   auto it = this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end()) {
     AKANTU_SILENT_EXCEPTION("No element of type "
                             << ElementTypeMapArray::printType(type, ghost_type)
                             << " in this const ElementTypeMapArray<"
                             << debug::demangle(typeid(T).name()) << "> class(\""
                             << this->id << "\")");
   }
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline Array<T> &
 ElementTypeMapArray<T, SupportType>::operator()(const SupportType & type,
                                                 GhostType ghost_type) {
   auto it = this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end()) {
     AKANTU_SILENT_EXCEPTION("No element of type "
                             << ElementTypeMapArray::printType(type, ghost_type)
                             << " in this ElementTypeMapArray<"
                             << debug::demangle(typeid(T).name())
                             << "> class (\"" << this->id << "\")");
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::setArray(
     const SupportType & type, GhostType ghost_type, const Array<T> & vect) {
   auto it = this->getData(ghost_type).find(type);
 
   if (AKANTU_DEBUG_TEST(dblWarning) && it != this->getData(ghost_type).end() &&
       it->second != &vect) {
     AKANTU_DEBUG_WARNING(
         "The Array "
         << this->printType(type, ghost_type)
         << " is already registred, this call can lead to a memory leak.");
   }
 
   this->getData(ghost_type)[type] = &(const_cast<Array<T> &>(vect));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::onElementsRemoved(
-    const ElementTypeMapArray<UInt> & new_numbering) {
+    const ElementTypeMapArray<Int> & new_numbering) {
   for (auto gt : ghost_types) {
     for (auto && type :
          new_numbering.elementTypes(_all_dimensions, gt, _ek_not_defined)) {
       auto support_type = convertType<ElementType, SupportType>(type);
       if (this->exists(support_type, gt)) {
         const auto & renumbering = new_numbering(type, gt);
         if (renumbering.empty()) {
           continue;
         }
 
         auto & vect = this->operator()(support_type, gt);
         auto nb_component = vect.getNbComponent();
         Array<T> tmp(renumbering.size(), nb_component);
-        UInt new_size = 0;
+        Int new_size = 0;
 
-        for (UInt i = 0; i < vect.size(); ++i) {
-          UInt new_i = renumbering(i);
-          if (new_i != UInt(-1)) {
+        for (Int i = 0; i < vect.size(); ++i) {
+          auto new_i = renumbering(i);
+          if (new_i != Int(-1)) {
             std::copy_n(vect.data() + i * nb_component, nb_component,
                         tmp.data() + new_i * nb_component);
             ++new_size;
           }
         }
         tmp.resize(new_size);
         vect.copy(tmp);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 void ElementTypeMapArray<T, SupportType>::printself(std::ostream & stream,
                                                     int indent) const {
   std::string space(indent, AKANTU_INDENT);
 
   stream << space << "ElementTypeMapArray<" << debug::demangle(typeid(T).name())
          << "> [" << std::endl;
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     auto gt = (GhostType)g;
 
     const DataMap & data = this->getData(gt);
     typename DataMap::const_iterator it;
     for (it = data.begin(); it != data.end(); ++it) {
       stream << space << space << ElementTypeMapArray::printType(it->first, gt)
              << " [" << std::endl;
       it->second->printself(stream, indent + 3);
       stream << space << space << " ]" << std::endl;
     }
   }
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 /* SupportType Iterator                                                       */
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(
-    DataMapIterator & list_begin, DataMapIterator & list_end, UInt dim,
+    DataMapIterator & list_begin, DataMapIterator & list_end, Int dim,
     ElementKind ek)
     : list_begin(list_begin), list_end(list_end), dim(dim), kind(ek) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(
     const type_iterator & it)
     : list_begin(it.list_begin), list_end(it.list_end), dim(it.dim),
       kind(it.kind) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 typename ElementTypeMap<Stored, SupportType>::type_iterator &
 ElementTypeMap<Stored, SupportType>::type_iterator::operator=(
     const type_iterator & it) {
   if (this != &it) {
     list_begin = it.list_begin;
     list_end = it.list_end;
     dim = it.dim;
     kind = it.kind;
   }
   return *this;
 }
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
 ElementTypeMap<Stored, SupportType>::type_iterator::operator*() {
   return list_begin->first;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
 ElementTypeMap<Stored, SupportType>::type_iterator::operator*() const {
   return list_begin->first;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator &
 ElementTypeMap<Stored, SupportType>::type_iterator::operator++() {
   ++list_begin;
   while ((list_begin != list_end) &&
          (((dim != _all_dimensions) &&
            (dim != Mesh::getSpatialDimension(list_begin->first))) ||
           ((kind != _ek_not_defined) &&
            (kind != Mesh::getKind(list_begin->first))))) {
     ++list_begin;
   }
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 typename ElementTypeMap<Stored, SupportType>::type_iterator
 ElementTypeMap<Stored, SupportType>::type_iterator::operator++(int) {
   type_iterator tmp(*this);
   operator++();
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline bool ElementTypeMap<Stored, SupportType>::type_iterator::operator==(
     const type_iterator & other) const {
   return this->list_begin == other.list_begin;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline bool ElementTypeMap<Stored, SupportType>::type_iterator::operator!=(
     const type_iterator & other) const {
   return this->list_begin != other.list_begin;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 auto ElementTypeMap<Stored, SupportType>::ElementTypesIteratorHelper::begin()
     -> iterator {
   auto b = container.get().getData(ghost_type).begin();
   auto e = container.get().getData(ghost_type).end();
 
   // loop until the first valid type
   while ((b != e) &&
          (((dim != _all_dimensions) &&
            (dim != Mesh::getSpatialDimension(b->first))) ||
           ((kind != _ek_not_defined) && (kind != Mesh::getKind(b->first))))) {
     ++b;
   }
 
   return iterator(b, e, dim, kind);
 }
 
 template <class Stored, typename SupportType>
 auto ElementTypeMap<Stored, SupportType>::ElementTypesIteratorHelper::end()
     -> iterator {
   auto e = container.get().getData(ghost_type).end();
   return iterator(e, e, dim, kind);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 auto ElementTypeMap<Stored, SupportType>::elementTypesImpl(
-    UInt dim, GhostType ghost_type, ElementKind kind) const
+    Int dim, GhostType ghost_type, ElementKind kind) const
     -> ElementTypesIteratorHelper {
   return ElementTypesIteratorHelper(*this, dim, ghost_type, kind);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 template <typename... pack>
 auto ElementTypeMap<Stored, SupportType>::elementTypesImpl(
     const use_named_args_t & unused, pack &&... _pack) const
     -> ElementTypesIteratorHelper {
   return ElementTypesIteratorHelper(*this, unused, _pack...);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline auto ElementTypeMap<Stored, SupportType>::firstType(
-    UInt dim, GhostType ghost_type, ElementKind kind) const -> type_iterator {
+    Int dim, GhostType ghost_type, ElementKind kind) const -> type_iterator {
   return elementTypes(dim, ghost_type, kind).begin();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline auto ElementTypeMap<Stored, SupportType>::lastType(
-    UInt dim, GhostType ghost_type, ElementKind kind) const -> type_iterator {
+    Int dim, GhostType ghost_type, ElementKind kind) const -> type_iterator {
   typename DataMap::const_iterator e;
   e = getData(ghost_type).end();
   return typename ElementTypeMap<Stored, SupportType>::type_iterator(e, e, dim,
                                                                      kind);
 }
 
 /* -------------------------------------------------------------------------- */
 
 /// standard output stream operator
 template <class Stored, typename SupportType>
 inline std::ostream &
 operator<<(std::ostream & stream,
            const ElementTypeMap<Stored, SupportType> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 class ElementTypeMapArrayInitializer {
 protected:
-  using CompFunc = std::function<UInt(ElementType, GhostType)>;
+  using CompFunc = std::function<Int(ElementType, GhostType)>;
 
 public:
-  ElementTypeMapArrayInitializer(const CompFunc & comp_func,
-                                 UInt spatial_dimension = _all_dimensions,
-                                 GhostType ghost_type = _not_ghost,
-                                 ElementKind element_kind = _ek_not_defined)
+  ElementTypeMapArrayInitializer(
+      const CompFunc & comp_func, Int spatial_dimension = _all_dimensions,
+      const GhostType & ghost_type = _not_ghost,
+      const ElementKind & element_kind = _ek_not_defined)
       : comp_func(comp_func), spatial_dimension(spatial_dimension),
         ghost_type(ghost_type), element_kind(element_kind) {}
 
   GhostType ghostType() const { return ghost_type; }
 
-  virtual UInt nbComponent(ElementType type) const {
+  virtual Int nbComponent(const ElementType & type) const {
     return comp_func(type, ghostType());
   }
 
   virtual bool isNodal() const { return false; }
 
 protected:
   CompFunc comp_func;
-  UInt spatial_dimension;
+  Int spatial_dimension;
   GhostType ghost_type;
   ElementKind element_kind;
 };
 
 /* -------------------------------------------------------------------------- */
 class MeshElementTypeMapArrayInitializer
     : public ElementTypeMapArrayInitializer {
   using CompFunc = ElementTypeMapArrayInitializer::CompFunc;
 
 public:
   MeshElementTypeMapArrayInitializer(
-      const Mesh & mesh, UInt nb_component = 1,
+      const Mesh & mesh, Int nb_component = 1,
       UInt spatial_dimension = _all_dimensions,
       GhostType ghost_type = _not_ghost,
       ElementKind element_kind = _ek_not_defined, bool with_nb_element = false,
       bool with_nb_nodes_per_element = false,
-      const ElementTypeMapArray<UInt> * filter = nullptr)
+      const ElementTypeMapArray<Idx> * filter = nullptr)
       : MeshElementTypeMapArrayInitializer(
             mesh,
-            [nb_component](ElementType /*unused*/, GhostType /*unused*/)
-                -> UInt { return nb_component; },
+            [nb_component](const ElementType &, const GhostType &) -> Int {
+              return nb_component;
+            },
             spatial_dimension, ghost_type, element_kind, with_nb_element,
             with_nb_nodes_per_element, filter) {}
 
   MeshElementTypeMapArrayInitializer(
       const Mesh & mesh, const CompFunc & comp_func,
-      UInt spatial_dimension = _all_dimensions,
+      Int spatial_dimension = _all_dimensions,
       GhostType ghost_type = _not_ghost,
       ElementKind element_kind = _ek_not_defined, bool with_nb_element = false,
       bool with_nb_nodes_per_element = false,
-      const ElementTypeMapArray<UInt> * filter = nullptr)
+      const ElementTypeMapArray<Idx> * filter = nullptr)
       : ElementTypeMapArrayInitializer(comp_func, spatial_dimension, ghost_type,
                                        element_kind),
         mesh(mesh), with_nb_element(with_nb_element),
         with_nb_nodes_per_element(with_nb_nodes_per_element), filter(filter) {}
 
   decltype(auto) elementTypes() const {
     if (filter) {
       return filter->elementTypes(this->spatial_dimension, this->ghost_type,
                                   this->element_kind);
     }
     return mesh.elementTypes(this->spatial_dimension, this->ghost_type,
                              this->element_kind);
   }
 
-  virtual UInt size(ElementType type) const {
+  virtual Idx size(ElementType type) const {
     if (with_nb_element) {
       if (filter) {
         return (*filter)(type, this->ghost_type).size();
       }
       return mesh.getNbElement(type, this->ghost_type);
     }
 
     return 0;
   }
 
-  UInt nbComponent(ElementType type) const override {
-    UInt res = ElementTypeMapArrayInitializer::nbComponent(type);
+  auto nbComponent(ElementType type) const override {
+    auto res = ElementTypeMapArrayInitializer::nbComponent(type);
     if (with_nb_nodes_per_element) {
       return (res * Mesh::getNbNodesPerElement(type));
     }
 
     return res;
   }
 
   bool isNodal() const override { return with_nb_nodes_per_element; }
 
 protected:
   const Mesh & mesh;
   bool with_nb_element{false};
   bool with_nb_nodes_per_element{false};
   const ElementTypeMapArray<UInt> * filter{nullptr};
 };
 
 /* -------------------------------------------------------------------------- */
 class FEEngineElementTypeMapArrayInitializer
     : public MeshElementTypeMapArrayInitializer {
 public:
   FEEngineElementTypeMapArrayInitializer(
-      const FEEngine & fe_engine, UInt nb_component = 1,
-      UInt spatial_dimension = _all_dimensions,
-      GhostType ghost_type = _not_ghost,
-      ElementKind element_kind = _ek_not_defined);
+      const FEEngine & fe_engine, Int nb_component = 1,
+      Int spatial_dimension = _all_dimensions,
+      const GhostType & ghost_type = _not_ghost,
+      const ElementKind & element_kind = _ek_not_defined);
 
   FEEngineElementTypeMapArrayInitializer(
       const FEEngine & fe_engine,
       const ElementTypeMapArrayInitializer::CompFunc & nb_component,
-      UInt spatial_dimension = _all_dimensions,
-      GhostType ghost_type = _not_ghost,
-      ElementKind element_kind = _ek_not_defined);
+      Int spatial_dimension = _all_dimensions,
+      const GhostType & ghost_type = _not_ghost,
+      const ElementKind & element_kind = _ek_not_defined);
 
-  UInt size(ElementType type) const override;
+  Int size(const ElementType & type) const override;
 
   using ElementTypesIteratorHelper =
       ElementTypeMapArray<Real, ElementType>::ElementTypesIteratorHelper;
 
   ElementTypesIteratorHelper elementTypes() const;
 
 protected:
   const FEEngine & fe_engine;
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 template <class Func>
 void ElementTypeMapArray<T, SupportType>::initialize(const Func & f,
                                                      const T & default_value,
                                                      bool do_not_default) {
   this->is_nodal = f.isNodal();
   auto ghost_type = f.ghostType();
   for (auto & type : f.elementTypes()) {
     if (not this->exists(type, ghost_type)) {
       if (do_not_default) {
         auto & array = this->alloc(0, f.nbComponent(type), type, ghost_type);
         array.resize(f.size(type));
       } else {
         this->alloc(f.size(type), f.nbComponent(type), type, ghost_type,
                     default_value);
       }
     } else {
       auto & array = this->operator()(type, ghost_type);
       if (not do_not_default) {
         array.resize(f.size(type), default_value);
       } else {
         array.resize(f.size(type));
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * All parameters are named optionals
  *  \param _nb_component a functor giving the number of components per
  *  (ElementType, GhostType) pair or a scalar giving a unique number of
  * components
  *  regardless of type
  *  \param _spatial_dimension a filter for the elements of a specific dimension
  *  \param _element_kind filter with element kind (_ek_regular, _ek_structural,
  * ...)
  *  \param _with_nb_element allocate the arrays with the number of elements for
  * each
  *  type in the mesh
  *  \param _with_nb_nodes_per_element multiply the number of components by the
  *  number of nodes per element
  *  \param _default_value default inital value
  *  \param _do_not_default do not initialize the allocated arrays
  *  \param _ghost_type filter a type of ghost
  */
 template <typename T, typename SupportType>
 template <typename... pack>
 void ElementTypeMapArray<T, SupportType>::initialize(const Mesh & mesh,
                                                      pack &&... _pack) {
   GhostType requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _casper);
   bool all_ghost_types =
       OPTIONAL_NAMED_ARG(all_ghost_types, requested_ghost_type == _casper);
 
   for (GhostType ghost_type : ghost_types) {
     if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types)) {
       continue;
     }
 
     auto functor = MeshElementTypeMapArrayInitializer(
         mesh, OPTIONAL_NAMED_ARG(nb_component, 1),
         OPTIONAL_NAMED_ARG(spatial_dimension, mesh.getSpatialDimension()),
         ghost_type, OPTIONAL_NAMED_ARG(element_kind, _ek_not_defined),
         OPTIONAL_NAMED_ARG(with_nb_element, false),
         OPTIONAL_NAMED_ARG(with_nb_nodes_per_element, false),
         OPTIONAL_NAMED_ARG(element_filter, nullptr));
 
     this->initialize(functor, OPTIONAL_NAMED_ARG(default_value, T()),
                      OPTIONAL_NAMED_ARG(do_not_default, false));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * All parameters are named optionals
  *  \param _nb_component a functor giving the number of components per
  *  (ElementType, GhostType) pair or a scalar giving a unique number of
  * components
  *  regardless of type
  *  \param _spatial_dimension a filter for the elements of a specific dimension
  *  \param _element_kind filter with element kind (_ek_regular, _ek_structural,
  * ...)
  *  \param _default_value default inital value
  *  \param _do_not_default do not initialize the allocated arrays
  *  \param _ghost_type filter a specific ghost type
  *  \param _all_ghost_types get all ghost types
  */
 template <typename T, typename SupportType>
 template <typename... pack>
 void ElementTypeMapArray<T, SupportType>::initialize(const FEEngine & fe_engine,
                                                      pack &&... _pack) {
   GhostType requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _casper);
   bool all_ghost_types =
       OPTIONAL_NAMED_ARG(all_ghost_types, requested_ghost_type == _casper);
 
   for (auto ghost_type : ghost_types) {
     if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types)) {
       continue;
     }
 
     auto functor = FEEngineElementTypeMapArrayInitializer(
         fe_engine, OPTIONAL_NAMED_ARG(nb_component, 1),
-        OPTIONAL_NAMED_ARG(spatial_dimension, UInt(-2)), ghost_type,
+        OPTIONAL_NAMED_ARG(spatial_dimension, Int(-2)), ghost_type,
         OPTIONAL_NAMED_ARG(element_kind, _ek_not_defined));
 
     this->initialize(functor, OPTIONAL_NAMED_ARG(default_value, T()),
                      OPTIONAL_NAMED_ARG(do_not_default, false));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, typename SupportType>
-inline T &
-ElementTypeMapArray<T, SupportType>::operator()(const Element & element,
-                                                UInt component) {
+inline T & ElementTypeMapArray<T, SupportType>::
+operator()(const Element & element, Int component) {
   return this->operator()(element.type, element.ghost_type)(element.element,
                                                             component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, typename SupportType>
-inline const T &
-ElementTypeMapArray<T, SupportType>::operator()(const Element & element,
-                                                UInt component) const {
+inline const T & ElementTypeMapArray<T, SupportType>::
+operator()(const Element & element, Int component) const {
   return this->operator()(element.type, element.ghost_type)(element.element,
                                                             component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, typename SupportType>
 inline decltype(auto)
 ElementTypeMapArray<T, SupportType>::get(const Element & element) {
   auto & array = operator()(element.type, element.ghost_type);
   auto it = array.begin(array.getNbComponent());
   return it[element.element];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, typename SupportType>
 inline decltype(auto)
 ElementTypeMapArray<T, SupportType>::get(const Element & element) const {
   auto & array = operator()(element.type, element.ghost_type);
   auto it = array.begin(array.getNbComponent());
   return it[element.element];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, typename SupportType>
 UInt ElementTypeMapArray<T, SupportType>::sizeImpl(UInt spatial_dimension,
                                                    GhostType ghost_type,
                                                    ElementKind kind) const {
   UInt size = 0;
   for (auto && type : this->elementTypes(spatial_dimension, ghost_type, kind)) {
     size += this->operator()(type, ghost_type).size();
   }
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, typename SupportType>
 template <typename... pack>
-UInt ElementTypeMapArray<T, SupportType>::size(pack &&... _pack) const {
-  UInt size = 0;
+Int ElementTypeMapArray<T, SupportType>::size(pack &&... _pack) const {
+  Int size = 0;
   GhostType requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _casper);
   bool all_ghost_types =
       OPTIONAL_NAMED_ARG(all_ghost_types, requested_ghost_type == _casper);
 
   for (auto ghost_type : ghost_types) {
     if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types)) {
       continue;
     }
 
     size +=
         sizeImpl(OPTIONAL_NAMED_ARG(spatial_dimension, _all_dimensions),
                  ghost_type, OPTIONAL_NAMED_ARG(element_kind, _ek_not_defined));
   }
   return size;
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_ELEMENT_TYPE_MAP_TMPL_HH_ */
diff --git a/src/mesh/group_manager.hh b/src/mesh/group_manager.hh
index 4cd70f563..a83d51735 100644
--- a/src/mesh/group_manager.hh
+++ b/src/mesh/group_manager.hh
@@ -1,350 +1,350 @@
 /**
  * @file   group_manager.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@gmail.com>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Stores information relevent to the notion of element and nodes
  * groups.
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_GROUP_MANAGER_HH_
 #define AKANTU_GROUP_MANAGER_HH_
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_iterators.hh"
 #include "element_type_map.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class ElementGroup;
 class NodeGroup;
 class Mesh;
 class Element;
 class ElementSynchronizer;
 template <bool> class CommunicationBufferTemplated;
 namespace dumpers {
   class Field;
 }
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class GroupManager {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   using ElementGroups = std::map<std::string, std::unique_ptr<ElementGroup>>;
   using NodeGroups = std::map<std::string, std::unique_ptr<NodeGroup>>;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   GroupManager(Mesh & mesh, const ID & id = "group_manager");
   virtual ~GroupManager();
 
   /* ------------------------------------------------------------------------ */
   /* Groups iterators                                                         */
   /* ------------------------------------------------------------------------ */
 public:
   using node_group_iterator = NodeGroups::iterator;
   using element_group_iterator = ElementGroups::iterator;
 
   using const_node_group_iterator = NodeGroups::const_iterator;
   using const_element_group_iterator = ElementGroups::const_iterator;
 
 #define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(group_type, function,        \
                                                       param_in, param_out)         \
   [[deprecated(                                                                    \
       "use iterate(Element|Node)Groups or "                                        \
       "(element|node)GroupExists")]] inline BOOST_PP_CAT(BOOST_PP_CAT(const_,      \
                                                                       group_type), \
                                                          _iterator)                \
       BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) const {        \
     return BOOST_PP_CAT(group_type, s).function(param_out);                        \
   };                                                                               \
                                                                                    \
   [[deprecated("use iterate(Element|Node)Groups or "                               \
                "(element|node)GroupExists")]] inline BOOST_PP_CAT(group_type,      \
                                                                   _iterator)       \
       BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) {              \
     return BOOST_PP_CAT(group_type, s).function(param_out);                        \
   }
 
 #define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(group_type, function) \
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(                               \
       group_type, function, BOOST_PP_EMPTY(), BOOST_PP_EMPTY())
 
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, begin);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, end);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, begin);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, end);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(element_group, find,
                                                 const std::string & name, name);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(node_group, find,
                                                 const std::string & name, name);
 
 public:
   decltype(auto) iterateNodeGroups() {
     return make_dereference_adaptor(make_values_adaptor(node_groups));
   }
   decltype(auto) iterateNodeGroups() const {
     return make_dereference_adaptor(make_values_adaptor(node_groups));
   }
 
   decltype(auto) iterateElementGroups() {
     return make_dereference_adaptor(make_values_adaptor(element_groups));
   }
   decltype(auto) iterateElementGroups() const {
     return make_dereference_adaptor(make_values_adaptor(element_groups));
   }
 
   /* ------------------------------------------------------------------------ */
   /* Clustering filter                                                        */
   /* ------------------------------------------------------------------------ */
 public:
   class ClusteringFilter {
   public:
     virtual bool operator()(const Element & /*unused*/) const { return true; }
   };
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// create an empty node group
   NodeGroup & createNodeGroup(const std::string & group_name,
                               bool replace_group = false);
 
   /// create an element group and the associated node group
   ElementGroup & createElementGroup(const std::string & group_name,
-                                    UInt dimension = _all_dimensions,
+                                    Int dimension = _all_dimensions,
                                     bool replace_group = false);
 
   /* ------------------------------------------------------------------------ */
   /// renames an element group
   void renameElementGroup(const std::string & name,
                           const std::string & new_name);
 
   /// renames a node group
   void renameNodeGroup(const std::string & name, const std::string & new_name);
 
   /// copy an existing element group
   void copyElementGroup(const std::string & name, const std::string & new_name);
 
   /// copy an existing node group
   void copyNodeGroup(const std::string & name, const std::string & new_name);
 
   /* ------------------------------------------------------------------------ */
 
   /// create a node group from another node group but filtered
   template <typename T>
   NodeGroup & createFilteredNodeGroup(const std::string & group_name,
                                       const NodeGroup & node_group, T & filter);
 
   /// create an element group from another element group but filtered
   template <typename T>
   ElementGroup &
-  createFilteredElementGroup(const std::string & group_name, UInt dimension,
+  createFilteredElementGroup(const std::string & group_name, Int dimension,
                              const NodeGroup & node_group, T & filter);
 
   /// destroy a node group
   void destroyNodeGroup(const std::string & group_name);
 
   /// destroy an element group and the associated node group
   void destroyElementGroup(const std::string & group_name,
                            bool destroy_node_group = false);
 
   // /// destroy all element groups and the associated node groups
   // void destroyAllElementGroups(bool destroy_node_groups = false);
 
   /// create a element group using an existing node group
   ElementGroup & createElementGroup(const std::string & group_name,
-                                    UInt dimension, NodeGroup & node_group);
+                                    Int dimension, NodeGroup & node_group);
 
   /// create groups based on values stored in a given mesh data
   template <typename T>
   void createGroupsFromMeshData(const std::string & dataset_name);
 
   /// create boundaries group by a clustering algorithm \todo extend to parallel
-  UInt createBoundaryGroupFromGeometry();
+  Int createBoundaryGroupFromGeometry();
 
   /// create element clusters for a given dimension
-  UInt createClusters(UInt element_dimension, Mesh & mesh_facets,
-                      const std::string & cluster_name_prefix = "cluster",
+  Int createClusters(Int element_dimension, Mesh & mesh_facets,
+                      std::string cluster_name_prefix = "cluster",
                       const ClusteringFilter & filter = ClusteringFilter());
 
   /// create element clusters for a given dimension
-  UInt createClusters(UInt element_dimension,
-                      const std::string & cluster_name_prefix = "cluster",
+  Int createClusters(Int element_dimension,
+                      std::string cluster_name_prefix = "cluster",
                       const ClusteringFilter & filter = ClusteringFilter());
 
 private:
   /// create element clusters for a given dimension
-  UInt createClusters(UInt element_dimension,
-                      const std::string & cluster_name_prefix,
-                      const ClusteringFilter & filter, Mesh & mesh_facets);
+  Int createClusters(Int element_dimension,
+                     const std::string & cluster_name_prefix,
+                     const ClusteringFilter & filter, Mesh & mesh_facets);
 
 public:
   /// Create an ElementGroup based on a NodeGroup
   void createElementGroupFromNodeGroup(const std::string & name,
                                        const std::string & node_group,
-                                       UInt dimension = _all_dimensions);
+                                       Int dimension = _all_dimensions);
 
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// this function insure that the group names are present on all processors
   /// /!\ it is a SMP call
   void synchronizeGroupNames();
 
   /// register an elemental field to the given group name (overloading for
   /// ElementalPartionField)
   template <typename T, template <bool> class dump_type>
   std::shared_ptr<dumpers::Field> createElementalField(
       const ElementTypeMapArray<T> & field, const std::string & group_name,
-      UInt spatial_dimension, ElementKind kind,
-      ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
+      UInt spatial_dimension, const ElementKind & kind,
+      ElementTypeMap<Int> nb_data_per_elem = ElementTypeMap<Int>());
 
   /// register an elemental field to the given group name (overloading for
   /// ElementalField)
   template <typename T, template <class> class ret_type,
             template <class, template <class> class, bool> class dump_type>
   std::shared_ptr<dumpers::Field> createElementalField(
       const ElementTypeMapArray<T> & field, const std::string & group_name,
-      UInt spatial_dimension, ElementKind kind,
-      ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
+      UInt spatial_dimension, const ElementKind & kind,
+      ElementTypeMap<Int> nb_data_per_elem = ElementTypeMap<Int>());
 
   /// register an elemental field to the given group name (overloading for
   /// MaterialInternalField)
   template <typename T,
             /// type of InternalMaterialField
             template <typename, bool filtered> class dump_type>
   std::shared_ptr<dumpers::Field>
   createElementalField(const ElementTypeMapArray<T> & field,
                        const std::string & group_name, UInt spatial_dimension,
-                       ElementKind kind,
-                       ElementTypeMap<UInt> nb_data_per_elem);
+                       const ElementKind & kind,
+                       ElementTypeMap<Int> nb_data_per_elem);
 
   template <typename type, bool flag, template <class, bool> class ftype>
   std::shared_ptr<dumpers::Field>
   createNodalField(const ftype<type, flag> * field,
-                   const std::string & group_name, UInt padding_size = 0);
+                   const std::string & group_name, Int padding_size = 0);
 
   template <typename type, bool flag, template <class, bool> class ftype>
   std::shared_ptr<dumpers::Field>
   createStridedNodalField(const ftype<type, flag> * field,
-                          const std::string & group_name, UInt size,
-                          UInt stride, UInt padding_size);
+                          const std::string & group_name, Int size,
+                          Int stride, Int padding_size);
 
 protected:
   /// fill a buffer with all the group names
   void fillBufferWithGroupNames(
       CommunicationBufferTemplated<false> & comm_buffer) const;
 
   /// take a buffer and create the missing groups localy
   void checkAndAddGroups(CommunicationBufferTemplated<false> & buffer);
 
   /// register an elemental field to the given group name
   template <class dump_type, typename field_type>
   inline std::shared_ptr<dumpers::Field>
   createElementalField(const field_type & field, const std::string & group_name,
-                       UInt spatial_dimension, ElementKind kind,
-                       const ElementTypeMap<UInt> & nb_data_per_elem);
+                       Int spatial_dimension, const ElementKind & kind,
+                       const ElementTypeMap<Int> & nb_data_per_elem);
 
   /// register an elemental field to the given group name
   template <class dump_type, typename field_type>
   inline std::shared_ptr<dumpers::Field>
   createElementalFilteredField(const field_type & field,
                                const std::string & group_name,
-                               UInt spatial_dimension, ElementKind kind,
-                               ElementTypeMap<UInt> nb_data_per_elem);
+                               Int spatial_dimension, const ElementKind & kind,
+                               ElementTypeMap<Int> nb_data_per_elem);
 
   /* ------------------------------------------------------------------------ */
   /* Accessor                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   // AKANTU_GET_MACRO(ElementGroups, element_groups, const ElementGroups &);
 
   const ElementGroup & getElementGroup(const std::string & name) const;
   const NodeGroup & getNodeGroup(const std::string & name) const;
 
   ElementGroup & getElementGroup(const std::string & name);
   NodeGroup & getNodeGroup(const std::string & name);
 
-  UInt getNbElementGroups(UInt dimension = _all_dimensions) const;
-  UInt getNbNodeGroups() { return node_groups.size(); };
+  Int getNbElementGroups(Int dimension = _all_dimensions) const;
+  Int getNbNodeGroups() { return node_groups.size(); };
 
   bool elementGroupExists(const std::string & name) {
     return element_groups.find(name) != element_groups.end();
   }
 
   bool nodeGroupExists(const std::string & name) {
     return node_groups.find(name) != node_groups.end();
   }
 
 private:
   template <typename GroupsType>
   void renameGroup(GroupsType & groups, const std::string & name,
                    const std::string & new_name);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// id to create element and node groups
   ID id;
 
   /// list of the node groups managed
   NodeGroups node_groups;
 
   /// list of the element groups managed
   ElementGroups element_groups;
 
   /// Mesh to which the element belongs
   Mesh & mesh;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const GroupManager & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_GROUP_MANAGER_HH_ */
diff --git a/src/mesh/mesh.hh b/src/mesh/mesh.hh
index 393448fc8..3119daef6 100644
--- a/src/mesh/mesh.hh
+++ b/src/mesh/mesh.hh
@@ -1,700 +1,733 @@
 /**
  * @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 Nov 12 2020
  *
  * @brief  the class representing the meshes
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_bbox.hh"
 #include "aka_event_handler_manager.hh"
 #include "communicator.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 <functional>
 #include <set>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class ElementSynchronizer;
 class NodeSynchronizer;
 class PeriodicNodeSynchronizer;
 class MeshGlobalDataUpdater;
 } // namespace akantu
 
 namespace akantu {
 
 namespace {
   DECLARE_NAMED_ARGUMENT(communicator);
   DECLARE_NAMED_ARGUMENT(edge_weight_function);
   DECLARE_NAMED_ARGUMENT(vertex_weight_function);
 } // namespace
 
 /* -------------------------------------------------------------------------- */
 /* Mesh                                                                       */
 /* -------------------------------------------------------------------------- */
 
 /**
  * @class  Mesh mesh.hh
  *
  * This class contaisn the coordinates of the nodes in the Mesh.nodes
  * akant::Array, and the connectivity. The connectivity are stored in by element
  * types.
  *
  * In order to loop on all element you have to loop on all types like this :
  * @code{.cpp}
  for(auto & type : mesh.elementTypes()) {
    UInt nb_element  = mesh.getNbElement(type);
    const Array<UInt> & conn = mesh.getConnectivity(type);
    for(UInt e = 0; e < nb_element; ++e) {
      ...
    }
  }
 
  or
 
  for_each_element(mesh, [](Element & element) {
     std::cout << element << std::endl
   });
  @endcode
 */
 class Mesh : public EventHandlerManager<MeshEventHandler>,
              public GroupManager,
              public MeshData,
              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, Communicator & communicator);
 
 public:
   /// constructor that create nodes coordinates array
   Mesh(UInt spatial_dimension, const ID & id = "mesh");
 
   /// mesh not distributed and not using the default communicator
   Mesh(UInt spatial_dimension, Communicator & communicator,
        const ID & id = "mesh");
 
   /**
    * constructor that use an existing nodes coordinates
    * array, by getting the vector of coordinates
    */
   Mesh(UInt spatial_dimension, const std::shared_ptr<Array<Real>> & nodes,
        const ID & id = "mesh");
 
   ~Mesh() override;
 
   /// 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);
 
 protected:
   void makeReady();
 
 private:
   /// initialize the connectivity to NULL and other stuff
   void init();
 
   /// function that computes the bounding box (fills xmin, xmax)
   void computeBoundingBox();
 
   /* ------------------------------------------------------------------------ */
   /* Distributed memory methods and accessors                                 */
   /* ------------------------------------------------------------------------ */
 public:
 protected:
   /// patitionate the mesh among the processors involved in their computation
   virtual void distributeImpl(
       Communicator & communicator,
       const std::function<Int(const Element &, const Element &)> &
           edge_weight_function,
       const std::function<Int(const Element &)> & vertex_weight_function);
 
 public:
   /// with the arguments to pass to the partitionner
   template <typename... pack>
   std::enable_if_t<are_named_argument<pack...>::value>
   distribute(pack &&... _pack) {
     distributeImpl(
         OPTIONAL_NAMED_ARG(communicator, Communicator::getStaticCommunicator()),
         OPTIONAL_NAMED_ARG(edge_weight_function,
                            [](auto &&, auto &&) { return 1; }),
         OPTIONAL_NAMED_ARG(vertex_weight_function, [](auto &&) { return 1; }));
   }
 
   /// defines is the mesh is distributed or not
   inline bool isDistributed() const { return this->is_distributed; }
 
   /* ------------------------------------------------------------------------ */
   /* Periodicity methods and accessors                                        */
   /* ------------------------------------------------------------------------ */
 public:
   /// set the periodicity in a given direction
   void makePeriodic(const SpatialDirection & direction);
   void makePeriodic(const SpatialDirection & direction, const ID & list_1,
                     const ID & list_2);
 
 protected:
   void makePeriodic(const SpatialDirection & direction,
-                    const Array<UInt> & list_left,
-                    const Array<UInt> & list_right);
+                    const Array<Idx> & list_1, const Array<Idx> & list_2);
 
   /// Removes the face that the mesh is periodic
   void wipePeriodicInfo();
 
-  inline void addPeriodicSlave(UInt slave, UInt master);
+  inline void addPeriodicSlave(Idx slave, Idx master);
 
   template <typename T>
   void synchronizePeriodicSlaveDataWithMaster(Array<T> & data);
 
   // update the periodic synchronizer (creates it if it does not exists)
   void updatePeriodicSynchronizer();
 
 public:
   /// defines if the mesh is periodic or not
   inline bool isPeriodic() const { return this->is_periodic; }
 
   inline bool isPeriodic(const SpatialDirection & /*direction*/) const {
     return this->is_periodic;
   }
 
   class PeriodicSlaves;
 
   /// get the master node for a given slave nodes, except if node not a slave
-  inline UInt getPeriodicMaster(UInt slave) const;
+  inline Idx getPeriodicMaster(Idx slave) const;
 
   /// get an iterable list of slaves for a given master node
-  inline decltype(auto) getPeriodicSlaves(UInt master) const;
+  inline decltype(auto) getPeriodicSlaves(Idx master) const;
 
   /* ------------------------------------------------------------------------ */
   /* General Methods                                                          */
   /* ------------------------------------------------------------------------ */
 public:
   /// function to print the containt of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /// extract coordinates of nodes from an element
   template <typename T>
-  inline void
-  extractNodalValuesFromElement(const Array<T> & nodal_values, T * local_coord,
-                                const UInt * connectivity, UInt n_nodes,
-                                UInt nb_degree_of_freedom) const;
+  inline void extractNodalValuesFromElement(const Array<T> & nodal_values,
+                                            T * elemental_values,
+                                            Idx * connectivity, Int n_nodes,
+                                            Int nb_degree_of_freedom) const;
 
   // /// extract coordinates of nodes from a reversed element
   // inline void extractNodalCoordinatesFromPBCElement(Real * local_coords,
   //                                                   UInt * connectivity,
   //                                                   UInt n_nodes);
 
   /// add a Array of connectivity for the given ElementType and GhostType .
   inline void addConnectivityType(ElementType type,
                                   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);
+                                   const Array<Int> & new_numbering);
 
   /// 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);
+  void getGlobalConnectivity(ElementTypeMapArray<Int> & global_connectivity);
 
 public:
-  void getAssociatedElements(const Array<UInt> & node_list,
-                             Array<Element> & elements) const;
+  void getAssociatedElements(const Array<Int> & node_list,
+                             Array<Element> & elements);
 
   void getAssociatedElements(const UInt & node,
                              Array<Element> & elements) const;
 
 public:
   /// fills the nodes_to_elements for given dimension elements
   void fillNodesToElements(UInt dimension = _all_dimensions);
 
 private:
   /// update the global ids, nodes type, ...
-  std::tuple<UInt, UInt> updateGlobalData(NewNodesEvent & nodes_event,
-                                          NewElementsEvent & elements_event);
+  std::tuple<Int, Int> updateGlobalData(NewNodesEvent & nodes_event,
+                                        NewElementsEvent & elements_event);
 
   void registerGlobalDataUpdater(
       std::unique_ptr<MeshGlobalDataUpdater> && global_data_updater);
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the id of the mesh
   AKANTU_GET_MACRO(ID, id, const ID &);
 
   /// get the spatial dimension of the mesh = number of component of the
   /// coordinates
-  AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
+  AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, Int);
 
   /// 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 to the element if they exists (not at the integration
   /// points)
   const Array<Real> & getNormals(ElementType element_type,
                                  GhostType ghost_type = _not_ghost) const;
 
   /// same as getNormals const but compute them if needed
   const Array<Real> & getNormals(ElementType element_type,
                                  GhostType ghost_type = _not_ghost);
 
   /// get the number of nodes
-  AKANTU_GET_MACRO(NbNodes, nodes->size(), UInt);
+  auto getNbNodes() const { return nodes->size(); }
 
   /// 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_AUTO(GlobalNodesIds, *nodes_global_ids);
   // 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;
+  inline auto getNodeGlobalId(Idx local_id) const;
 
   /// get the global id of a node
-  inline UInt getNodeLocalId(UInt global_id) const;
+  inline auto getNodeLocalId(Idx global_id) const;
 
   /// get the global number of nodes
-  inline UInt getNbGlobalNodes() const;
+  inline auto getNbGlobalNodes() const;
 
   /// get the nodes type Array
   AKANTU_GET_MACRO(NodesFlags, *nodes_flags, const Array<NodeFlag> &);
 
 protected:
   AKANTU_GET_MACRO_NOT_CONST(NodesFlags, *nodes_flags, Array<NodeFlag> &);
 
 public:
-  inline NodeFlag getNodeFlag(UInt local_id) const;
-  inline Int getNodePrank(UInt local_id) const;
+  inline NodeFlag getNodeFlag(Idx local_id) const;
+  inline auto getNodePrank(Idx local_id) const;
 
   /// say if a node is a pure ghost node
-  inline bool isPureGhostNode(UInt n) const;
+  inline bool isPureGhostNode(Idx n) const;
 
   /// say if a node is pur local or master node
-  inline bool isLocalOrMasterNode(UInt n) const;
+  inline bool isLocalOrMasterNode(Idx n) const;
 
-  inline bool isLocalNode(UInt n) const;
-  inline bool isMasterNode(UInt n) const;
-  inline bool isSlaveNode(UInt n) const;
+  inline bool isLocalNode(Idx n) const;
+  inline bool isMasterNode(Idx n) const;
+  inline bool isSlaveNode(Idx n) const;
 
-  inline bool isPeriodicSlave(UInt n) const;
-  inline bool isPeriodicMaster(UInt n) const;
+  inline bool isPeriodicSlave(Idx n) const;
+  inline bool isPeriodicMaster(Idx n) const;
 
   const Vector<Real> & getLowerBounds() const { return bbox.getLowerBounds(); }
   const Vector<Real> & getUpperBounds() const { return bbox.getUpperBounds(); }
   AKANTU_GET_MACRO(BBox, bbox, const BBox &);
 
   const Vector<Real> & getLocalLowerBounds() const {
     return bbox_local.getLowerBounds();
   }
   const Vector<Real> & getLocalUpperBounds() const {
     return bbox_local.getUpperBounds();
   }
   AKANTU_GET_MACRO(LocalBBox, bbox_local, const BBox &);
 
   /// 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_BY_ELEMENT_TYPE_CONST(Connectivity, connectivities, Idx);
+  AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Connectivity, connectivities, Idx);
   AKANTU_GET_MACRO(Connectivities, connectivities,
-                   const ElementTypeMapArray<UInt> &);
+                   const ElementTypeMapArray<Idx> &);
 
   /// get the number of element of a type in the mesh
-  inline UInt getNbElement(ElementType type,
-                           GhostType ghost_type = _not_ghost) const;
+  inline auto 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(UInt spatial_dimension = _all_dimensions,
-                           GhostType ghost_type = _not_ghost,
-                           ElementKind kind = _ek_not_defined) const;
+  inline auto getNbElement(const Int spatial_dimension = _all_dimensions,
+                           const GhostType & ghost_type = _not_ghost,
+                           const ElementKind & kind = _ek_not_defined) const;
 
   /// compute the barycenter of a given element
   inline void getBarycenter(const Element & element,
                             Vector<Real> & barycenter) const;
 
   void getBarycenters(Array<Real> & barycenter, ElementType type,
                       GhostType ghost_type) const;
 
   /// get the element connected to a subelement (element of lower dimension)
   const auto & getElementToSubelement() const;
 
   /// get the element connected to a subelement
   const auto & getElementToSubelement(ElementType el_type,
                                       GhostType ghost_type = _not_ghost) const;
 
   /// get the elements connected to a subelement
   const auto & getElementToSubelement(const Element & element) const;
 
   /// get the subelement (element of lower dimension) connected to a element
   const auto & getSubelementToElement() const;
 
   /// get the subelement connected to an element
   const auto & getSubelementToElement(ElementType el_type,
                                       GhostType ghost_type = _not_ghost) const;
 
   /// get the subelement (element of lower dimension) connected to a element
   decltype(auto) getSubelementToElement(const Element & element) const;
 
   /// get connectivity of a given element
   inline decltype(auto) getConnectivity(const Element & element) const;
   inline decltype(auto)
   getConnectivityWithPeriodicity(const Element & element) const;
 
 protected:
   /// get the element connected to a subelement (element of lower dimension)
   auto & getElementToSubelementNC();
   auto & getSubelementToElementNC();
   inline auto & getElementToSubelementNC(const Element & element);
   inline decltype(auto) getSubelementToElementNC(const Element & element);
   /// get the element connected to a subelement
   auto & getElementToSubelementNC(ElementType el_type,
                                   GhostType ghost_type = _not_ghost);
   /// get the subelement connected to an element
   auto & getSubelementToElementNC(ElementType el_type,
                                   GhostType ghost_type = _not_ghost);
 
   inline decltype(auto) getConnectivityNC(const Element & element);
 
 public:
   /// get a name field associated to the mesh
   template <typename T>
   inline const Array<T> & getData(const ID & data_name, ElementType el_type,
                                   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, ElementType el_type,
                             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);
 
   template <typename T>
   std::shared_ptr<dumpers::Field>
   createFieldFromAttachedData(const std::string & field_id,
                               const std::string & group_name,
                               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, ElementType el_type,
-                 GhostType ghost_type = _not_ghost, UInt nb_component = 1,
-                 bool size_to_nb_element = true,
+  getDataPointer(const std::string & data_name, const ElementType & el_type,
+                 const GhostType & ghost_type = _not_ghost,
+                 Int nb_component = 1, bool size_to_nb_element = true,
                  bool resize_with_parent = false);
 
   template <typename T>
-  inline Array<T> & getDataPointer(const ID & data_name, ElementType el_type,
-                                   GhostType ghost_type, UInt nb_component,
-                                   bool size_to_nb_element,
+  inline Array<T> & getDataPointer(const ID & data_name,
+                                   const ElementType & el_type,
+                                   const GhostType & ghost_type,
+                                   Int nb_component, bool size_to_nb_element,
                                    bool resize_with_parent, const T & defaul_);
 
   /// Facets mesh accessor
   inline const Mesh & getMeshFacets() const;
   inline Mesh & getMeshFacets();
 
   inline auto hasMeshFacets() const { return mesh_facets != nullptr; }
 
   /// Parent mesh accessor
   inline const Mesh & getMeshParent() const;
 
-  inline bool isMeshFacets() const { return this->is_mesh_facets; }
+  inline auto isMeshFacets() const { return this->is_mesh_facets; }
 
   /// return the dumper from a group and and a dumper name
   DumperIOHelper & getGroupDumper(const std::string & dumper_name,
                                   const std::string & group_name);
 
   /* ------------------------------------------------------------------------ */
   /* Wrappers on ElementClass functions                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the number of nodes per element for a given element type
-  static inline UInt getNbNodesPerElement(ElementType type);
+  static inline auto 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(ElementType type);
+  static inline auto getP1ElementType(const ElementType & type);
 
   /// get the kind of the element type
-  static inline ElementKind getKind(ElementType type);
+  static inline auto getKind(const ElementType & type);
 
   /// get spatial dimension of a type of element
-  static inline UInt getSpatialDimension(ElementType type);
-
-  /// get the natural space dimension of a type of element
-  static inline UInt getNaturalSpaceDimension(const ElementType & type);
+  static inline auto getSpatialDimension(const ElementType & type);
 
   /// get number of facets of a given element type
-  static inline UInt getNbFacetsPerElement(ElementType type);
+  static inline auto getNbFacetsPerElement(const ElementType & type);
 
   /// get number of facets of a given element type
-  static inline UInt getNbFacetsPerElement(ElementType type, UInt t);
+  static inline auto getNbFacetsPerElement(const ElementType & type, Idx t);
 
   /// get local connectivity of a facet for a given facet type
-  static inline decltype(auto) getFacetLocalConnectivity(ElementType type,
-                                                         UInt t = 0);
+  static inline decltype(auto)
+  getFacetLocalConnectivity(const ElementType & type, Idx t = 0);
 
   /// get connectivity of facets for a given element
   inline decltype(auto) getFacetConnectivity(const Element & element,
-                                             UInt t = 0) const;
+                                             Idx t = 0) const;
 
   /// get the number of type of the surface element associated to a given
   /// element type
-  static inline UInt getNbFacetTypes(ElementType type, UInt t = 0);
+  static inline auto getNbFacetTypes(const ElementType & type, Idx t = 0);
 
   /// get the type of the surface element associated to a given element
-  static inline constexpr auto getFacetType(ElementType type, UInt t = 0);
+  static inline auto getFacetType(const ElementType & type, Idx t = 0);
 
   /// get all the type of the surface element associated to a given element
   static inline decltype(auto) getAllFacetTypes(ElementType type);
 
   /// get the number of nodes in the given element list
-  static inline UInt getNbNodesPerElementList(const Array<Element> & elements);
+  static inline auto getNbNodesPerElementList(const Array<Element> & elements);
 
   /* ------------------------------------------------------------------------ */
   /* Element type Iterator                                                    */
   /* ------------------------------------------------------------------------ */
 
-  using type_iterator = ElementTypeMapArray<UInt, ElementType>::type_iterator;
+  using type_iterator [[deprecated]] =
+      ElementTypeMapArray<Idx, ElementType>::type_iterator;
   using ElementTypesIteratorHelper =
-      ElementTypeMapArray<UInt, ElementType>::ElementTypesIteratorHelper;
+      ElementTypeMapArray<Idx, ElementType>::ElementTypesIteratorHelper;
 
   template <typename... pack>
   ElementTypesIteratorHelper elementTypes(pack &&... _pack) const;
 
   [[deprecated("Use elementTypes instead")]] inline decltype(auto)
-  firstType(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
+  firstType(Int dim = _all_dimensions, GhostType ghost_type = _not_ghost,
             ElementKind kind = _ek_regular) const {
     return connectivities.elementTypes(dim, ghost_type, kind).begin();
   }
 
   [[deprecated("Use elementTypes instead")]] inline decltype(auto)
-  lastType(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
+  lastType(Int dim = _all_dimensions, GhostType ghost_type = _not_ghost,
            ElementKind kind = _ek_regular) const {
     return connectivities.elementTypes(dim, ghost_type, kind).end();
   }
 
-  AKANTU_GET_MACRO(ElementSynchronizer, *element_synchronizer,
-                   const ElementSynchronizer &);
+  AKANTU_GET_MACRO_AUTO(ElementSynchronizer, *element_synchronizer);
   AKANTU_GET_MACRO_NOT_CONST(ElementSynchronizer, *element_synchronizer,
                              ElementSynchronizer &);
-  AKANTU_GET_MACRO(NodeSynchronizer, *node_synchronizer,
-                   const NodeSynchronizer &);
+  AKANTU_GET_MACRO_AUTO(NodeSynchronizer, *node_synchronizer);
   AKANTU_GET_MACRO_NOT_CONST(NodeSynchronizer, *node_synchronizer,
                              NodeSynchronizer &);
-  AKANTU_GET_MACRO(PeriodicNodeSynchronizer, *periodic_node_synchronizer,
-                   const PeriodicNodeSynchronizer &);
+  AKANTU_GET_MACRO_AUTO(PeriodicNodeSynchronizer, *periodic_node_synchronizer);
   AKANTU_GET_MACRO_NOT_CONST(PeriodicNodeSynchronizer,
                              *periodic_node_synchronizer,
                              PeriodicNodeSynchronizer &);
 
   // AKANTU_GET_MACRO_NOT_CONST(Communicator, *communicator, StaticCommunicator
   // &);
-  AKANTU_GET_MACRO(Communicator, *communicator, const auto &);
-  AKANTU_GET_MACRO_NOT_CONST(Communicator, *communicator, auto &);
-  AKANTU_GET_MACRO(PeriodicMasterSlaves, periodic_master_slave, const auto &);
+  AKANTU_GET_MACRO_AUTO(Communicator, communicator);
+  AKANTU_GET_MACRO_NOT_CONST(Communicator, communicator, auto &);
+  AKANTU_GET_MACRO_AUTO(PeriodicMasterSlaves, periodic_master_slave);
 
   /* ------------------------------------------------------------------------ */
   /* Private methods for friends                                              */
   /* ------------------------------------------------------------------------ */
 private:
   friend class MeshAccessor;
   friend class MeshUtils;
 
   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();
+  inline Array<Idx> & getNodesGlobalIdsPointer();
 
   /// get a pointer to the nodes_type Array<Int> and create it if necessary
   inline Array<NodeFlag> & getNodesFlagsPointer();
 
   /// get a pointer to the connectivity Array for the given type and create it
   /// if necessary
-  inline Array<UInt> &
-  getConnectivityPointer(ElementType type, GhostType ghost_type = _not_ghost);
+  inline Array<Idx> &
+  getConnectivityPointer(const ElementType & type,
+                         const GhostType & ghost_type = _not_ghost);
 
   /// get the ghost element counter
-  inline Array<UInt> & getGhostsCounters(ElementType type,
-                                         GhostType ghost_type = _ghost) {
+  inline Array<Idx> & 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(ElementType type,
                                 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(ElementType type,
                                 GhostType ghost_type = _not_ghost);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   ID id;
 
   /// array of the nodes coordinates
   std::shared_ptr<Array<Real>> nodes;
 
   /// global node ids
-  std::shared_ptr<Array<UInt>> nodes_global_ids;
+  std::shared_ptr<Array<Idx>> nodes_global_ids;
 
   /// node flags (shared/periodic/...)
   std::shared_ptr<Array<NodeFlag>> nodes_flags;
 
   /// processor handling the node when not local or master
-  std::unordered_map<UInt, Int> nodes_prank;
+  std::unordered_map<Idx, Int> nodes_prank;
 
   /// global number of nodes;
   UInt nb_global_nodes{0};
 
   /// all class of elements present in this mesh (for heterogenous meshes)
-  ElementTypeMapArray<UInt> connectivities;
+  ElementTypeMapArray<Idx> connectivities;
 
   /// count the references on ghost elements
-  ElementTypeMapArray<UInt> ghosts_counters;
+  ElementTypeMapArray<Idx> ghosts_counters;
 
   /// the spatial dimension of this mesh
-  UInt spatial_dimension{0};
+  Idx spatial_dimension{0};
 
   /// size covered by the mesh on each direction
   Vector<Real> size;
   /// global bounding box
   BBox bbox;
 
   /// local bounding box
   BBox bbox_local;
 
   /// 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};
 
   /// defines if the mesh is periodic
   bool is_periodic{false};
 
   /// Communicator on which mesh is distributed
-  Communicator * communicator;
+  Communicator & communicator;
 
   /// Element synchronizer
   std::unique_ptr<ElementSynchronizer> element_synchronizer;
 
   /// Node synchronizer
   std::unique_ptr<NodeSynchronizer> node_synchronizer;
 
   /// Node synchronizer for periodic nodes
   std::unique_ptr<PeriodicNodeSynchronizer> periodic_node_synchronizer;
 
   using NodesToElements = std::vector<std::unique_ptr<std::set<Element>>>;
 
   /// class to update global data using external knowledge
   std::unique_ptr<MeshGlobalDataUpdater> global_data_updater;
 
   /// This info is stored to simplify the dynamic changes
   NodesToElements nodes_to_elements;
 
   /// periodicity local info
-  std::unordered_map<UInt, UInt> periodic_slave_master;
-  std::unordered_multimap<UInt, UInt> periodic_master_slave;
+  std::unordered_map<Idx, Idx> periodic_slave_master;
+  std::unordered_multimap<Idx, Idx> periodic_master_slave;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream, const Mesh & _this) {
   _this.printself(stream);
   return stream;
 }
 
+/* -------------------------------------------------------------------------- */
+inline auto Mesh::getNbNodesPerElement(const ElementType & type) {
+  Int 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 auto Mesh::getNbElement(const ElementType & type,
+                              const GhostType & ghost_type) const {
+  try {
+    const auto & conn = connectivities(type, ghost_type);
+    return conn.size();
+  } catch (...) {
+    return 0;
+  }
+}
+
+/* -------------------------------------------------------------------------- */
+inline auto Mesh::getNbElement(const Int spatial_dimension,
+                               const GhostType & ghost_type,
+                               const ElementKind & kind) const {
+  AKANTU_DEBUG_ASSERT(spatial_dimension <= 3 || spatial_dimension == Int(-1),
+                      "spatial_dimension is " << spatial_dimension
+                                              << " and is greater than 3 !");
+  Int nb_element = 0;
+
+  for (auto type : elementTypes(spatial_dimension, ghost_type, kind))
+    nb_element += getNbElement(type, ghost_type);
+
+  return nb_element;
+}
+/* -------------------------------------------------------------------------- */
+
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* Inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "element_type_map_tmpl.hh"
 #include "mesh_inline_impl.hh"
 
 #endif /* AKANTU_MESH_HH_ */
diff --git a/src/mesh/mesh_accessor.hh b/src/mesh/mesh_accessor.hh
index 0eff39457..8382669b2 100644
--- a/src/mesh/mesh_accessor.hh
+++ b/src/mesh/mesh_accessor.hh
@@ -1,221 +1,221 @@
 /**
  * @file   mesh_accessor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jun 30 2015
  * @date last modification: Tue Feb 09 2021
  *
  * @brief  this class allow to access some private member of mesh it is used for
  * IO for examples
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MESH_ACCESSOR_HH_
 #define AKANTU_MESH_ACCESSOR_HH_
 
 namespace akantu {
 class NodeSynchronizer;
 class ElementSynchronizer;
 class MeshGlobalDataUpdater;
 } // namespace akantu
 
 namespace akantu {
 
 class MeshAccessor {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   explicit MeshAccessor(Mesh & mesh) : _mesh(mesh) {}
   virtual ~MeshAccessor() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the global number of nodes
   inline UInt getNbGlobalNodes() const { return this->_mesh.nb_global_nodes; }
 
   /// set the global number of nodes
-  inline void setNbGlobalNodes(UInt nb_global_nodes) {
+  inline void setNbGlobalNodes(Int nb_global_nodes) {
     this->_mesh.nb_global_nodes = nb_global_nodes;
   }
 
   /// set the mesh as being distributed
   inline void setDistributed() { this->_mesh.is_distributed = true; }
 
   /// get a pointer to the nodes_global_ids Array<UInt> and create it if
   /// necessary
   inline auto & getNodesGlobalIds() {
     return this->_mesh.getNodesGlobalIdsPointer();
   }
 
   /// get a pointer to the nodes_type Array<Int> and create it if necessary
   inline auto & getNodesFlags() { return this->_mesh.getNodesFlags(); }
 
   /// get a pointer to the nodes_type Array<Int> and create it if necessary
   inline void setNodePrank(UInt node, Int prank) {
     this->_mesh.nodes_prank[node] = prank;
   }
 
   /// get a pointer to the coordinates Array
   inline auto & getNodes() { return this->_mesh.getNodesPointer(); }
 
   /// get a pointer to the coordinates Array
   inline auto getNodesSharedPtr() { return this->_mesh.nodes; }
 
   /// get the connectivities
   inline auto & getConnectivities() { return this->_mesh.connectivities; }
 
   /// get the connectivity Array for the given type and create it
   /// if necessary
   inline auto & getConnectivity(ElementType type,
                                 GhostType ghost_type = _not_ghost) {
     return this->_mesh.getConnectivityPointer(type, ghost_type);
   }
 
   /// resize the connectivity (use carefully)
   inline void resizeConnectivity(UInt new_size, ElementType type,
                                  GhostType ghost_type = _not_ghost) {
     this->getConnectivity(type, ghost_type).resize(new_size, UInt(-1));
   }
 
   /// resize the nodes (use carefully)
   inline void resizeNodes(UInt new_size) {
     this->getNodes().resize(new_size, UInt(-1));
   }
 
   /// get the connectivity for the given element
   inline decltype(auto) getConnectivity(const Element & element) {
     return this->_mesh.getConnectivityNC(element);
   }
 
   /// get the ghost element counter
   inline auto & getGhostsCounters(ElementType type,
                                   GhostType ghost_type = _ghost) {
     return this->_mesh.getGhostsCounters(type, ghost_type);
   }
 
   /// get the element_to_subelement Array for the given type and
   /// create it if necessary
   inline auto & getElementToSubelement(ElementType type,
                                        GhostType ghost_type = _not_ghost) {
     return this->_mesh.getElementToSubelementPointer(type, ghost_type);
   }
 
   inline decltype(auto)
   getElementToSubelementNC(const ElementType & type,
                            const GhostType & ghost_type = _not_ghost) {
     return this->_mesh.getElementToSubelementNC(type, ghost_type);
   }
 
   /// get the subelement_to_element Array for the given type and
   /// create it if necessary
   inline auto & getSubelementToElement(ElementType type,
                                        GhostType ghost_type = _not_ghost) {
     return this->_mesh.getSubelementToElementPointer(type, ghost_type);
   }
 
   inline decltype(auto)
   getSubelementToElementNC(const ElementType & type,
                            const GhostType & ghost_type = _not_ghost) {
     return this->_mesh.getSubelementToElementNC(type, ghost_type);
   }
 
   /// get  the element_to_subelement, creates it if necessary
   inline decltype(auto) getElementToSubelement() {
     return this->_mesh.getElementToSubelementNC();
   }
 
   /// get subelement_to_element, creates it if necessary
   inline decltype(auto) getSubelementToElement() {
     return this->_mesh.getSubelementToElementNC();
   }
 
   /// get a pointer to the element_to_subelement Array for element and
   /// create it if necessary
   inline decltype(auto) getElementToSubelement(const Element & element) {
     return this->_mesh.getElementToSubelementNC(element);
   }
 
   /// get a pointer to the subelement_to_element Array for the given element and
   /// create it if necessary
   inline decltype(auto) getSubelementToElement(const Element & element) {
     return this->_mesh.getSubelementToElementNC(element);
   }
 
   template <typename T>
-  inline auto & getData(const std::string & data_name, ElementType el_type,
-                        GhostType ghost_type = _not_ghost,
-                        UInt nb_component = 1, bool size_to_nb_element = true,
-                        bool resize_with_parent = false) {
+  inline auto &
+  getData(const std::string & data_name, const ElementType & el_type,
+          const GhostType & ghost_type = _not_ghost, Int nb_component = 1,
+          bool size_to_nb_element = true, bool resize_with_parent = false) {
     return this->_mesh.getDataPointer<T>(data_name, el_type, ghost_type,
                                          nb_component, size_to_nb_element,
                                          resize_with_parent);
   }
 
   /// get the node synchonizer
   auto & getNodeSynchronizer() { return *this->_mesh.node_synchronizer; }
 
   /// get the element synchonizer
   auto & getElementSynchronizer() { return *this->_mesh.element_synchronizer; }
 
   decltype(auto) updateGlobalData(NewNodesEvent & nodes_event,
                                   NewElementsEvent & elements_event) {
     return this->_mesh.updateGlobalData(nodes_event, elements_event);
   }
 
   void registerGlobalDataUpdater(
       std::unique_ptr<MeshGlobalDataUpdater> && global_data_updater) {
     this->_mesh.registerGlobalDataUpdater(
         std::forward<std::unique_ptr<MeshGlobalDataUpdater>>(
             global_data_updater));
   }
 
   /* ------------------------------------------------------------------------ */
   void makeReady() { this->_mesh.makeReady(); }
 
   /* ------------------------------------------------------------------------ */
-  void addPeriodicSlave(UInt slave, UInt master) {
+  void addPeriodicSlave(Idx slave, Idx master) {
     this->_mesh.addPeriodicSlave(slave, master);
   }
 
   void markMeshPeriodic() {
-    for (UInt s : arange(this->_mesh.spatial_dimension)) {
+    for (Idx s : arange(this->_mesh.spatial_dimension)) {
       this->_mesh.is_periodic |= 1 << s;
     }
   }
 
   void wipePeriodicInfo() { this->_mesh.wipePeriodicInfo(); }
 
 private:
   Mesh & _mesh;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MESH_ACCESSOR_HH_ */
diff --git a/src/mesh/mesh_events.hh b/src/mesh/mesh_events.hh
index eced63fb7..09248f7b8 100644
--- a/src/mesh/mesh_events.hh
+++ b/src/mesh/mesh_events.hh
@@ -1,204 +1,204 @@
 /**
  * @file   mesh_events.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Feb 20 2015
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Classes corresponding to mesh events type
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 <utility>
 
 #include "aka_array.hh"
 #include "element.hh"
 #include "element_type_map.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MESH_EVENTS_HH_
 #define AKANTU_MESH_EVENTS_HH_
 
 namespace akantu {
 
 /// akantu::MeshEvent is the base event for meshes
 template <class Entity> class MeshEvent {
 public:
   MeshEvent(const std::string & origin = "") : origin_(origin) {}
 
   virtual ~MeshEvent() = default;
   /// Get the list of entity modified by the event nodes or elements
   const Array<Entity> & getList() const { return list; }
   /// Get the list of entity modified by the event nodes or elements
   Array<Entity> & getList() { return list; }
 
   std::string origin() const { return origin_; }
   
 protected:
   Array<Entity> list;
 
 private:
   std::string origin_;
 };
 
 class Mesh;
 
 /// akantu::MeshEvent related to new nodes in the mesh
-class NewNodesEvent : public MeshEvent<UInt> {
+class NewNodesEvent : public MeshEvent<Idx> {
 public:
   NewNodesEvent(const std::string & origin = "") : MeshEvent(origin) {}
   ~NewNodesEvent() override = default;
 };
 
 /// akantu::MeshEvent related to nodes removed from the mesh
-class RemovedNodesEvent : public MeshEvent<UInt> {
+class RemovedNodesEvent : public MeshEvent<Idx> {
 public:
   inline RemovedNodesEvent(const Mesh & mesh, const std::string & origin = "");
 
   ~RemovedNodesEvent() override = default;
   /// Get the new numbering following suppression of nodes from nodes arrays
-  AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, Array<UInt> &);
+  AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering, auto &);
   /// Get the new numbering following suppression of nodes from nodes arrays
-  AKANTU_GET_MACRO(NewNumbering, new_numbering, const Array<UInt> &);
+  AKANTU_GET_MACRO(NewNumbering, new_numbering, const auto &);
 
 private:
-  Array<UInt> new_numbering;
+  Array<Idx> new_numbering;
 };
 
 /// akantu::MeshEvent related to new elements in the mesh
 class NewElementsEvent : public MeshEvent<Element> {
 public:
   NewElementsEvent(const std::string & origin = "") : MeshEvent<Element>(origin) {}
   ~NewElementsEvent() override = default;
 };
 
 /// akantu::MeshEvent related to elements removed from the mesh
 class RemovedElementsEvent : public MeshEvent<Element> {
 public:
   inline RemovedElementsEvent(const Mesh & mesh,
                               const ID & new_numbering_id = "new_numbering",
                               const std::string & origin = "");
 
   ~RemovedElementsEvent() override = default;
 
   /// Get the new numbering following suppression of elements from elements
   /// arrays
   AKANTU_GET_MACRO(NewNumbering, new_numbering,
-                   const ElementTypeMapArray<UInt> &);
+                   const auto &);
   /// Get the new numbering following suppression of elements from elements
   /// arrays
   AKANTU_GET_MACRO_NOT_CONST(NewNumbering, new_numbering,
-                             ElementTypeMapArray<UInt> &);
+                             auto &);
   /// Get the new numbering following suppression of elements from elements
   /// arrays
-  AKANTU_GET_MACRO_BY_ELEMENT_TYPE(NewNumbering, new_numbering, UInt);
+  AKANTU_GET_MACRO_BY_ELEMENT_TYPE(NewNumbering, new_numbering, Idx);
   /// Get the new numbering following suppression of elements from elements
   /// arrays
-  AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NewNumbering, new_numbering, UInt);
+  AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(NewNumbering, new_numbering, Idx);
 
 protected:
-  ElementTypeMapArray<UInt> new_numbering;
+  ElementTypeMapArray<Idx> 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:
   inline ChangedElementsEvent(
       const Mesh & mesh, const ID & new_numbering_id = "changed_event:new_numbering",
       const std::string & origin = "")
       : RemovedElementsEvent(mesh, new_numbering_id, origin) {}
 
   ~ChangedElementsEvent() override = default;
   AKANTU_GET_MACRO(ListOld, list, const Array<Element> &);
   AKANTU_GET_MACRO_NOT_CONST(ListOld, list, Array<Element> &);
   AKANTU_GET_MACRO(ListNew, new_list, const Array<Element> &);
   AKANTU_GET_MACRO_NOT_CONST(ListNew, new_list, Array<Element> &);
 
 protected:
   Array<Element> new_list;
 };
 
 /* -------------------------------------------------------------------------- */
 
 class MeshEventHandler {
 public:
   virtual ~MeshEventHandler() = default;
   /* ------------------------------------------------------------------------ */
   /* Internal code                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// send a akantu::NewNodesEvent
   inline void sendEvent(const NewNodesEvent & event) {
     onNodesAdded(event.getList(), event);
   }
   /// send a akantu::RemovedNodesEvent
   inline void sendEvent(const RemovedNodesEvent & event) {
     onNodesRemoved(event.getList(), event.getNewNumbering(), event);
   }
   /// send a akantu::NewElementsEvent
   inline void sendEvent(const NewElementsEvent & event) {
     onElementsAdded(event.getList(), event);
   }
   /// send a akantu::RemovedElementsEvent
   inline void sendEvent(const RemovedElementsEvent & event) {
     onElementsRemoved(event.getList(), event.getNewNumbering(), event);
   }
   /// send a akantu::ChangedElementsEvent
   inline void sendEvent(const ChangedElementsEvent & event) {
     onElementsChanged(event.getListOld(), event.getListNew(),
                       event.getNewNumbering(), event);
   }
   template <class EventHandler> friend class EventHandlerManager;
 
   /* ------------------------------------------------------------------------ */
   /* Interface                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// function to implement to react on  akantu::NewNodesEvent
-  virtual void onNodesAdded(const Array<UInt> & /*nodes_list*/,
+  virtual void onNodesAdded(const Array<Idx> & /*nodes_list*/,
                             const NewNodesEvent & /*event*/) {}
   /// function to implement to react on  akantu::RemovedNodesEvent
-  virtual void onNodesRemoved(const Array<UInt> & /*nodes_list*/,
-                              const Array<UInt> & /*new_numbering*/,
+  virtual void onNodesRemoved(const Array<Idx> & /*nodes_list*/,
+                              const Array<Idx> & /*new_numbering*/,
                               const RemovedNodesEvent & /*event*/) {}
   /// function to implement to react on  akantu::NewElementsEvent
   virtual void onElementsAdded(const Array<Element> & /*elements_list*/,
                                const NewElementsEvent & /*event*/) {}
   /// function to implement to react on  akantu::RemovedElementsEvent
   virtual void
   onElementsRemoved(const Array<Element> & /*elements_list*/,
-                    const ElementTypeMapArray<UInt> & /*new_numbering*/,
+                    const ElementTypeMapArray<Idx> & /*new_numbering*/,
                     const RemovedElementsEvent & /*event*/) {}
   /// 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 ElementTypeMapArray<Idx> & /*new_numbering*/,
                     const ChangedElementsEvent & /*event*/) {}
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MESH_EVENTS_HH_ */
diff --git a/src/mesh/mesh_inline_impl.hh b/src/mesh/mesh_inline_impl.hh
index bb2d7a895..7c72a528c 100644
--- a/src/mesh/mesh_inline_impl.hh
+++ b/src/mesh/mesh_inline_impl.hh
@@ -1,788 +1,825 @@
 /**
  * @file   mesh_inline_impl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author Mohit Pundir <mohit.pundir@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: Fri Dec 11 2020
  *
  * @brief  Implementation of the inline functions of the mesh class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "element_class.hh"
-#include "mesh.hh"
+//#include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MESH_INLINE_IMPL_HH_
 #define AKANTU_MESH_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+inline auto 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 ElementKind Element::kind() const { return Mesh::getKind(type); }
 
 /* -------------------------------------------------------------------------- */
+inline auto Mesh::getNbFacetsPerElement(const ElementType & type) {
+  AKANTU_DEBUG_IN();
+
+  Int 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 auto Mesh::getNbFacetsPerElement(const ElementType & type, Idx t) {
+  AKANTU_DEBUG_IN();
+
+  Int 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;
+}
+
 /* -------------------------------------------------------------------------- */
 template <typename... pack>
 Mesh::ElementTypesIteratorHelper Mesh::elementTypes(pack &&... _pack) const {
   return connectivities.elementTypes(_pack...);
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto) Mesh::getConnectivity(const Element & element) const {
   const auto & conn = connectivities(element.type, element.ghost_type);
   auto it = conn.begin(conn.getNbComponent());
   return it[element.element];
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto) Mesh::getConnectivity(const Element & element) {
   auto & conn = connectivities(element.type, element.ghost_type);
   auto it = conn.begin(conn.getNbComponent());
   return it[element.element];
 }
 
 /* -------------------------------------------------------------------------- */
 inline RemovedNodesEvent::RemovedNodesEvent(const Mesh & mesh,
                                             const std::string & origin)
-    : MeshEvent<UInt>(origin),
+    : MeshEvent<Idx>(origin),
       new_numbering(mesh.getNbNodes(), 1, "new_numbering") {}
 
 /* -------------------------------------------------------------------------- */
 inline RemovedElementsEvent::RemovedElementsEvent(const Mesh & mesh,
                                                   const ID & new_numbering_id,
                                                   const std::string & origin)
     : MeshEvent<Element>(origin),
       new_numbering(new_numbering_id, mesh.getID()) {}
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Mesh::sendEvent<NewElementsEvent>(NewElementsEvent & event) {
   this->fillNodesToElements();
   EventHandlerManager<MeshEventHandler>::sendEvent(event);
 }
 
 /* -------------------------------------------------------------------------- */
 template <> inline void Mesh::sendEvent<NewNodesEvent>(NewNodesEvent & event) {
   this->computeBoundingBox();
   this->nodes_flags->resize(this->nodes->size(), NodeFlag::_normal);
   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 and not is_mesh_facets) {
     this->removeNodesFromArray(*nodes_global_ids, new_numbering);
   }
   if (not is_mesh_facets) {
     this->removeNodesFromArray(*nodes_flags, 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)) {
+      if (new_i != Int(-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) {
+                                       const Array<Idx> & 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)) {
+  auto nb_component = vect.getNbComponent();
+  auto new_nb_nodes = 0;
+  for (Int i = 0; i < new_numbering.size(); ++i) {
+    auto new_i = new_numbering(i);
+    if (new_i != Int(-1)) {
       T * to_copy = vect.data() + i * nb_component;
       std::uninitialized_copy(to_copy, to_copy + nb_component,
                               tmp.data() + new_i * nb_component);
       ++new_nb_nodes;
     }
   }
 
   tmp.resize(new_nb_nodes);
   vect.copy(tmp);
 }
 
 /* -------------------------------------------------------------------------- */
-inline Array<UInt> & Mesh::getNodesGlobalIdsPointer() {
+inline Array<Idx> & Mesh::getNodesGlobalIdsPointer() {
   AKANTU_DEBUG_IN();
   if (not nodes_global_ids) {
-    nodes_global_ids = std::make_shared<Array<UInt>>(
+    nodes_global_ids = std::make_shared<Array<Idx>>(
         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<UInt> & Mesh::getConnectivityPointer(ElementType type,
-                                                  GhostType ghost_type) {
+inline Array<Idx> & 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(ElementType type, GhostType ghost_type) {
   return getDataPointer<std::vector<Element>>("element_to_subelement", type,
                                               ghost_type, 1, true);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Element> &
 Mesh::getSubelementToElementPointer(ElementType type, GhostType ghost_type) {
   auto & array = getDataPointer<Element>(
       "subelement_to_element", type, ghost_type, getNbFacetsPerElement(type),
       false, is_mesh_facets, ElementNull);
   return array;
 }
 
 /* -------------------------------------------------------------------------- */
 inline const auto & Mesh::getElementToSubelement() const {
   return getData<std::vector<Element>>("element_to_subelement");
 }
 
 /* -------------------------------------------------------------------------- */
 inline auto & Mesh::getElementToSubelementNC() {
   return getData<std::vector<Element>>("element_to_subelement");
 }
 
 /* -------------------------------------------------------------------------- */
 inline const auto & Mesh::getElementToSubelement(ElementType type,
                                                  GhostType ghost_type) const {
   return getData<std::vector<Element>>("element_to_subelement", type,
                                        ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline auto & Mesh::getElementToSubelementNC(ElementType type,
                                              GhostType ghost_type) {
   return getData<std::vector<Element>>("element_to_subelement", type,
                                        ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const auto &
 Mesh::getElementToSubelement(const Element & element) const {
   return getData<std::vector<Element>>("element_to_subelement")(element, 0);
 }
 
 /* -------------------------------------------------------------------------- */
 inline auto & Mesh::getElementToSubelementNC(const Element & element) {
   return getData<std::vector<Element>>("element_to_subelement")(element, 0);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const auto & Mesh::getSubelementToElement() const {
   return getData<Element>("subelement_to_element");
 }
 
 /* -------------------------------------------------------------------------- */
 inline auto & Mesh::getSubelementToElementNC() {
   return getData<Element>("subelement_to_element");
 }
 
 /* -------------------------------------------------------------------------- */
 inline const auto & Mesh::getSubelementToElement(ElementType type,
                                                  GhostType ghost_type) const {
   return getData<Element>("subelement_to_element", type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline auto & Mesh::getSubelementToElementNC(ElementType type,
                                              GhostType ghost_type) {
   return getData<Element>("subelement_to_element", type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto)
 Mesh::getSubelementToElement(const Element & element) const {
   return this->getSubelementToElement().get(element);
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto)
 Mesh::getSubelementToElementNC(const Element & element) {
   return this->getSubelementToElement().get(element);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline Array<T> &
-Mesh::getDataPointer(const ID & data_name, ElementType el_type,
-                     GhostType ghost_type, UInt nb_component,
+Mesh::getDataPointer(const ID & data_name, const ElementType & el_type,
+                     const GhostType & ghost_type, Int nb_component,
                      bool size_to_nb_element, bool resize_with_parent) {
   Array<T> & tmp = this->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));
     }
   }
 
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline Array<T> &
-Mesh::getDataPointer(const ID & data_name, ElementType el_type,
-                     GhostType ghost_type, UInt nb_component,
+Mesh::getDataPointer(const ID & data_name, const ElementType & el_type,
+                     const GhostType & ghost_type, Int nb_component,
                      bool size_to_nb_element, bool resize_with_parent,
                      const T & defaul_) {
   Array<T> & tmp = this->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), defaul_);
     } else {
       tmp.resize(this->getNbElement(el_type, ghost_type), defaul_);
     }
   }
 
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline const Array<T> & Mesh::getData(const ID & data_name, ElementType el_type,
                                       GhostType ghost_type) const {
   return this->getElementalDataArray<T>(data_name, el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline Array<T> & Mesh::getData(const ID & data_name, ElementType el_type,
                                 GhostType ghost_type) {
   return this->getElementalDataArray<T>(data_name, el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline const ElementTypeMapArray<T> &
 Mesh::getData(const ID & data_name) const {
   return this->getElementalData<T>(data_name);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline ElementTypeMapArray<T> & Mesh::getData(const ID & data_name) {
   return this->getElementalData<T>(data_name);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbElement(ElementType type, 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,
                                GhostType ghost_type, 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(const Element & element,
-                                Vector<Real> & barycenter) const {
+                                VectorProxy<Real> & barycenter) const {
   auto && conn = getConnectivity(element);
   Matrix<Real> local_coord(spatial_dimension, conn.size());
   auto node_begin = make_view(*nodes, spatial_dimension).begin();
 
   for (auto && data : enumerate(conn)) {
     local_coord(std::get<0>(data)) = node_begin[std::get<1>(data)];
   }
 
   Math::barycenter(local_coord.data(), conn.size(), spatial_dimension,
                    barycenter.data());
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbNodesPerElement(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(ElementType type) {
+inline auto 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(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(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::getNaturalSpaceDimension(const ElementType & type) {
   UInt natural_dimension = 0;
 #define GET_NATURAL_DIMENSION(type)                                            \
   natural_dimension = ElementClass<type>::getNaturalSpaceDimension()
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NATURAL_DIMENSION);
 #undef GET_NATURAL_DIMENSION
 
   return natural_dimension;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbFacetTypes(ElementType type, UInt /*t*/) {
   UInt nb = 0;
 #define GET_NB_FACET_TYPE(type) nb = ElementClass<type>::getNbFacetTypes()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET_TYPE);
 #undef GET_NB_FACET_TYPE
   return nb;
 }
 
 /* -------------------------------------------------------------------------- */
-inline constexpr auto Mesh::getFacetType(ElementType type, UInt t) {
+inline auto Mesh::getFacetType(const ElementType & type, Idx t) {
 #define GET_FACET_TYPE(type) return ElementClass<type>::getFacetType(t);
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH_NO_DEFAULT(GET_FACET_TYPE);
 
 #undef GET_FACET_TYPE
 
   return _not_defined;
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto) Mesh::getAllFacetTypes(ElementType type) {
 #define GET_FACET_TYPE(type)                                                   \
   {                                                                            \
     auto && map = ElementClass<type>::getFacetTypes();                         \
     return Eigen::Map<                                                         \
         const Eigen::Matrix<ElementType, Eigen::Dynamic, Eigen::Dynamic>>(     \
         map.data(), map.rows(), map.cols());                                   \
   }
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH_NO_DEFAULT(GET_FACET_TYPE);
 #undef GET_FACET_TYPE
 
   auto && map = ElementClass<_not_defined>::getFacetTypes();
   return Eigen::Map<
       const Eigen::Matrix<ElementType, Eigen::Dynamic, Eigen::Dynamic>>(
       map.data(), map.rows(), map.cols());
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbFacetsPerElement(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(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 decltype(auto) Mesh::getFacetLocalConnectivity(ElementType type,
                                                       UInt t) {
   AKANTU_DEBUG_IN();
 
 #define GET_FACET_CON(type)                                                    \
   AKANTU_DEBUG_OUT();                                                          \
   return ElementClass<type>::getFacetLocalConnectivityPerElement(t)
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_CON);
 #undef GET_FACET_CON
 
   AKANTU_DEBUG_OUT();
   return ElementClass<_not_defined>::getFacetLocalConnectivityPerElement(0);
   // This avoid a compilation warning but will certainly
   // also cause a segfault if reached
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto) Mesh::getFacetConnectivity(const Element & element,
-                                                 UInt t) const {
+                                                 Idx t) const {
   AKANTU_DEBUG_IN();
 
   auto local_facets = getFacetLocalConnectivity(element.type, t);
-  Matrix<UInt> facets(local_facets.rows(), local_facets.cols());
+  Matrix<Idx> facets(local_facets.rows(), local_facets.cols());
 
-  const Array<UInt> & conn = connectivities(element.type, element.ghost_type);
+  const auto & conn = connectivities(element.type, element.ghost_type);
 
   for (Int f = 0; f < facets.rows(); ++f) {
     for (Int n = 0; n < facets.cols(); ++n) {
       facets(f, n) = conn(element.element, local_facets(f, n));
     }
   }
 
   AKANTU_DEBUG_OUT();
   return facets;
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto) Mesh::getConnectivity(const Element & element) const {
   return connectivities.get(element);
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto) Mesh::getConnectivityNC(const Element & element) {
   return connectivities.get(element);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Mesh::extractNodalValuesFromElement(
-    const Array<T> & nodal_values, T * local_coord, const UInt * connectivity,
-    UInt n_nodes, UInt nb_degree_of_freedom) const {
-  for (UInt n = 0; n < n_nodes; ++n) {
+    const Array<T> & nodal_values, T * local_coord, Int * connectivity,
+    Int n_nodes, Int nb_degree_of_freedom) const {
+  for (Int n = 0; n < n_nodes; ++n) {
     memcpy(local_coord + n * nb_degree_of_freedom,
            nodal_values.data() + connectivity[n] * nb_degree_of_freedom,
            nb_degree_of_freedom * sizeof(T));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Mesh::addConnectivityType(ElementType type, GhostType ghost_type) {
   getConnectivityPointer(type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
-inline bool Mesh::isPureGhostNode(UInt n) const {
+inline bool Mesh::isPureGhostNode(Idx n) const {
   return ((*nodes_flags)(n)&NodeFlag::_shared_mask) == NodeFlag::_pure_ghost;
 }
 
 /* -------------------------------------------------------------------------- */
-inline bool Mesh::isLocalOrMasterNode(UInt n) const {
+inline bool Mesh::isLocalOrMasterNode(Idx n) const {
   return ((*nodes_flags)(n)&NodeFlag::_local_master_mask) == NodeFlag::_normal;
 }
 
 /* -------------------------------------------------------------------------- */
-inline bool Mesh::isLocalNode(UInt n) const {
+inline bool Mesh::isLocalNode(Idx n) const {
   return ((*nodes_flags)(n)&NodeFlag::_shared_mask) == NodeFlag::_normal;
 }
 
 /* -------------------------------------------------------------------------- */
-inline bool Mesh::isMasterNode(UInt n) const {
+inline bool Mesh::isMasterNode(Idx n) const {
   return ((*nodes_flags)(n)&NodeFlag::_shared_mask) == NodeFlag::_master;
 }
 
 /* -------------------------------------------------------------------------- */
-inline bool Mesh::isSlaveNode(UInt n) const {
+inline bool Mesh::isSlaveNode(Idx n) const {
   return ((*nodes_flags)(n)&NodeFlag::_shared_mask) == NodeFlag::_slave;
 }
 
 /* -------------------------------------------------------------------------- */
-inline bool Mesh::isPeriodicSlave(UInt n) const {
+inline bool Mesh::isPeriodicSlave(Idx n) const {
   return ((*nodes_flags)(n)&NodeFlag::_periodic_mask) ==
          NodeFlag::_periodic_slave;
 }
 
 /* -------------------------------------------------------------------------- */
-inline bool Mesh::isPeriodicMaster(UInt n) const {
+inline bool Mesh::isPeriodicMaster(Idx n) const {
   return ((*nodes_flags)(n)&NodeFlag::_periodic_mask) ==
          NodeFlag::_periodic_master;
 }
 
 /* -------------------------------------------------------------------------- */
-inline NodeFlag Mesh::getNodeFlag(UInt local_id) const {
+inline NodeFlag Mesh::getNodeFlag(Idx local_id) const {
   return (*nodes_flags)(local_id);
 }
 
 /* -------------------------------------------------------------------------- */
-inline Int Mesh::getNodePrank(UInt local_id) const {
+inline auto Mesh::getNodePrank(Idx local_id) const {
   auto it = nodes_prank.find(local_id);
   return it == nodes_prank.end() ? -1 : it->second;
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt Mesh::getNodeGlobalId(UInt local_id) const {
+inline auto Mesh::getNodeGlobalId(Idx local_id) const {
   return nodes_global_ids ? (*nodes_global_ids)(local_id) : local_id;
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt Mesh::getNodeLocalId(UInt global_id) const {
+inline auto Mesh::getNodeLocalId(Idx global_id) const {
   if (nodes_global_ids == nullptr) {
     return global_id;
   }
   return nodes_global_ids->find(global_id);
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt Mesh::getNbGlobalNodes() const {
+inline auto 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;
+inline auto Mesh::getNbNodesPerElementList(const Array<Element> & elements) {
+  Int nb_nodes_per_element = 0;
+  Int nb_nodes = 0;
   ElementType current_element_type = _not_defined;
 
   for (const auto & el : elements) {
     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 == nullptr) {
     AKANTU_SILENT_EXCEPTION(
         "No facet mesh is defined yet! check the buildFacets functions");
   }
 
   return *this->mesh_facets;
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Mesh & Mesh::getMeshFacets() const {
   if (this->mesh_facets == nullptr) {
     AKANTU_SILENT_EXCEPTION(
         "No facet mesh is defined yet! check the buildFacets functions");
   }
 
   return *this->mesh_facets;
 }
 /* -------------------------------------------------------------------------- */
 inline const Mesh & Mesh::getMeshParent() const {
   if (this->mesh_parent == nullptr) {
     AKANTU_SILENT_EXCEPTION(
         "No parent mesh is defined! This is only valid in a mesh_facets");
   }
 
   return *this->mesh_parent;
 }
 
 /* -------------------------------------------------------------------------- */
-void Mesh::addPeriodicSlave(UInt slave, UInt master) {
+void Mesh::addPeriodicSlave(Idx slave, Idx master) {
   if (master == slave) {
     return;
   }
 
   // if pair already registered
   auto master_slaves = periodic_master_slave.equal_range(master);
   auto slave_it =
       std::find_if(master_slaves.first, master_slaves.second,
                    [&](auto & pair) { return pair.second == slave; });
   if (slave_it == master_slaves.second) {
     // no duplicates
     periodic_master_slave.insert(std::make_pair(master, slave));
     AKANTU_DEBUG_INFO("adding periodic slave, slave gid:"
                       << getNodeGlobalId(slave) << " [lid: " << slave << "]"
                       << ", master gid:" << getNodeGlobalId(master)
                       << " [lid: " << master << "]");
     // std::cout << "adding periodic slave, slave gid:" <<
     // getNodeGlobalId(slave)
     //           << " [lid: " << slave << "]"
     //           << ", master gid:" << getNodeGlobalId(master)
     //           << " [lid: " << master << "]" << std::endl;
   }
 
   periodic_slave_master[slave] = master;
 
   auto set_flag = [&](auto node, auto flag) {
     (*nodes_flags)[node] &= ~NodeFlag::_periodic_mask; // clean periodic flags
     (*nodes_flags)[node] |= flag;
   };
 
   set_flag(slave, NodeFlag::_periodic_slave);
   set_flag(master, NodeFlag::_periodic_master);
 }
 
 /* -------------------------------------------------------------------------- */
-UInt Mesh::getPeriodicMaster(UInt slave) const {
+Idx Mesh::getPeriodicMaster(Idx slave) const {
   return periodic_slave_master.at(slave);
 }
 
 /* -------------------------------------------------------------------------- */
 class Mesh::PeriodicSlaves {
-  using internal_iterator = std::unordered_multimap<UInt, UInt>::const_iterator;
+  using internal_iterator = std::unordered_multimap<Idx, Idx>::const_iterator;
   std::pair<internal_iterator, internal_iterator> pair;
 
 public:
-  PeriodicSlaves(const Mesh & mesh, UInt master)
+  PeriodicSlaves(const Mesh & mesh, Idx master)
       : pair(mesh.getPeriodicMasterSlaves().equal_range(master)) {}
 
   PeriodicSlaves(const PeriodicSlaves & other) = default;
   PeriodicSlaves(PeriodicSlaves && other) = default;
   PeriodicSlaves & operator=(const PeriodicSlaves & other) = default;
 
   class const_iterator {
     internal_iterator it;
 
   public:
     const_iterator(internal_iterator it) : it(it) {}
 
     const_iterator operator++() {
       ++it;
       return *this;
     }
     bool operator!=(const const_iterator & other) { return other.it != it; }
     auto operator*() { return it->second; }
   };
 
   auto begin() const { return const_iterator(pair.first); }
   auto end() const { return const_iterator(pair.second); }
 };
 
 /* -------------------------------------------------------------------------- */
-inline decltype(auto) Mesh::getPeriodicSlaves(UInt master) const {
+inline decltype(auto) Mesh::getPeriodicSlaves(Idx master) const {
   return PeriodicSlaves(*this, master);
 }
 
 /* -------------------------------------------------------------------------- */
-inline Vector<UInt>
+inline Vector<Idx>
 Mesh::getConnectivityWithPeriodicity(const Element & element) const {
-  Vector<UInt> conn = getConnectivity(element);
+  Vector<Idx> conn = getConnectivity(element);
   if (not isPeriodic()) {
     return conn;
   }
 
   for (auto && node : conn) {
     if (isPeriodicSlave(node)) {
       node = getPeriodicMaster(node);
     }
   }
 
   return conn;
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_MESH_INLINE_IMPL_HH_ */
diff --git a/src/mesh/mesh_iterators.hh b/src/mesh/mesh_iterators.hh
index cf3ff81ae..2305ffefe 100644
--- a/src/mesh/mesh_iterators.hh
+++ b/src/mesh/mesh_iterators.hh
@@ -1,226 +1,225 @@
 /**
  * @file   mesh_iterators.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jul 16 2015
  * @date last modification: Thu Mar 11 2021
  *
  * @brief  Set of helper classes to have fun with range based for
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_named_argument.hh"
-#include "aka_static_if.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MESH_ITERATORS_HH_
 #define AKANTU_MESH_ITERATORS_HH_
 
 namespace akantu {
 
 class MeshElementsByTypes {
   using elements_iterator = Array<Element>::scalar_iterator;
 
 public:
   explicit MeshElementsByTypes(const Array<Element> & elements) {
     this->elements.copy(elements);
     std::sort(this->elements.begin(), this->elements.end());
   }
 
   /* ------------------------------------------------------------------------ */
   class MeshElementsRange {
   public:
     MeshElementsRange() = default;
 
     MeshElementsRange(const elements_iterator & begin,
                       const elements_iterator & end)
         : type((*begin).type), ghost_type((*begin).ghost_type), begin(begin),
           end(end) {}
 
     AKANTU_GET_MACRO(Type, type, ElementType);
     AKANTU_GET_MACRO(GhostType, ghost_type, GhostType);
 
-    const Array<UInt> & getElements() {
+    const Array<Int> & getElements() {
       elements.resize(end - begin);
       auto el_it = elements.begin();
       for (auto it = begin; it != end; ++it, ++el_it) {
         *el_it = it->element;
       }
 
       return elements;
     }
 
   private:
     ElementType type{_not_defined};
     GhostType ghost_type{_casper};
     elements_iterator begin;
     elements_iterator end;
-    Array<UInt> elements;
+    Array<Int> elements;
   };
 
   /* ------------------------------------------------------------------------ */
   class iterator {
     struct element_comparator {
       bool operator()(const Element & lhs, const Element & rhs) const {
         return ((rhs == ElementNull) || std::tie(lhs.ghost_type, lhs.type) <
                                             std::tie(rhs.ghost_type, rhs.type));
       }
     };
 
   public:
     iterator(const iterator &) = default;
     iterator(const elements_iterator & first, const elements_iterator & last)
         : range(std::equal_range(first, last, *first, element_comparator())),
           first(first), last(last) {}
 
     decltype(auto) operator*() const {
       return MeshElementsRange(range.first, range.second);
     }
 
     iterator operator++() {
       first = range.second;
       range = std::equal_range(first, last, *first, element_comparator());
       return *this;
     }
 
     bool operator==(const iterator & other) const {
       return (first == other.first and last == other.last);
     }
 
     bool operator!=(const iterator & other) const {
       return (not operator==(other));
     }
 
   private:
     std::pair<elements_iterator, elements_iterator> range;
     elements_iterator first;
     elements_iterator last;
   };
 
   iterator begin() { return iterator(elements.begin(), elements.end()); }
   iterator end() { return iterator(elements.end(), elements.end()); }
 
 private:
   Array<Element> elements;
 };
 
 /* -------------------------------------------------------------------------- */
 namespace mesh_iterators {
   namespace details {
     template <class internal_iterator> class delegated_iterator {
     public:
       using value_type = std::remove_pointer_t<
           typename internal_iterator::value_type::second_type>;
       using difference_type = std::ptrdiff_t;
       using pointer = value_type *;
       using reference = value_type &;
       using iterator_category = std::input_iterator_tag;
 
       explicit delegated_iterator(internal_iterator it) : it(std::move(it)) {}
 
       decltype(auto) operator*() {
         return std::forward<decltype(*(it->second))>(*(it->second));
       }
 
       delegated_iterator operator++() {
         ++it;
         return *this;
       }
 
       bool operator==(const delegated_iterator & other) const {
         return other.it == it;
       }
 
       bool operator!=(const delegated_iterator & other) const {
         return other.it != it;
       }
 
     private:
       internal_iterator it;
     };
   } // namespace details
 } // namespace mesh_iterators
 
 /* -------------------------------------------------------------------------- */
 template <class Func>
-void for_each_element(UInt nb_elements, const Array<UInt> & filter_elements,
+void for_each_element(Int nb_elements, const Array<Idx> & filter_elements,
                       Func && function) {
   if (filter_elements != empty_filter) {
     std::for_each(filter_elements.begin(), filter_elements.end(),
                   std::forward<Func>(function));
   } else {
     auto && range = arange(nb_elements);
     std::for_each(range.begin(), range.end(), std::forward<Func>(function));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Func, typename... pack>
 void for_each_element(const Mesh & mesh, Func && function, pack &&... _pack) {
   auto requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _casper);
-  const ElementTypeMapArray<UInt> * filter =
+  const ElementTypeMapArray<Idx> * filter =
       OPTIONAL_NAMED_ARG(element_filter, nullptr);
 
   bool all_ghost_types = requested_ghost_type == _casper;
 
   auto spatial_dimension =
       OPTIONAL_NAMED_ARG(spatial_dimension, mesh.getSpatialDimension());
   auto element_kind = OPTIONAL_NAMED_ARG(element_kind, _ek_not_defined);
 
   for (auto ghost_type : ghost_types) {
     if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types)) {
       continue;
     }
 
     auto element_types =
         mesh.elementTypes(spatial_dimension, ghost_type, element_kind);
 
     if (filter) {
       element_types =
           filter->elementTypes(spatial_dimension, ghost_type, element_kind);
     }
 
     for (auto type : element_types) {
-      const Array<UInt> * filter_array;
+      const Array<Idx> * filter_array;
 
       if (filter) {
         filter_array = &((*filter)(type, ghost_type));
       } else {
         filter_array = &empty_filter;
       }
 
       auto nb_elements = mesh.getNbElement(type, ghost_type);
 
       for_each_element(nb_elements, *filter_array, [&](auto && el) {
         auto element = Element{type, el, ghost_type};
         std::forward<Func>(function)(element);
       });
     }
   }
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_MESH_ITERATORS_HH_ */
diff --git a/src/mesh_utils/cohesive_element_inserter.cc b/src/mesh_utils/cohesive_element_inserter.cc
index 3e3f87751..05ddc09c1 100644
--- a/src/mesh_utils/cohesive_element_inserter.cc
+++ b/src/mesh_utils/cohesive_element_inserter.cc
@@ -1,328 +1,328 @@
 /**
  * @file   cohesive_element_inserter.cc
  *
  * @author Mathias Lebihain <mathias.lebihain@enpc.fr>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Dec 04 2013
  * @date last modification: Wed Nov 11 2020
  *
  * @brief  Cohesive element inserter functions
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "cohesive_element_inserter_helper.hh"
 #include "communicator.hh"
 #include "element_group.hh"
 #include "element_synchronizer.hh"
 #include "global_ids_updater.hh"
 #include "mesh_accessor.hh"
 #include "mesh_iterators.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <limits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 CohesiveElementInserter::CohesiveElementInserter(Mesh & mesh, const ID & id)
     : Parsable(ParserType::_cohesive_inserter), id(id), mesh(mesh),
       mesh_facets(mesh.initMeshFacets()),
       insertion_facets("insertion_facets", id),
       insertion_limits(mesh.getSpatialDimension(), 2),
       check_facets("check_facets", id) {
 
   this->registerParam("cohesive_surfaces", physical_surfaces, _pat_parsable,
                       "List of groups to consider for insertion");
   this->registerParam("cohesive_zones", physical_zones, _pat_parsable,
                       "List of groups to consider for insertion");
   this->registerParam("bounding_box", insertion_limits, _pat_parsable,
                       "Global limit for insertion");
 
-  UInt spatial_dimension = mesh.getSpatialDimension();
+  auto spatial_dimension = mesh.getSpatialDimension();
 
   /// init insertion limits
-  for (UInt dim = 0; dim < spatial_dimension; ++dim) {
+  for (Int dim = 0; dim < spatial_dimension; ++dim) {
     insertion_limits(dim, 0) = std::numeric_limits<Real>::max() * Real(-1.);
     insertion_limits(dim, 1) = std::numeric_limits<Real>::max();
   }
 
   insertion_facets.initialize(mesh_facets,
                               _spatial_dimension = spatial_dimension - 1,
                               _with_nb_element = true, _default_value = false);
 }
 
 /* -------------------------------------------------------------------------- */
 CohesiveElementInserter::~CohesiveElementInserter() = default;
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::parseSection(const ParserSection & section) {
   Parsable::parseSection(section);
 
   if (is_extrinsic) {
     limitCheckFacets(this->check_facets);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::limitCheckFacets() {
   limitCheckFacets(this->check_facets);
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::setLimit(SpatialDirection 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() {
+Int CohesiveElementInserter::insertIntrinsicElements() {
   limitCheckFacets(insertion_facets);
   return insertElements();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::limitCheckFacets(
     ElementTypeMapArray<bool> & check_facets) {
   AKANTU_DEBUG_IN();
 
-  UInt spatial_dimension = mesh.getSpatialDimension();
+  auto spatial_dimension = mesh.getSpatialDimension();
 
   check_facets.initialize(mesh_facets,
                           _spatial_dimension = spatial_dimension - 1,
                           _with_nb_element = true, _default_value = true);
   check_facets.set(true);
 
   // remove the pure ghost elements
   for_each_element(
       mesh_facets,
       [&](auto && facet) {
         const auto & element_to_facet = mesh_facets.getElementToSubelement(
             facet.type, facet.ghost_type)(facet.element);
         auto & left = element_to_facet[0];
         auto & right = element_to_facet[1];
         if (right == ElementNull ||
             (left.ghost_type == _ghost && right.ghost_type == _ghost)) {
           check_facets(facet) = false;
           return;
         }
 #ifndef AKANTU_NDEBUG
         if (left == ElementNull) {
           AKANTU_DEBUG_WARNING("By convention element should not have "
                                "ElementNull on there first side: "
                                << facet);
         }
 #endif
 
         if (left.kind() == _ek_cohesive or right.kind() == _ek_cohesive) {
           check_facets(facet) = false;
         }
       },
       _spatial_dimension = spatial_dimension - 1);
 
   auto tolerance = Math::getTolerance();
   Vector<Real> bary_facet(spatial_dimension);
   // set the limits to the bounding box
   for_each_element(
       mesh_facets,
       [&](auto && facet) {
         auto & need_check = check_facets(facet);
         if (not need_check) {
           return;
         }
 
         mesh_facets.getBarycenter(facet, bary_facet);
-        UInt coord_in_limit = 0;
+        Int coord_in_limit = 0;
 
         while (coord_in_limit < spatial_dimension and
                bary_facet(coord_in_limit) >
                    (insertion_limits(coord_in_limit, 0) - tolerance) and
                bary_facet(coord_in_limit) <
                    (insertion_limits(coord_in_limit, 1) + tolerance)) {
           ++coord_in_limit;
         }
 
         if (coord_in_limit != spatial_dimension) {
           need_check = false;
         }
       },
       _spatial_dimension = spatial_dimension - 1);
 
   // remove the physical zones
   if (mesh.hasData("physical_names") and not physical_zones.empty()) {
     auto && physical_names = mesh.getData<std::string>("physical_names");
     for_each_element(
         mesh_facets,
         [&](auto && facet) {
           const auto & element_to_facet = mesh_facets.getElementToSubelement(
               facet.type, facet.ghost_type)(facet.element);
           auto count = 0;
           for (auto i : arange(2)) {
             const auto & element = element_to_facet[i];
             if (element == ElementNull) {
               continue;
             }
             const auto & name = physical_names(element);
             count += find(physical_zones.begin(), physical_zones.end(), name) !=
                      physical_zones.end();
           }
 
           if (count != 2) {
             check_facets(facet) = false;
           }
         },
         _spatial_dimension = spatial_dimension - 1);
   }
 
   if (physical_surfaces.empty()) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   if (not mesh_facets.hasData("physical_names")) {
     AKANTU_DEBUG_ASSERT(
         physical_surfaces.empty(),
         "No physical names in the mesh but insertion limited to a group");
     AKANTU_DEBUG_OUT();
     return;
   }
 
   const auto & physical_ids =
       mesh_facets.getData<std::string>("physical_names");
 
   // set the limits to the physical surfaces
   for_each_element(
       mesh_facets,
       [&](auto && facet) {
         auto & need_check = check_facets(facet, 0);
         if (not need_check) {
           return;
         }
 
         const auto & physical_id = physical_ids(facet);
         auto it = find(physical_surfaces.begin(), physical_surfaces.end(),
                        physical_id);
 
         need_check = (it != physical_surfaces.end());
       },
       _spatial_dimension = spatial_dimension - 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt CohesiveElementInserter::insertElements(bool only_double_facets) {
   CohesiveNewNodesEvent node_event(AKANTU_CURRENT_FUNCTION);
   NewElementsEvent element_event(AKANTU_CURRENT_FUNCTION);
 
   if (mesh_facets.isDistributed()) {
     mesh_facets.getElementSynchronizer().synchronizeOnce(
         *this, SynchronizationTag::_ce_groups);
   }
 
   CohesiveElementInserterHelper cohesive_element_inserter_helper(
       mesh, insertion_facets);
 
   UInt nb_new_elements{0};
   if (only_double_facets) {
     nb_new_elements = cohesive_element_inserter_helper.insertFacetsOnly();
   } else {
     nb_new_elements = cohesive_element_inserter_helper.insertCohesiveElement();
     element_event.getList().copy(
         cohesive_element_inserter_helper.getNewElements());
   }
 
   auto && doubled_nodes = cohesive_element_inserter_helper.getDoubledNodes();
   auto nb_new_nodes = doubled_nodes.size();
 
   node_event.getList().reserve(nb_new_nodes);
   node_event.getOldNodesList().reserve(nb_new_nodes);
 
   for (auto && doubled_node : make_view(doubled_nodes, 2)) {
     node_event.getList().push_back(doubled_node(1));
     node_event.getOldNodesList().push_back(doubled_node(0));
   }
 
   if (nb_new_elements > 0) {
     updateInsertionFacets();
   }
 
   MeshAccessor mesh_accessor(mesh);
   std::tie(nb_new_nodes, nb_new_elements) =
       mesh_accessor.updateGlobalData(node_event, element_event);
 
   return nb_new_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::updateInsertionFacets() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   for (auto && facet_gt : ghost_types) {
     for (auto && facet_type :
          mesh_facets.elementTypes(spatial_dimension - 1, facet_gt)) {
       auto & ins_facets = insertion_facets(facet_type, facet_gt);
 
       // this is the intrinsic case
       if (not is_extrinsic) {
         continue;
       }
 
       auto & f_check = check_facets(facet_type, facet_gt);
       for (auto && pair : zip(ins_facets, f_check)) {
         bool & ins = std::get<0>(pair);
         bool & check = std::get<1>(pair);
         if (ins) {
           ins = check = false;
         }
       }
     }
   }
 
   // resize for the newly added facets
   insertion_facets.initialize(mesh_facets,
                               _spatial_dimension = spatial_dimension - 1,
                               _with_nb_element = true, _default_value = false);
 
   // resize for the newly added facets
   if (is_extrinsic) {
     check_facets.initialize(mesh_facets,
                             _spatial_dimension = spatial_dimension - 1,
                             _with_nb_element = true, _default_value = false);
   } else {
     insertion_facets.set(false);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/cohesive_element_inserter.hh b/src/mesh_utils/cohesive_element_inserter.hh
index 0ec5aa80f..5e43d387a 100644
--- a/src/mesh_utils/cohesive_element_inserter.hh
+++ b/src/mesh_utils/cohesive_element_inserter.hh
@@ -1,175 +1,175 @@
 /**
  * @file   cohesive_element_inserter.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Dec 04 2013
  * @date last modification: Tue Jul 21 2020
  *
  * @brief  Cohesive element inserter
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 #include "mesh_utils.hh"
 #include "parsable.hh"
 /* -------------------------------------------------------------------------- */
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_COHESIVE_ELEMENT_INSERTER_HH_
 #define AKANTU_COHESIVE_ELEMENT_INSERTER_HH_
 
 namespace akantu {
 class GlobalIdsUpdater;
 class FacetSynchronizer;
 class SolidMechanicsModeslCohesivel;
 } // namespace akantu
 
 namespace akantu {
 
 class CohesiveElementInserter : public DataAccessor<Element>, public Parsable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   CohesiveElementInserter(Mesh & mesh,
                           const ID & id = "cohesive_element_inserter");
 
   ~CohesiveElementInserter() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// set range limitation for intrinsic cohesive element insertion
   void setLimit(SpatialDirection axis, Real first_limit, Real second_limit);
 
   /// insert intrinsic cohesive elements in a predefined range
-  auto insertIntrinsicElements() -> UInt;
+  Int insertIntrinsicElements();
 
   /// insert extrinsic cohesive elements (returns the number of new
   /// cohesive elements)
   UInt insertElements(bool only_double_facets = false);
 
   /// limit check facets to match given insertion limits
   void limitCheckFacets();
 
 protected:
   void parseSection(const ParserSection & section) override;
 
 protected:
   /// internal version of limitCheckFacets
   void limitCheckFacets(ElementTypeMapArray<bool> & check_facets);
 
   /// update facet insertion arrays after facets doubling
   void updateInsertionFacets();
 
   /// functions for parallel communications
-  inline UInt getNbData(const Array<Element> & elements,
+  inline Int getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO_NOT_CONST(InsertionFacetsByElement, insertion_facets,
                              ElementTypeMapArray<bool> &);
   AKANTU_GET_MACRO(InsertionFacetsByElement, insertion_facets,
                    const ElementTypeMapArray<bool> &);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(InsertionFacets, insertion_facets, bool);
 
   AKANTU_GET_MACRO(CheckFacets, check_facets,
                    const ElementTypeMapArray<bool> &);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(CheckFacets, check_facets, bool);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(CheckFacets, check_facets, bool);
 
   AKANTU_GET_MACRO(MeshFacets, mesh_facets, const Mesh &);
   AKANTU_GET_MACRO_NOT_CONST(MeshFacets, mesh_facets, Mesh &);
 
   AKANTU_SET_MACRO(IsExtrinsic, is_extrinsic, bool);
 
 public:
   friend class SolidMechanicsModelCohesive;
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// object id
   ID id;
 
   /// main mesh where to insert cohesive elements
   Mesh & mesh;
 
   /// mesh containing facets
   Mesh & mesh_facets;
 
   /// list of facets where to insert elements
   ElementTypeMapArray<bool> insertion_facets;
 
   /// limits for element insertion
   Matrix<Real> insertion_limits;
 
   /// list of groups to consider for insertion, ignored if empty
   std::set<ID> physical_surfaces;
 
   /// list of groups in between which an inside which element are insterted
   std::set<ID> physical_zones;
 
   /// vector containing facets in which extrinsic cohesive elements can be
   /// inserted
   ElementTypeMapArray<bool> check_facets;
 
   /// global connectivity ids updater
   std::unique_ptr<GlobalIdsUpdater> global_ids_updater;
 
   /// is this inserter used in extrinsic
   bool is_extrinsic{false};
 };
 
 class CohesiveNewNodesEvent : public NewNodesEvent {
 public:
   CohesiveNewNodesEvent(const std::string & origin) : NewNodesEvent(origin) {}
   ~CohesiveNewNodesEvent() override = default;
 
-  AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
-  AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
+  AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<Idx> &);
+  AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<Idx> &);
 
 private:
-  Array<UInt> old_nodes;
+  Array<Idx> old_nodes;
 };
 
 } // namespace akantu
 
 #include "cohesive_element_inserter_inline_impl.hh"
 
 #endif /* AKANTU_COHESIVE_ELEMENT_INSERTER_HH_ */
diff --git a/src/mesh_utils/cohesive_element_inserter_inline_impl.hh b/src/mesh_utils/cohesive_element_inserter_inline_impl.hh
index 7a41290be..71d8ddf29 100644
--- a/src/mesh_utils/cohesive_element_inserter_inline_impl.hh
+++ b/src/mesh_utils/cohesive_element_inserter_inline_impl.hh
@@ -1,91 +1,91 @@
 /**
  * @file   cohesive_element_inserter_inline_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Oct 13 2017
  * @date last modification: Wed Nov 11 2020
  *
  * @brief  Cohesive element inserter inline functions
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "cohesive_element_inserter.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_HH_
 #define AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-inline UInt
+inline Int
 CohesiveElementInserter::getNbData(const Array<Element> & elements,
                                    const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
-  UInt size = 0;
+  Int size = 0;
 
   if (tag == SynchronizationTag::_ce_groups) {
     size = elements.size() * sizeof(bool);
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 CohesiveElementInserter::packData(CommunicationBuffer & buffer,
                                   const Array<Element> & elements,
                                   const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
   if (tag == SynchronizationTag::_ce_groups) {
     for (const auto & el : elements) {
       const bool & data = insertion_facets(el);
       buffer << data;
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void
 CohesiveElementInserter::unpackData(CommunicationBuffer & buffer,
                                     const Array<Element> & elements,
                                     const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   if (tag == SynchronizationTag::_ce_groups) {
     for (const auto & el : elements) {
       bool & data = insertion_facets(el);
       buffer >> data;
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_COHESIVE_ELEMENT_INSERTER_INLINE_IMPL_HH_ */
diff --git a/src/mesh_utils/global_ids_updater.hh b/src/mesh_utils/global_ids_updater.hh
index 8d7f3b2ac..1e4530e41 100644
--- a/src/mesh_utils/global_ids_updater.hh
+++ b/src/mesh_utils/global_ids_updater.hh
@@ -1,108 +1,108 @@
 /**
  * @file   global_ids_updater.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Oct 02 2015
  * @date last modification: Thu Feb 20 2020
  *
  * @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-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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;
 } // namespace 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 local_nb_new_nodes);
+  Int updateGlobalIDs(Int local_nb_new_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 local_nb_new_nodes);
+  Int updateGlobalIDsLocally(Int local_nb_new_nodes);
 
   /// function to synchronize the global connectivity of new inserted
   /// nodes among the processors. It must be called after updating the
   /// node types.
   void synchronizeGlobalIDs();
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
-  inline UInt getNbData(const Array<Element> & elements,
+  inline Int getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
   /* ------------------------------------------------------------------------ */
   template <bool pack_mode>
   inline void
   packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
                                const Array<Element> & elements) const;
 
   /* ------------------------------------------------------------------------ */
   /* Members                                                                  */
   /* ------------------------------------------------------------------------ */
 private:
   /// Reference to the mesh to update
   Mesh & mesh;
 
   /// distributed synchronizer to communicate the connectivity
   ElementSynchronizer & synchronizer;
 
   /// Tells if a reduction is taking place or not
   bool reduce{false};
 
-  std::unordered_map<UInt, std::vector<std::pair<UInt, NodeFlag>>> nodes_flags;
+  std::unordered_map<Idx, std::vector<std::pair<Idx, NodeFlag>>> nodes_flags;
 };
 
 } // namespace akantu
 
 #include "global_ids_updater_inline_impl.hh"
 
 #endif /* AKANTU_GLOBAL_IDS_UPDATER_HH_ */
diff --git a/src/mesh_utils/global_ids_updater_inline_impl.hh b/src/mesh_utils/global_ids_updater_inline_impl.hh
index 63cc4d022..9214012e8 100644
--- a/src/mesh_utils/global_ids_updater_inline_impl.hh
+++ b/src/mesh_utils/global_ids_updater_inline_impl.hh
@@ -1,157 +1,157 @@
 /**
  * @file   global_ids_updater_inline_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Oct 02 2015
  * @date last modification: Tue Sep 08 2020
  *
  * @brief  Implementation of the inline functions of GlobalIdsUpdater
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
-#include "global_ids_updater.hh"
+//#include "global_ids_updater.hh"
 #include "mesh.hh"
 #include "mesh_accessor.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_GLOBAL_IDS_UPDATER_INLINE_IMPL_HH_
 #define AKANTU_GLOBAL_IDS_UPDATER_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-inline UInt GlobalIdsUpdater::getNbData(const Array<Element> & elements,
-                                        const SynchronizationTag & tag) const {
+inline Int GlobalIdsUpdater::getNbData(const Array<Element> & elements,
+                                       const SynchronizationTag & tag) const {
   UInt size = 0;
   if (tag == SynchronizationTag::_giu_global_conn) {
     size += Mesh::getNbNodesPerElementList(elements) *
                 (sizeof(UInt) + sizeof(Int)) +
             sizeof(int);
 #ifndef AKANTU_NDEBUG
     size += sizeof(NodeFlag) * Mesh::getNbNodesPerElementList(elements);
 #endif
   }
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void GlobalIdsUpdater::packData(CommunicationBuffer & buffer,
                                        const Array<Element> & elements,
                                        const SynchronizationTag & tag) const {
   if (tag != SynchronizationTag::_giu_global_conn) {
     return;
   }
 
   int prank = mesh.getCommunicator().whoAmI();
 
   const auto & global_nodes_ids = mesh.getGlobalNodesIds();
   buffer << prank;
 
   for (const auto & element : elements) {
     /// get element connectivity
-    const Vector<UInt> current_conn =
+    auto && current_conn =
         const_cast<const Mesh &>(mesh).getConnectivity(element);
 
     /// loop on all connectivity nodes
     for (auto node : current_conn) {
-      UInt index = -1;
+      Int index = -1;
       if ((this->reduce and mesh.isLocalOrMasterNode(node)) or
           (not this->reduce and not mesh.isPureGhostNode(node))) {
         index = global_nodes_ids(node);
       }
       buffer << index;
       buffer << (mesh.isLocalOrMasterNode(node) ? prank
                                                 : mesh.getNodePrank(node));
 #ifndef AKANTU_NDEBUG
       auto node_flag = mesh.getNodeFlag(node);
       buffer << node_flag;
 #endif
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void GlobalIdsUpdater::unpackData(CommunicationBuffer & buffer,
                                          const Array<Element> & elements,
                                          const SynchronizationTag & tag) {
   if (tag != SynchronizationTag::_giu_global_conn) {
     return;
   }
 
   MeshAccessor mesh_accessor(mesh);
   auto & global_nodes_ids = mesh_accessor.getNodesGlobalIds();
 
   int proc;
   buffer >> proc;
 
   for (const auto & element : elements) {
     /// get element connectivity
-    Vector<UInt> current_conn =
+    auto && current_conn =
         const_cast<const Mesh &>(mesh).getConnectivity(element);
 
     /// loop on all connectivity nodes
     for (auto node : current_conn) {
-      UInt index;
+      Int index;
       Int node_prank;
       buffer >> index;
       buffer >> node_prank;
 #ifndef AKANTU_NDEBUG
       NodeFlag node_flag;
       buffer >> node_flag;
       if (reduce) {
         nodes_flags[node].push_back(std::make_pair(proc, node_flag));
       }
 #endif
 
-      if (index == UInt(-1)) {
+      if (index == Int(-1)) {
         continue;
       }
 
       if (mesh.isSlaveNode(node)) {
         auto & gid = global_nodes_ids(node);
         AKANTU_DEBUG_ASSERT(gid == UInt(-1) or gid == index,
                             "The node already has a global id, from proc "
                                 << proc << ", different from the one received "
                                 << gid << " " << index);
         gid = index;
 #ifndef AKANTU_NDEBUG
         auto current_proc = mesh.getNodePrank(node);
         AKANTU_DEBUG_ASSERT(
             current_proc == -1 or current_proc == node_prank,
             "The node "
                 << index << " already has a prank: " << current_proc
                 << ", that is different from the one we are trying to set "
                 << node_prank << " " << node_flag);
 #endif
         mesh_accessor.setNodePrank(node, node_prank);
       }
     }
   }
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_GLOBAL_IDS_UPDATER_INLINE_IMPL_HH_ */
diff --git a/src/model/common/dof_manager/dof_manager.cc b/src/model/common/dof_manager/dof_manager.cc
index 13faf30c8..4cce09f23 100644
--- a/src/model/common/dof_manager/dof_manager.cc
+++ b/src/model/common/dof_manager/dof_manager.cc
@@ -1,1017 +1,1018 @@
 /**
  * @file   dof_manager.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Aug 18 2015
  * @date last modification: Sat Mar 06 2021
  *
  * @brief  Implementation of the common parts of the DOFManagers
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "communicator.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 #include "node_group.hh"
 #include "node_synchronizer.hh"
 #include "non_linear_solver.hh"
 #include "periodic_node_synchronizer.hh"
 #include "time_step_solver.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFManager(const ID & id)
     : id(id), dofs_flag(0, 1, std::string(id + ":dofs_type")),
       global_equation_number(0, 1, "global_equation_number"),
       communicator(Communicator::getStaticCommunicator()) {}
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFManager(Mesh & mesh, const ID & id)
     : id(id), mesh(&mesh), dofs_flag(0, 1, std::string(id + ":dofs_type")),
       global_equation_number(0, 1, "global_equation_number"),
       communicator(mesh.getCommunicator()) {
   this->mesh->registerEventHandler(*this, _ehp_dof_manager);
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManager::~DOFManager() = default;
 
 /* -------------------------------------------------------------------------- */
 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,
-    ElementType type, GhostType ghost_type, Real scale_factor,
-    const Array<UInt> & filter_elements) {
+    const ElementType & type, const GhostType & ghost_type, Real scale_factor,
+    const Array<Int> & filter_elements) {
   AKANTU_DEBUG_IN();
 
   UInt nb_element;
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_degree_of_freedom =
       elementary_vect.getNbComponent() / nb_nodes_per_element;
 
   UInt * filter_it = nullptr;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
     filter_it = filter_elements.data();
   } 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<Real>::const_matrix_iterator elem_it =
       elementary_vect.begin(nb_degree_of_freedom, nb_nodes_per_element);
 
   for (UInt el = 0; el < nb_element; ++el, ++elem_it) {
     UInt element = el;
     if (filter_it != nullptr) {
       // conn_it = conn_begin + *filter_it;
       element = *filter_it;
     }
 
     // const Vector<UInt> & conn = *conn_it;
     const Matrix<Real> & elemental_val = *elem_it;
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       UInt offset_node = connectivity(element, n) * nb_degree_of_freedom;
       Vector<Real> assemble(array_assembeled.data() + offset_node,
                             nb_degree_of_freedom);
       Vector<Real> elem_val = elemental_val(n);
       assemble.aXplusY(elem_val, scale_factor);
     }
 
     if (filter_it != nullptr) {
       ++filter_it;
     }
     //    else
     //      ++conn_it;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::assembleElementalArrayToResidual(
-    const ID & dof_id, const Array<Real> & elementary_vect, ElementType type,
-    GhostType ghost_type, Real scale_factor,
-    const Array<UInt> & filter_elements) {
+    const ID & dof_id, const Array<Real> & elementary_vect,
+    const ElementType & type, const GhostType & ghost_type, Real scale_factor,
+    const Array<Int> & 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.zero();
 
   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, ElementType type, GhostType ghost_type,
-    Real scale_factor, const Array<UInt> & filter_elements) {
+    const ID & lumped_mtx, const ElementType & type,
+    const GhostType & ghost_type, Real scale_factor,
+    const Array<Int> & 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.zero();
 
   this->assembleElementalArrayLocalArray(
       elementary_vect, array_localy_assembeled, type, ghost_type, scale_factor,
       filter_elements);
 
   this->assembleToLumpedMatrix(dof_id, array_localy_assembeled, lumped_mtx, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::assembleMatMulDOFsToResidual(const ID & A_id,
                                               Real scale_factor) {
   for (auto & pair : this->dofs) {
     const auto & dof_id = pair.first;
     auto & dof_data = *pair.second;
 
     this->assembleMatMulVectToResidual(dof_id, A_id, *dof_data.dof,
                                        scale_factor);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::splitSolutionPerDOFs() {
   for (auto && data : this->dofs) {
     auto & dof_data = *data.second;
     dof_data.solution.resize(dof_data.dof->size() *
                              dof_data.dof->getNbComponent());
     this->getSolutionPerDOFs(data.first, dof_data.solution);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::getSolutionPerDOFs(const ID & dof_id,
                                     Array<Real> & solution_array) {
   AKANTU_DEBUG_IN();
   this->getArrayPerDOFs(dof_id, this->getSolution(), solution_array);
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 void DOFManager::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 DOFManager::assembleToResidual(const ID & dof_id,
                                     Array<Real> & array_to_assemble,
                                     Real scale_factor) {
   AKANTU_DEBUG_IN();
 
   // this->makeConsistentForPeriodicity(dof_id, array_to_assemble);
   this->assembleToGlobalArray(dof_id, array_to_assemble, this->getResidual(),
                               scale_factor);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::assembleToLumpedMatrix(const ID & dof_id,
                                         Array<Real> & array_to_assemble,
                                         const ID & lumped_mtx,
                                         Real scale_factor) {
   AKANTU_DEBUG_IN();
 
   // this->makeConsistentForPeriodicity(dof_id, array_to_assemble);
   auto & lumped = this->getLumpedMatrix(lumped_mtx);
   this->assembleToGlobalArray(dof_id, array_to_assemble, lumped, scale_factor);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFData::DOFData(const ID & dof_id)
     : support_type(_dst_generic), group_support("__mesh__"),
       solution(0, 1, dof_id + ":solution"),
       local_equation_number(0, 1, dof_id + ":local_equation_number"),
       associated_nodes(0, 1, dof_id + "associated_nodes") {}
 
 /* -------------------------------------------------------------------------- */
 DOFManager::DOFData::~DOFData() = default;
 
 /* -------------------------------------------------------------------------- */
 template <typename Func>
 auto DOFManager::countDOFsForNodes(const DOFData & dof_data, UInt nb_nodes,
                                    Func && getNode) {
   auto nb_local_dofs = nb_nodes;
   decltype(nb_local_dofs) nb_pure_local = 0;
   for (auto n : arange(nb_nodes)) {
     UInt node = getNode(n);
 
     // http://www.open-std.org/jtc1/sc22/open/n2356/conv.html
     // bool are by convention casted to 0 and 1 when promoted to int
     nb_pure_local += this->mesh->isLocalOrMasterNode(node);
     nb_local_dofs -= this->mesh->isPeriodicSlave(node);
   }
 
   const auto & dofs_array = *dof_data.dof;
   nb_pure_local *= dofs_array.getNbComponent();
   nb_local_dofs *= dofs_array.getNbComponent();
   return std::make_pair(nb_local_dofs, nb_pure_local);
 }
 
 /* -------------------------------------------------------------------------- */
 auto DOFManager::getNewDOFDataInternal(const ID & dof_id) -> DOFData & {
   auto it = this->dofs.find(dof_id);
   if (it != this->dofs.end()) {
     AKANTU_EXCEPTION("This dof array has already been registered");
   }
 
   std::unique_ptr<DOFData> dof_data_ptr = this->getNewDOFData(dof_id);
   DOFData & dof_data = *dof_data_ptr;
 
   this->dofs[dof_id] = std::move(dof_data_ptr);
   return dof_data;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                               const DOFSupportType & support_type) {
   auto & dofs_storage = this->getNewDOFDataInternal(dof_id);
   dofs_storage.support_type = support_type;
 
   this->registerDOFsInternal(dof_id, dofs_array);
 
   resizeGlobalArrays();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFs(const ID & dof_id, Array<Real> & dofs_array,
                               const ID & support_group) {
   auto & dofs_storage = this->getNewDOFDataInternal(dof_id);
   dofs_storage.support_type = _dst_nodal;
   dofs_storage.group_support = support_group;
 
   this->registerDOFsInternal(dof_id, dofs_array);
 
   resizeGlobalArrays();
 }
 
 /* -------------------------------------------------------------------------- */
 std::tuple<UInt, UInt, UInt>
 DOFManager::registerDOFsInternal(const ID & dof_id, Array<Real> & dofs_array) {
   DOFData & dof_data = this->getDOFData(dof_id);
   dof_data.dof = &dofs_array;
 
   UInt nb_local_dofs = 0;
   UInt nb_pure_local = 0;
 
   const auto & support_type = dof_data.support_type;
 
   switch (support_type) {
   case _dst_nodal: {
     const auto & group = dof_data.group_support;
 
     std::function<UInt(UInt)> getNode;
     if (group == "__mesh__") {
       AKANTU_DEBUG_ASSERT(
           dofs_array.size() == this->mesh->getNbNodes(),
           "The array of dof is too short to be associated to nodes.");
 
       std::tie(nb_local_dofs, nb_pure_local) = countDOFsForNodes(
           dof_data, this->mesh->getNbNodes(), [](auto && n) { return n; });
     } else {
       const auto & node_group =
           this->mesh->getElementGroup(group).getNodeGroup().getNodes();
 
       AKANTU_DEBUG_ASSERT(
           dofs_array.size() == node_group.size(),
           "The array of dof is too shot to be associated to nodes.");
 
       std::tie(nb_local_dofs, nb_pure_local) =
           countDOFsForNodes(dof_data, node_group.size(),
                             [&node_group](auto && n) { return node_group(n); });
     }
 
     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.");
   }
   }
 
   dof_data.local_nb_dofs = nb_local_dofs;
   dof_data.pure_local_nb_dofs = nb_pure_local;
   dof_data.ghosts_nb_dofs = nb_local_dofs - nb_pure_local;
 
   this->pure_local_system_size += nb_pure_local;
   this->local_system_size += nb_local_dofs;
 
   auto nb_total_pure_local = nb_pure_local;
   communicator.allReduce(nb_total_pure_local, SynchronizerOperation::_sum);
 
   this->system_size += nb_total_pure_local;
 
   // updating the dofs data after counting is finished
   switch (support_type) {
   case _dst_nodal: {
     const auto & group = dof_data.group_support;
     if (group != "__mesh__") {
       auto & support_nodes =
           this->mesh->getElementGroup(group).getNodeGroup().getNodes();
       this->updateDOFsData(
           dof_data, nb_local_dofs, nb_pure_local, support_nodes.size(),
           [&support_nodes](UInt node) -> UInt { return support_nodes[node]; });
     } else {
       this->updateDOFsData(dof_data, nb_local_dofs, nb_pure_local,
                            mesh->getNbNodes(),
                            [](UInt node) -> UInt { return node; });
     }
     break;
   }
   case _dst_generic: {
     this->updateDOFsData(dof_data, nb_local_dofs, nb_pure_local);
     break;
   }
   }
 
   return std::make_tuple(nb_local_dofs, nb_pure_local, nb_total_pure_local);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFsPrevious(const ID & dof_id, Array<Real> & array) {
   DOFData & dof = this->getDOFData(dof_id);
 
   if (dof.previous != nullptr) {
     AKANTU_EXCEPTION("The previous dofs array for "
                      << dof_id << " has already been registered");
   }
 
   dof.previous = &array;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFsIncrement(const ID & dof_id, Array<Real> & array) {
   DOFData & dof = this->getDOFData(dof_id);
 
   if (dof.increment != nullptr) {
     AKANTU_EXCEPTION("The dofs increment array for "
                      << dof_id << " has already been registered");
   }
 
   dof.increment = &array;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerDOFsDerivative(const ID & dof_id, UInt order,
                                         Array<Real> & dofs_derivative) {
   DOFData & dof = this->getDOFData(dof_id);
   std::vector<Array<Real> *> & derivatives = dof.dof_derivatives;
 
   if (derivatives.size() < order) {
     derivatives.resize(order, nullptr);
   } else {
     if (derivatives[order - 1] != nullptr) {
       AKANTU_EXCEPTION("The dof derivatives of order "
                        << order << " already been registered for this dof ("
                        << dof_id << ")");
     }
   }
 
   derivatives[order - 1] = &dofs_derivative;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::registerBlockedDOFs(const ID & dof_id,
                                      Array<bool> & blocked_dofs) {
   DOFData & dof = this->getDOFData(dof_id);
 
   if (dof.blocked_dofs != nullptr) {
     AKANTU_EXCEPTION("The blocked dofs array for "
                      << dof_id << " has already been registered");
   }
 
   dof.blocked_dofs = &blocked_dofs;
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix &
 DOFManager::registerSparseMatrix(const ID & matrix_id,
                                  std::unique_ptr<SparseMatrix> & matrix) {
   auto it = this->matrices.find(matrix_id);
   if (it != this->matrices.end()) {
     AKANTU_EXCEPTION("The matrix " << matrix_id << " already exists in "
                                    << this->id);
   }
 
   auto & ret = *matrix;
   this->matrices[matrix_id] = std::move(matrix);
   return ret;
 }
 
 /* -------------------------------------------------------------------------- */
 /// Get an instance of a new SparseMatrix
 SolverVector &
 DOFManager::registerLumpedMatrix(const ID & matrix_id,
                                  std::unique_ptr<SolverVector> & matrix) {
   auto 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 & ret = *matrix;
   this->lumped_matrices[matrix_id] = std::move(matrix);
   ret.resize();
   return ret;
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver & DOFManager::registerNonLinearSolver(
     const ID & non_linear_solver_id,
     std::unique_ptr<NonLinearSolver> & non_linear_solver) {
   NonLinearSolversMap::const_iterator it =
       this->non_linear_solvers.find(non_linear_solver_id);
   if (it != this->non_linear_solvers.end()) {
     AKANTU_EXCEPTION("The non linear solver " << non_linear_solver_id
                                               << " already exists in "
                                               << this->id);
   }
 
   NonLinearSolver & ret = *non_linear_solver;
   this->non_linear_solvers[non_linear_solver_id] = std::move(non_linear_solver);
 
   return ret;
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver & DOFManager::registerTimeStepSolver(
     const ID & time_step_solver_id,
     std::unique_ptr<TimeStepSolver> & time_step_solver) {
   TimeStepSolversMap::const_iterator it =
       this->time_step_solvers.find(time_step_solver_id);
   if (it != this->time_step_solvers.end()) {
     AKANTU_EXCEPTION("The non linear solver " << time_step_solver_id
                                               << " already exists in "
                                               << this->id);
   }
 
   TimeStepSolver & ret = *time_step_solver;
   this->time_step_solvers[time_step_solver_id] = std::move(time_step_solver);
   return ret;
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix & DOFManager::getMatrix(const ID & id) {
   ID matrix_id = this->id + ":mtx:" + id;
   SparseMatricesMap::const_iterator it = this->matrices.find(matrix_id);
   if (it == this->matrices.end()) {
     AKANTU_SILENT_EXCEPTION("The matrix " << matrix_id << " does not exists in "
                                           << this->id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFManager::hasMatrix(const ID & id) const {
   ID mtx_id = this->id + ":mtx:" + id;
   auto it = this->matrices.find(mtx_id);
   return it != this->matrices.end();
 }
 
 /* -------------------------------------------------------------------------- */
 SolverVector & 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 SolverVector & DOFManager::getLumpedMatrix(const ID & id) const {
   ID matrix_id = this->id + ":lumped_mtx:" + id;
   auto it = this->lumped_matrices.find(matrix_id);
   if (it == this->lumped_matrices.end()) {
     AKANTU_SILENT_EXCEPTION("The lumped matrix "
                             << matrix_id << " does not exists in " << this->id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFManager::hasLumpedMatrix(const ID & id) const {
   ID mtx_id = this->id + ":lumped_mtx:" + id;
   auto it = this->lumped_matrices.find(mtx_id);
   return it != this->lumped_matrices.end();
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver & DOFManager::getNonLinearSolver(const ID & id) {
   ID non_linear_solver_id = this->id + ":nls:" + id;
   NonLinearSolversMap::const_iterator it =
       this->non_linear_solvers.find(non_linear_solver_id);
   if (it == this->non_linear_solvers.end()) {
     AKANTU_EXCEPTION("The non linear solver " << non_linear_solver_id
                                               << " does not exists in "
                                               << this->id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFManager::hasNonLinearSolver(const ID & id) const {
   ID solver_id = this->id + ":nls:" + id;
   auto it = this->non_linear_solvers.find(solver_id);
   return it != this->non_linear_solvers.end();
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver & DOFManager::getTimeStepSolver(const ID & id) {
   ID time_step_solver_id = this->id + ":tss:" + id;
   TimeStepSolversMap::const_iterator it =
       this->time_step_solvers.find(time_step_solver_id);
   if (it == this->time_step_solvers.end()) {
     AKANTU_EXCEPTION("The non linear solver " << time_step_solver_id
                                               << " does not exists in "
                                               << this->id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 bool DOFManager::hasTimeStepSolver(const ID & solver_id) const {
   ID time_step_solver_id = this->id + ":tss:" + solver_id;
   auto it = this->time_step_solvers.find(time_step_solver_id);
   return it != this->time_step_solvers.end();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::savePreviousDOFs(const ID & dofs_id) {
   this->getPreviousDOFs(dofs_id).copy(this->getDOFs(dofs_id));
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::zeroResidual() { this->residual->zero(); }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::zeroMatrix(const ID & mtx) { this->getMatrix(mtx).zero(); }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::zeroLumpedMatrix(const ID & mtx) {
   this->getLumpedMatrix(mtx).zero();
 }
 
 /* -------------------------------------------------------------------------- */
 /* 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;
   UInt nb_new_pure_local;
 
   std::tie(nb_new_local_dofs, nb_new_pure_local) =
       countDOFsForNodes(dof_data, nodes_list.size(),
                         [&nodes_list](auto && n) { return nodes_list(n); });
 
   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;
 
   dof_data.solution.resize(local_system_size);
 
   updateDOFsData(dof_data, nb_new_local_dofs, nb_new_pure_local,
                  nodes_list.size(),
                  [&nodes_list](UInt pos) -> UInt { return nodes_list[pos]; });
 
   return std::make_pair(nb_new_local_dofs, nb_new_pure_local);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::resizeGlobalArrays() {
   // resize all relevant arrays
   this->residual->resize();
   this->solution->resize();
   this->data_cache->resize();
 
   for (auto & lumped_matrix : lumped_matrices) {
     lumped_matrix.second->resize();
   }
 
   for (auto & matrix : matrices) {
     matrix.second->clearProfile();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onNodesAdded(const Array<UInt> & nodes_list,
                               const NewNodesEvent & /*unused*/) {
   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);
     }
   }
 
   this->resizeGlobalArrays();
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 class GlobalDOFInfoDataAccessor : public DataAccessor<UInt> {
 public:
   using size_type =
       typename std::unordered_map<UInt, std::vector<UInt>>::size_type;
 
   GlobalDOFInfoDataAccessor(DOFManager::DOFData & dof_data,
                             DOFManager & dof_manager)
       : dof_data(dof_data), dof_manager(dof_manager) {
     for (auto && pair :
          zip(dof_data.local_equation_number, dof_data.associated_nodes)) {
       UInt node;
       Int dof;
       std::tie(dof, node) = pair;
 
       dofs_per_node[node].push_back(dof);
     }
   }
 
   UInt getNbData(const Array<UInt> & nodes,
                  const SynchronizationTag & tag) const override {
     if (tag == SynchronizationTag::_ask_nodes or
         tag == SynchronizationTag::_giu_global_conn) {
       return nodes.size() * dof_data.dof->getNbComponent() * sizeof(Int);
     }
 
     return 0;
   }
 
   void packData(CommunicationBuffer & buffer, const Array<UInt> & nodes,
                 const SynchronizationTag & tag) const override {
     if (tag == SynchronizationTag::_ask_nodes or
         tag == SynchronizationTag::_giu_global_conn) {
       for (const auto & node : nodes) {
         const auto & dofs = dofs_per_node.at(node);
         for (const auto & dof : dofs) {
           buffer << dof_manager.global_equation_number(dof);
         }
       }
     }
   }
 
   void unpackData(CommunicationBuffer & buffer, const Array<UInt> & nodes,
                   const SynchronizationTag & tag) override {
     if (tag == SynchronizationTag::_ask_nodes or
         tag == SynchronizationTag::_giu_global_conn) {
       for (const auto & node : nodes) {
         const auto & dofs = dofs_per_node[node];
         for (const auto & dof : dofs) {
           Int global_dof;
           buffer >> global_dof;
           AKANTU_DEBUG_ASSERT(
               (dof_manager.global_equation_number(dof) == -1 or
                dof_manager.global_equation_number(dof) == global_dof),
               "This dof already had a global_dof_id which is different from "
               "the received one. "
                   << dof_manager.global_equation_number(dof)
                   << " != " << global_dof);
           dof_manager.global_equation_number(dof) = global_dof;
           dof_manager.global_to_local_mapping[global_dof] = dof;
         }
       }
     }
   }
 
 protected:
   std::unordered_map<UInt, std::vector<Int>> dofs_per_node;
   DOFManager::DOFData & dof_data;
   DOFManager & dof_manager;
 };
 
 /* -------------------------------------------------------------------------- */
 auto DOFManager::computeFirstDOFIDs(UInt nb_new_local_dofs,
                                     UInt nb_new_pure_local) {
   // determine the first local/global dof id to use
   UInt offset = 0;
 
   this->communicator.exclusiveScan(nb_new_pure_local, offset);
 
   auto first_global_dof_id = this->first_global_dof_id + offset;
   auto first_local_dof_id = this->local_system_size - nb_new_local_dofs;
 
   offset = nb_new_pure_local;
   this->communicator.allReduce(offset);
   this->first_global_dof_id += offset;
 
   return std::make_pair(first_local_dof_id, first_global_dof_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::updateDOFsData(DOFData & dof_data, UInt nb_new_local_dofs,
                                 UInt nb_new_pure_local, UInt nb_node,
                                 const std::function<UInt(UInt)> & getNode) {
   auto nb_local_dofs_added = nb_node * dof_data.dof->getNbComponent();
 
   auto first_dof_pos = dof_data.local_equation_number.size();
   dof_data.local_equation_number.reserve(dof_data.local_equation_number.size() +
                                          nb_local_dofs_added);
   dof_data.associated_nodes.reserve(dof_data.associated_nodes.size() +
                                     nb_local_dofs_added);
 
   this->dofs_flag.resize(this->local_system_size, NodeFlag::_normal);
   this->global_equation_number.resize(this->local_system_size, -1);
 
   std::unordered_map<std::pair<UInt, UInt>, UInt> masters_dofs;
 
   // update per dof info
   UInt local_eq_num;
   UInt first_global_dof_id;
   std::tie(local_eq_num, first_global_dof_id) =
       computeFirstDOFIDs(nb_new_local_dofs, nb_new_pure_local);
   for (auto d : arange(nb_local_dofs_added)) {
     auto node = getNode(d / dof_data.dof->getNbComponent());
     auto dof_flag = this->mesh->getNodeFlag(node);
 
     dof_data.associated_nodes.push_back(node);
     auto is_local_dof = this->mesh->isLocalOrMasterNode(node);
     auto is_periodic_slave = this->mesh->isPeriodicSlave(node);
     auto is_periodic_master = this->mesh->isPeriodicMaster(node);
 
     if (is_periodic_slave) {
       dof_data.local_equation_number.push_back(-1);
       continue;
     }
 
     // update equation numbers
     this->dofs_flag(local_eq_num) = dof_flag;
     dof_data.local_equation_number.push_back(local_eq_num);
 
     if (is_local_dof) {
       this->global_equation_number(local_eq_num) = first_global_dof_id;
       this->global_to_local_mapping[first_global_dof_id] = local_eq_num;
       ++first_global_dof_id;
     } else {
       this->global_equation_number(local_eq_num) = -1;
     }
 
     if (is_periodic_master) {
       auto node = getNode(d / dof_data.dof->getNbComponent());
       auto dof = d % dof_data.dof->getNbComponent();
       masters_dofs.insert(
           std::make_pair(std::make_pair(node, dof), local_eq_num));
     }
 
     ++local_eq_num;
   }
 
   // correct periodic slave equation numbers
   if (this->mesh->isPeriodic()) {
     auto assoc_begin = dof_data.associated_nodes.begin();
     for (auto d : arange(nb_local_dofs_added)) {
       auto node = dof_data.associated_nodes(first_dof_pos + d);
       if (not this->mesh->isPeriodicSlave(node)) {
         continue;
       }
 
       auto master_node = this->mesh->getPeriodicMaster(node);
       auto dof = d % dof_data.dof->getNbComponent();
       dof_data.local_equation_number(first_dof_pos + d) =
           masters_dofs[std::make_pair(master_node, dof)];
     }
   }
 
   // synchronize the global numbering for slaves nodes
   if (this->mesh->isDistributed()) {
     GlobalDOFInfoDataAccessor data_accessor(dof_data, *this);
 
     if (this->mesh->isPeriodic()) {
       mesh->getPeriodicNodeSynchronizer().synchronizeOnce(
           data_accessor, SynchronizationTag::_giu_global_conn);
     }
 
     auto & node_synchronizer = this->mesh->getNodeSynchronizer();
     node_synchronizer.synchronizeOnce(data_accessor,
                                       SynchronizationTag::_ask_nodes);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::updateDOFsData(DOFData & dof_data, UInt nb_new_local_dofs,
                                 UInt nb_new_pure_local) {
   dof_data.local_equation_number.reserve(dof_data.local_equation_number.size() +
                                          nb_new_local_dofs);
 
   UInt first_local_dof_id;
   UInt first_global_dof_id;
   std::tie(first_local_dof_id, first_global_dof_id) =
       computeFirstDOFIDs(nb_new_local_dofs, nb_new_pure_local);
 
   this->dofs_flag.resize(this->local_system_size, NodeFlag::_normal);
   this->global_equation_number.resize(this->local_system_size, -1);
 
   // update per dof info
   for (auto _ [[gnu::unused]] : arange(nb_new_local_dofs)) {
     // update equation numbers
     this->dofs_flag(first_local_dof_id) = NodeFlag::_normal;
 
     dof_data.local_equation_number.push_back(first_local_dof_id);
 
     this->global_equation_number(first_local_dof_id) = first_global_dof_id;
     this->global_to_local_mapping[first_global_dof_id] = first_local_dof_id;
 
     ++first_global_dof_id;
     ++first_local_dof_id;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onNodesRemoved(const Array<UInt> & /*unused*/,
                                 const Array<UInt> & /*unused*/,
                                 const RemovedNodesEvent & /*unused*/) {}
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onElementsAdded(const Array<Element> & /*unused*/,
                                  const NewElementsEvent & /*unused*/) {}
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onElementsRemoved(const Array<Element> & /*unused*/,
                                    const ElementTypeMapArray<UInt> & /*unused*/,
                                    const RemovedElementsEvent & /*unused*/) {}
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::onElementsChanged(const Array<Element> & /*unused*/,
                                    const Array<Element> & /*unused*/,
                                    const ElementTypeMapArray<UInt> & /*unused*/,
                                    const ChangedElementsEvent & /*unused*/) {}
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::updateGlobalBlockedDofs() {
   this->previous_global_blocked_dofs.copy(this->global_blocked_dofs);
   this->global_blocked_dofs.reserve(this->local_system_size, 0);
   this->previous_global_blocked_dofs_release =
       this->global_blocked_dofs_release;
 
   for (auto & pair : dofs) {
     if (not this->hasBlockedDOFs(pair.first)) {
       continue;
     }
 
     DOFData & dof_data = *pair.second;
     for (auto && data : zip(dof_data.getLocalEquationsNumbers(),
                             make_view(*dof_data.blocked_dofs))) {
       const auto & dof = std::get<0>(data);
       const auto & is_blocked = std::get<1>(data);
       if (is_blocked) {
         this->global_blocked_dofs.push_back(dof);
       }
     }
   }
 
   std::sort(this->global_blocked_dofs.begin(), this->global_blocked_dofs.end());
   auto last = std::unique(this->global_blocked_dofs.begin(),
                           this->global_blocked_dofs.end());
   this->global_blocked_dofs.resize(last - this->global_blocked_dofs.begin());
 
   auto are_equal =
       global_blocked_dofs.size() == previous_global_blocked_dofs.size() and
       std::equal(global_blocked_dofs.begin(), global_blocked_dofs.end(),
                  previous_global_blocked_dofs.begin());
 
   if (not are_equal) {
     ++this->global_blocked_dofs_release;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::applyBoundary(const ID & matrix_id) {
   auto & J = this->getMatrix(matrix_id);
 
   if (this->jacobian_release == J.getRelease()) {
     if (this->hasBlockedDOFsChanged()) {
       J.applyBoundary();
     }
 
     previous_global_blocked_dofs.copy(global_blocked_dofs);
   } else {
     J.applyBoundary();
   }
 
   this->jacobian_release = J.getRelease();
   this->previous_global_blocked_dofs_release =
           this->global_blocked_dofs_release;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::assembleMatMulVectToGlobalArray(const ID & dof_id,
                                                  const ID & A_id,
                                                  const Array<Real> & x,
                                                  SolverVector & array,
                                                  Real scale_factor) {
   auto & A = this->getMatrix(A_id);
 
   data_cache->resize();
   data_cache->zero();
   this->assembleToGlobalArray(dof_id, x, *data_cache, 1.);
 
   A.matVecMul(*data_cache, array, scale_factor, 1.);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManager::assembleMatMulVectToResidual(const ID & dof_id,
                                               const ID & A_id,
                                               const Array<Real> & x,
                                               Real scale_factor) {
   assembleMatMulVectToGlobalArray(dof_id, A_id, x, *residual, scale_factor);
 }
 
 } // namespace akantu
diff --git a/src/model/common/dof_manager/dof_manager.hh b/src/model/common/dof_manager/dof_manager.hh
index 2b3e6362a..5a511fd56 100644
--- a/src/model/common/dof_manager/dof_manager.hh
+++ b/src/model/common/dof_manager/dof_manager.hh
@@ -1,723 +1,723 @@
 /**
  * @file   dof_manager.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Aug 18 2015
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Class handling the different types of dofs
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "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;
 class SolverVector;
 class SolverCallback;
 } // namespace akantu
 
 namespace akantu {
 
 class DOFManager : protected MeshEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 protected:
   struct DOFData;
 
 public:
   DOFManager(const ID & id = "dof_manager");
   DOFManager(Mesh & mesh, const ID & id = "dof_manager");
   ~DOFManager() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 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 & support_group);
 
   /// 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,
                                   Array<Real> & array_to_assemble,
                                   Real scale_factor = 1.);
 
   /// Assemble an array to the global lumped matrix array
   virtual void assembleToLumpedMatrix(const ID & dof_id,
                                       Array<Real> & array_to_assemble,
                                       const ID & lumped_mtx,
                                       Real scale_factor = 1.);
 
   /**
    * 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,
       ElementType type, GhostType ghost_type,
       Real scale_factor = 1.,
-      const Array<UInt> & filter_elements = empty_filter);
+      const Array<Int> & 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,
       ElementType type, GhostType ghost_type,
       Real scale_factor = 1.,
-      const Array<UInt> & filter_elements = empty_filter);
+      const Array<Int> & 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, ElementType type,
-      GhostType ghost_type, Real scale_factor = 1.,
-      const Array<UInt> & filter_elements = empty_filter);
+      const ID & lumped_mtx, const ElementType & type,
+      const GhostType & ghost_type, Real scale_factor = 1.,
+      const Array<Int> & 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, ElementType type,
       GhostType ghost_type = _not_ghost,
       const MatrixType & elemental_matrix_type = _symmetric,
-      const Array<UInt> & filter_elements = empty_filter) = 0;
+      const Array<Int> & filter_elements = empty_filter) = 0;
 
   /// multiply a vector by a matrix and assemble the result to the residual
   virtual void assembleMatMulVectToArray(const ID & dof_id, const ID & A_id,
                                          const Array<Real> & x,
                                          Array<Real> & array,
                                          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;
 
   /// 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);
 
   /// multiply the dofs by a matrix and assemble the result to the residual
   virtual void assembleMatMulDOFsToResidual(const ID & A_id,
                                             Real scale_factor = 1);
 
   /// updates the global blocked_dofs array
   virtual void updateGlobalBlockedDofs();
 
   /// sets the residual to 0
   virtual void zeroResidual();
   /// sets the matrix to 0
   virtual void zeroMatrix(const ID & mtx);
   /// sets the lumped matrix to 0
   virtual void zeroLumpedMatrix(const ID & mtx);
 
   virtual void applyBoundary(const ID & matrix_id = "J");
   // virtual void applyBoundaryLumped(const ID & matrix_id = "J");
 
   /// extract a lumped matrix part corresponding to a given dof
   virtual void getLumpedMatrixPerDOFs(const ID & dof_id, const ID & lumped_mtx,
                                       Array<Real> & lumped);
 
   /// splits the solution storage from a global view to the per dof storages
   void splitSolutionPerDOFs();
 
 private:
   /// dispatch the creation of the dof data and register it
   DOFData & getNewDOFDataInternal(const ID & dof_id);
 
 protected:
   /// common function to help registering dofs the return values are the add new
   /// numbers of local dofs, pure local dofs, and system size
   virtual std::tuple<UInt, UInt, UInt>
   registerDOFsInternal(const ID & dof_id, Array<Real> & dofs_array);
 
   /// 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);
 
   /// fill a Vector with the equation numbers corresponding to the given
   /// connectivity
   static inline void extractElementEquationNumber(
       const Array<Int> & equation_numbers, const Vector<UInt> & connectivity,
       UInt nb_degree_of_freedom, Vector<Int> & element_equation_number);
 
   /// Assemble a array to a global one
   void assembleMatMulVectToGlobalArray(const ID & dof_id, const ID & A_id,
                                        const Array<Real> & x,
                                        SolverVector & array,
                                        Real scale_factor = 1.);
 
   /// common function that can be called by derived class with proper matrice
   /// types
   template <typename Mat>
   void assemblePreassembledMatrix_(Mat & A, const ID & dof_id_m,
                                    const ID & dof_id_n,
                                    const TermsToAssemble & terms);
 
   template <typename Mat>
   void assembleElementalMatricesToMatrix_(
       Mat & A, const ID & dof_id, const Array<Real> & elementary_mat,
       ElementType type, GhostType ghost_type,
       const MatrixType & elemental_matrix_type,
-      const Array<UInt> & filter_elements);
+      const Array<Int> & filter_elements);
 
   template <typename Vec>
   void assembleMatMulVectToArray_(const ID & dof_id, const ID & A_id,
                                   const Array<Real> & x, Array<Real> & array,
                                   Real scale_factor);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// 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);
 
   /// Answer to the question is a dof a slave dof ?
   inline bool isPureGhostDOF(UInt local_dof_num);
 
   /// tells if the dof manager knows about a global dof
   bool hasGlobalEquationNumber(Int global) const;
 
   /// return the local index of the global equation number
   inline Int globalToLocalEquationNumber(Int global) const;
 
   /// converts local equation numbers to global equation numbers;
   inline Int localToGlobalEquationNumber(Int local) const;
 
   /// get the array of dof types (use only if you know what you do...)
   inline NodeFlag getDOFFlag(Int local_id) const;
 
   /// defines if the boundary changed
   bool hasBlockedDOFsChanged() {
     return  this->global_blocked_dofs_release !=
         this->previous_global_blocked_dofs_release;
   }
 
   /// 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);
 
   /// Pure local number of dofs
   AKANTU_GET_MACRO(PureLocalSystemSize, this->pure_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 & dof_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;
 
   /// Get a reference to the solution array registered for the given id
   inline Array<Real> & getSolution(const ID & dofs_id);
 
   /// Get the blocked dofs array
   AKANTU_GET_MACRO(GlobalBlockedDOFs, global_blocked_dofs, const Array<Int> &);
   /// Get the blocked dofs array
   AKANTU_GET_MACRO(PreviousGlobalBlockedDOFs, previous_global_blocked_dofs,
                    const Array<Int> &);
 
   /* ------------------------------------------------------------------------ */
   /* 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 equation numbers corresponding to a dof_id. This might be used to
   /// access the matrix.
-  inline const Array<Int> & getLocalEquationsNumbers(const ID & dof_id) const;
+  inline decltype(auto) getLocalEquationsNumbers(const ID & dof_id) const;
 
 protected:
   /// get the array of dof types (use only if you know what you do...)
-  inline const Array<UInt> & getDOFsAssociatedNodes(const ID & dof_id) const;
+  inline decltype(auto)  getDOFsAssociatedNodes(const ID & dof_id) const;
 
 protected:
   /* ------------------------------------------------------------------------ */
   /// register a matrix
   SparseMatrix & registerSparseMatrix(const ID & matrix_id,
                                       std::unique_ptr<SparseMatrix> & matrix);
 
   /// register a lumped matrix (aka a Vector)
   SolverVector & registerLumpedMatrix(const ID & matrix_id,
                                       std::unique_ptr<SolverVector> & 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);
 
   template <class NLSType, class DMType>
   NonLinearSolver & registerNonLinearSolver(DMType & dm, const ID & id,
                                             const NonLinearSolverType & type) {
     ID non_linear_solver_id = this->id + ":nls:" + id;
     std::unique_ptr<NonLinearSolver> nls = std::make_unique<NLSType>(
         dm, type, non_linear_solver_id);
     return this->registerNonLinearSolver(non_linear_solver_id, nls);
   }
 
   template <class TSSType, class DMType>
   TimeStepSolver & registerTimeStepSolver(DMType & dm, const ID & id,
                                           const TimeStepSolverType & type,
                                           NonLinearSolver & non_linear_solver,
                                           SolverCallback & solver_callback) {
     ID time_step_solver_id = this->id + ":tss:" + id;
     std::unique_ptr<TimeStepSolver> tss =
         std::make_unique<TSSType>(dm, type, non_linear_solver, solver_callback,
                                   time_step_solver_id);
     return this->registerTimeStepSolver(time_step_solver_id, tss);
   }
 
   template <class MatType, class DMType>
   SparseMatrix & registerSparseMatrix(DMType & dm, const ID & id,
                                       const MatrixType & matrix_type) {
     ID matrix_id = this->id + ":mtx:" + id;
     std::unique_ptr<SparseMatrix> sm =
         std::make_unique<MatType>(dm, matrix_type, matrix_id);
     return this->registerSparseMatrix(matrix_id, sm);
   }
 
   template <class MatType>
   SparseMatrix & registerSparseMatrix(const ID & id,
                                       const ID & matrix_to_copy_id) {
     ID matrix_id = this->id + ":mtx:" + id;
     auto & sm_to_copy =
         aka::as_type<MatType>(this->getMatrix(matrix_to_copy_id));
     std::unique_ptr<SparseMatrix> sm =
         std::make_unique<MatType>(sm_to_copy, matrix_id);
     return this->registerSparseMatrix(matrix_id, sm);
   }
 
   template <class MatType, class DMType>
   SolverVector & registerLumpedMatrix(DMType & dm, const ID & id) {
     ID matrix_id = this->id + ":lumped_mtx:" + id;
     std::unique_ptr<SolverVector> sm = std::make_unique<MatType>(dm, matrix_id);
     return this->registerLumpedMatrix(matrix_id, sm);
   }
 
 protected:
   virtual void makeConsistentForPeriodicity(const ID & dof_id,
                                             SolverVector & array) = 0;
 
   virtual void assembleToGlobalArray(const ID & dof_id,
                                      const Array<Real> & array_to_assemble,
                                      SolverVector & global_array,
                                      Real scale_factor) = 0;
 
 public:
   /// extract degrees of freedom (identified by ID) from a global solver array
   virtual void getArrayPerDOFs(const ID & dof_id, const SolverVector & global,
                                Array<Real> & local) = 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 SolverVector & getNewLumpedMatrix(const ID & matrix_id) = 0;
   /// Get the lumped version of a given matrix
   const SolverVector & getLumpedMatrix(const ID & matrix_id) const;
   /// Get the lumped version of a given matrix
   SolverVector & 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,
                        SolverCallback & solver_callback) = 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 != nullptr) {
       return *mesh;
     }
     AKANTU_EXCEPTION("No mesh registered in this dof manager");
   }
 
   /* ------------------------------------------------------------------------ */
   AKANTU_GET_MACRO(Communicator, communicator, const auto &);
   AKANTU_GET_MACRO_NOT_CONST(Communicator, communicator, auto &);
 
   /* ------------------------------------------------------------------------ */
   AKANTU_GET_MACRO(Solution, *(solution.get()), const auto &);
   AKANTU_GET_MACRO_NOT_CONST(Solution, *(solution.get()), auto &);
 
   AKANTU_GET_MACRO(Residual, *(residual.get()), const auto &);
   AKANTU_GET_MACRO_NOT_CONST(Residual, *(residual.get()), auto &);
 
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler interface                                               */
   /* ------------------------------------------------------------------------ */
 protected:
   friend class GlobalDOFInfoDataAccessor;
   /// helper function for the DOFManager::onNodesAdded method
-  virtual std::pair<UInt, UInt> updateNodalDOFs(const ID & dof_id,
+  virtual std::pair<Int, Int> updateNodalDOFs(const ID & dof_id,
                                                 const Array<UInt> & nodes_list);
 
   template <typename Func>
-  auto countDOFsForNodes(const DOFData & dof_data, UInt nb_nodes,
+  auto countDOFsForNodes(const DOFData & dof_data, Int nb_nodes,
                          Func && getNode);
 
-  void updateDOFsData(DOFData & dof_data, UInt nb_new_local_dofs,
-                      UInt nb_new_pure_local, UInt nb_nodes,
-                      const std::function<UInt(UInt)> & getNode);
+  void updateDOFsData(DOFData & dof_data, Int nb_new_local_dofs,
+                      Int nb_new_pure_local, Int nb_nodes,
+                      const std::function<Idx(Idx)> & getNode);
 
-  void updateDOFsData(DOFData & dof_data, UInt nb_new_local_dofs,
-                      UInt nb_new_pure_local);
+  void updateDOFsData(DOFData & dof_data, Int nb_new_local_dofs,
+                      Int nb_new_pure_local);
 
-  auto computeFirstDOFIDs(UInt nb_new_local_dofs, UInt nb_new_pure_local);
+  auto computeFirstDOFIDs(Int nb_new_local_dofs, Int nb_new_pure_local);
 
   /// resize all the global information and takes the needed measure like
   /// cleaning matrices profiles
   virtual void resizeGlobalArrays();
 
 public:
   /// function to implement to react on  akantu::NewNodesEvent
-  void onNodesAdded(const Array<UInt> & nodes_list,
+  void onNodesAdded(const Array<Idx> & nodes_list,
                     const NewNodesEvent & event) override;
   /// function to implement to react on  akantu::RemovedNodesEvent
-  void onNodesRemoved(const Array<UInt> & nodes_list,
-                      const Array<UInt> & new_numbering,
+  void onNodesRemoved(const Array<Idx> & nodes_list,
+                      const Array<Idx> & new_numbering,
                       const RemovedNodesEvent & event) override;
   /// function to implement to react on  akantu::NewElementsEvent
   void onElementsAdded(const Array<Element> & elements_list,
                        const NewElementsEvent & event) override;
   /// function to implement to react on  akantu::RemovedElementsEvent
   void onElementsRemoved(const Array<Element> & elements_list,
-                         const ElementTypeMapArray<UInt> & new_numbering,
+                         const ElementTypeMapArray<Idx> & new_numbering,
                          const RemovedElementsEvent & event) override;
   /// function to implement to react on  akantu::ChangedElementsEvent
   void onElementsChanged(const Array<Element> & old_elements_list,
                          const Array<Element> & new_elements_list,
-                         const ElementTypeMapArray<UInt> & new_numbering,
+                         const ElementTypeMapArray<Idx> & new_numbering,
                          const ChangedElementsEvent & event) override;
 
 protected:
   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 std::unique_ptr<DOFData> getNewDOFData(const ID & dof_id) = 0;
 
   /* ------------------------------------------------------------------------ */
   /* 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{nullptr};
 
     /// Blocked degree of freedoms array
     Array<bool> * blocked_dofs{nullptr};
 
     /// Degree of freedoms increment
     Array<Real> * increment{nullptr};
 
     /// Degree of freedoms at previous step
     Array<Real> * previous{nullptr};
 
     /// Solution associated to the dof
     Array<Real> solution;
 
     /* ---------------------------------------------------------------------- */
     /* data for dynamic simulations                                           */
     /* ---------------------------------------------------------------------- */
     /// Degree of freedom derivatives arrays
     std::vector<Array<Real> *> dof_derivatives;
 
     /* ---------------------------------------------------------------------- */
     /// number of dofs to consider locally for this dof id
-    UInt local_nb_dofs{0};
+    Int local_nb_dofs{0};
 
     /// Number of purely local dofs
-    UInt pure_local_nb_dofs{0};
+    Int pure_local_nb_dofs{0};
 
     /// number of ghost dofs
-    UInt ghosts_nb_dofs{0};
+    Int ghosts_nb_dofs{0};
 
     /// local numbering equation numbers
-    Array<Int> local_equation_number;
+    Array<Idx> local_equation_number;
 
     /// associated node for _dst_nodal dofs only
-    Array<UInt> associated_nodes;
+    Array<Idx> associated_nodes;
 
-    virtual Array<Int> & getLocalEquationsNumbers() {
+    virtual Array<Idx> & getLocalEquationsNumbers() {
       return local_equation_number;
     }
   };
 
   /// 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<SolverVector>>;
 
   /// 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>>;
 
   ID id;
 
   /// store a reference to the dof arrays
   DOFStorage dofs;
 
   /// list of sparse matrices that where created
   SparseMatricesMap matrices;
 
   /// list of lumped matrices
   LumpedMatricesMap lumped_matrices;
 
   /// non linear solvers storage
   NonLinearSolversMap non_linear_solvers;
 
   /// time step solvers storage
   TimeStepSolversMap time_step_solvers;
 
   /// reference to the underlying mesh
   Mesh * mesh{nullptr};
 
   /// Total number of degrees of freedom (size with the ghosts)
   UInt local_system_size{0};
 
   /// Number of purely local dofs (size without the ghosts)
   UInt pure_local_system_size{0};
 
   /// Total number of degrees of freedom
   UInt system_size{0};
 
   /// rhs to the system of equation corresponding to the residual linked to the
   /// different dofs
   std::unique_ptr<SolverVector> residual;
 
   /// solution of the system of equation corresponding to the different dofs
   std::unique_ptr<SolverVector> solution;
 
   /// a vector that helps internally to perform some tasks
   std::unique_ptr<SolverVector> data_cache;
 
   /// define the dofs type, local, shared, ghost
   Array<NodeFlag> dofs_flag;
 
   /// equation number in global numbering
   Array<Int> global_equation_number;
 
   using equation_numbers_map = std::unordered_map<Int, Int>;
 
   /// dual information of global_equation_number
   equation_numbers_map global_to_local_mapping;
 
   /// Communicator used for this manager, should be the same as in the mesh if a
   /// mesh is registered
   Communicator & communicator;
 
   /// accumulator to know what would be the next global id to use
   UInt first_global_dof_id{0};
 
   /// Release at last apply boundary on jacobian
   UInt jacobian_release{0};
 
   /// blocked degree of freedom in the system equation corresponding to the
   /// different dofs
   Array<Int> global_blocked_dofs;
 
   UInt global_blocked_dofs_release{0};
 
   /// blocked degree of freedom in the system equation corresponding to the
   /// different dofs
   Array<Int> previous_global_blocked_dofs;
 
   UInt previous_global_blocked_dofs_release{0};
 
 private:
   /// This is for unit testing
   friend class DOFManagerTester;
 };
 
 using DefaultDOFManagerFactory =
     Factory<DOFManager, ID, const ID &>;
 using DOFManagerFactory =
     Factory<DOFManager, ID, Mesh &, const ID &>;
 
 } // namespace akantu
 
 #include "dof_manager_inline_impl.hh"
 
 #endif /* AKANTU_DOF_MANAGER_HH_ */
diff --git a/src/model/common/dof_manager/dof_manager_default.cc b/src/model/common/dof_manager/dof_manager_default.cc
index feda05c7d..c1b90e0a9 100644
--- a/src/model/common/dof_manager/dof_manager_default.cc
+++ b/src/model/common/dof_manager/dof_manager_default.cc
@@ -1,491 +1,491 @@
 /**
  * @file   dof_manager_default.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Aug 18 2015
  * @date last modification: Tue Mar 30 2021
  *
  * @brief  Implementation of the default DOFManager
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "communicator.hh"
 #include "dof_synchronizer.hh"
 #include "element_group.hh"
 #include "non_linear_solver_default.hh"
 #include "periodic_node_synchronizer.hh"
 #include "solver_vector_default.hh"
 #include "solver_vector_distributed.hh"
 #include "sparse_matrix_aij.hh"
 #include "time_step_solver_default.hh"
 
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <memory>
 #include <numeric>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 DOFManagerDefault::DOFManagerDefault(const ID & id)
     : DOFManager(id), synchronizer(nullptr) {
   residual = std::make_unique<SolverVectorDefault>(
       *this, std::string(id + ":residual"));
   solution = std::make_unique<SolverVectorDefault>(
       *this, std::string(id + ":solution"));
   data_cache = std::make_unique<SolverVectorDefault>(
       *this, std::string(id + ":data_cache"));
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManagerDefault::DOFManagerDefault(Mesh & mesh, const ID & id)
     : DOFManager(mesh, id), synchronizer(nullptr) {
   if (this->mesh->isDistributed()) {
     this->synchronizer = std::make_unique<DOFSynchronizer>(
         *this, this->id + ":dof_synchronizer");
     residual = std::make_unique<SolverVectorDistributed>(
         *this, std::string(id + ":residual"));
     solution = std::make_unique<SolverVectorDistributed>(
         *this, std::string(id + ":solution"));
     data_cache = std::make_unique<SolverVectorDistributed>(
         *this, std::string(id + ":data_cache"));
 
   } else {
     residual = std::make_unique<SolverVectorDefault>(
         *this, std::string(id + ":residual"));
     solution = std::make_unique<SolverVectorDefault>(
         *this, std::string(id + ":solution"));
     data_cache = std::make_unique<SolverVectorDefault>(
         *this, std::string(id + ":data_cache"));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManagerDefault::~DOFManagerDefault() = default;
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::makeConsistentForPeriodicity(const ID & dof_id,
                                                      SolverVector & array) {
   auto & dof_data = this->getDOFDataTyped<DOFDataDefault>(dof_id);
   if (dof_data.support_type != _dst_nodal) {
     return;
   }
 
   if (not mesh->isPeriodic()) {
     return;
   }
 
   this->mesh->getPeriodicNodeSynchronizer()
       .reduceSynchronizeWithPBCSlaves<AddOperation>(
           aka::as_type<SolverVectorDefault>(array).getVector());
 }
 
 /* -------------------------------------------------------------------------- */
 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();
 
   auto & dof_data = this->getDOFDataTyped<DOFDataDefault>(dof_id);
   AKANTU_DEBUG_ASSERT(dof_data.local_equation_number.size() ==
                           array_to_assemble.size() *
                               array_to_assemble.getNbComponent(),
                       "The array to assemble does not have a correct size."
                           << " (" << array_to_assemble.getID() << ")");
 
   if (dof_data.support_type == _dst_nodal and mesh->isPeriodic()) {
     for (auto && data :
          zip(dof_data.local_equation_number, dof_data.associated_nodes,
              make_view(array_to_assemble))) {
       auto && equ_num = std::get<0>(data);
       // auto && node = std::get<1>(data);
       auto && arr = std::get<2>(data);
 
       // Guillaume to Nico:
       // This filter of periodic slave should not be.
       // Indeed you want to get the contribution even
       // from periodic slaves and cumulate to the right
       // equation number.
 
       global_array(equ_num) += scale_factor * (arr);
       // scale_factor * (arr) * (not this->mesh->isPeriodicSlave(node));
     }
   } else {
     for (auto && data :
          zip(dof_data.local_equation_number, make_view(array_to_assemble))) {
       auto && equ_num = std::get<0>(data);
       auto && arr = std::get<1>(data);
       global_array(equ_num) += scale_factor * (arr);
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assembleToGlobalArray(
     const ID & dof_id, const Array<Real> & array_to_assemble,
     SolverVector & global_array_v, Real scale_factor) {
 
   assembleToGlobalArray(
       dof_id, array_to_assemble,
       aka::as_type<SolverVectorDefault>(global_array_v).getVector(),
       scale_factor);
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManagerDefault::DOFDataDefault::DOFDataDefault(const ID & dof_id)
     : DOFData(dof_id) {}
 
 /* -------------------------------------------------------------------------- */
 auto DOFManagerDefault::getNewDOFData(const ID & dof_id)
     -> std::unique_ptr<DOFData> {
   return std::make_unique<DOFDataDefault>(dof_id);
 }
 
 /* -------------------------------------------------------------------------- */
 std::tuple<UInt, UInt, UInt>
 DOFManagerDefault::registerDOFsInternal(const ID & dof_id,
                                         Array<Real> & dofs_array) {
   auto ret = DOFManager::registerDOFsInternal(dof_id, dofs_array);
 
   // update the synchronizer if needed
   if (this->synchronizer) {
     this->synchronizer->registerDOFs(dof_id);
   }
 
   return ret;
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix & DOFManagerDefault::getNewMatrix(const ID & id,
                                                const MatrixType & matrix_type) {
   return this->registerSparseMatrix<SparseMatrixAIJ>(*this, id, matrix_type);
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix & DOFManagerDefault::getNewMatrix(const ID & id,
                                                const ID & matrix_to_copy_id) {
   return this->registerSparseMatrix<SparseMatrixAIJ>(id, matrix_to_copy_id);
 }
 
 /* -------------------------------------------------------------------------- */
 SolverVector & DOFManagerDefault::getNewLumpedMatrix(const ID & id) {
   return this->registerLumpedMatrix<SolverVectorDefault>(*this, id);
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrixAIJ & DOFManagerDefault::getMatrix(const ID & id) {
   auto & matrix = DOFManager::getMatrix(id);
   return aka::as_type<SparseMatrixAIJ>(matrix);
 }
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver &
 DOFManagerDefault::getNewNonLinearSolver(const ID & id,
                                          const NonLinearSolverType & type) {
   switch (type) {
 #if defined(AKANTU_USE_MUMPS)
   case NonLinearSolverType::_newton_raphson:
     /* FALLTHRU */
     /* [[fallthrough]]; un-comment when compiler will get it */
   case NonLinearSolverType::_newton_raphson_contact:
   case NonLinearSolverType::_newton_raphson_modified: {
     return this->registerNonLinearSolver<NonLinearSolverNewtonRaphson>(
         *this, id, type);
   }
   case NonLinearSolverType::_linear: {
     return this->registerNonLinearSolver<NonLinearSolverLinear>(*this, id,
                                                                 type);
   }
 #endif
   case NonLinearSolverType::_lumped: {
     return this->registerNonLinearSolver<NonLinearSolverLumped>(*this, id,
                                                                 type);
   }
   default:
     AKANTU_EXCEPTION("The asked type of non linear solver is not supported by "
                      "this dof manager");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver & DOFManagerDefault::getNewTimeStepSolver(
     const ID & id, const TimeStepSolverType & type,
     NonLinearSolver & non_linear_solver, SolverCallback & solver_callback) {
   return this->registerTimeStepSolver<TimeStepSolverDefault>(
       *this, id, type, non_linear_solver, solver_callback);
 }
 
 /* -------------------------------------------------------------------------- */
 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<Int> & equation_number = this->getLocalEquationsNumbers(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::getArrayPerDOFs(const ID & dof_id,
                                         const SolverVector & global_array,
                                         Array<Real> & local_array) {
   getArrayPerDOFs(dof_id,
                   aka::as_type<SolverVectorDefault>(global_array).getVector(),
                   local_array);
 }
 
 /* -------------------------------------------------------------------------- */
 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);
   auto & cache = aka::as_type<SolverVectorArray>(*this->data_cache);
 
   cache.zero();
   this->assembleToGlobalArray(dof_id, x, cache.getVector(), scale_factor);
 
   for (auto && data : zip(make_view(A), make_view(cache.getVector()),
                           make_view(this->getResidualArray()))) {
     const auto & A = std::get<0>(data);
     const auto & x = std::get<1>(data);
     auto & r = std::get<2>(data);
     r += A * x;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assembleElementalMatricesToMatrix(
     const ID & matrix_id, const ID & dof_id, const Array<Real> & elementary_mat,
     ElementType type, GhostType ghost_type,
     const MatrixType & elemental_matrix_type,
-    const Array<UInt> & filter_elements) {
+    const Array<Int> & filter_elements) {
   this->addToProfile(matrix_id, dof_id, type, ghost_type);
   auto & A = getMatrix(matrix_id);
   DOFManager::assembleElementalMatricesToMatrix_(
       A, dof_id, elementary_mat, type, ghost_type, elemental_matrix_type,
       filter_elements);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assemblePreassembledMatrix(
     const ID & dof_id_m, const ID & dof_id_n, const ID & matrix_id,
     const TermsToAssemble & terms) {
   auto & A = getMatrix(matrix_id);
   DOFManager::assemblePreassembledMatrix_(A, dof_id_m, dof_id_n, terms);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::assembleMatMulVectToArray(const ID & dof_id,
                                                   const ID & A_id,
                                                   const Array<Real> & x,
                                                   Array<Real> & array,
                                                   Real scale_factor) {
   if (mesh->isDistributed()) {
     DOFManager::assembleMatMulVectToArray_<SolverVectorDistributed>(
         dof_id, A_id, x, array, scale_factor);
   } else {
     DOFManager::assembleMatMulVectToArray_<SolverVectorDefault>(
         dof_id, A_id, x, array, scale_factor);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::addToProfile(const ID & matrix_id, const ID & dof_id,
                                      ElementType type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   const auto & 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;
   }
 
   auto nb_degree_of_freedom_per_node = dof_data.dof->getNbComponent();
 
   const auto & equation_number = this->getLocalEquationsNumbers(dof_id);
 
   auto & A = this->getMatrix(matrix_id);
   A.resize(system_size);
   auto size = A.size();
 
   auto 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;
 
   auto nb_elements = connectivity.size();
   UInt * ge_it = nullptr;
   if (dof_data.group_support != "__mesh__") {
     const auto & 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<Int> element_eq_nb(size_mat);
 
   for (UInt e = 0; e < nb_elements; ++e) {
     if (ge_it != nullptr) {
       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(),
         [&](auto & local) { return this->localToGlobalEquationNumber(local); });
 
     if (ge_it != nullptr) {
       ++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();
 }
 
 /* -------------------------------------------------------------------------- */
 Array<Real> & DOFManagerDefault::getSolutionArray() {
   return dynamic_cast<SolverVectorDefault *>(this->solution.get())->getVector();
 }
 
 /* -------------------------------------------------------------------------- */
 const Array<Real> & DOFManagerDefault::getResidualArray() const {
   return dynamic_cast<SolverVectorDefault *>(this->residual.get())->getVector();
 }
 
 /* -------------------------------------------------------------------------- */
 Array<Real> & DOFManagerDefault::getResidualArray() {
   return dynamic_cast<SolverVectorDefault *>(this->residual.get())->getVector();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::onNodesAdded(const Array<UInt> & nodes_list,
                                      const NewNodesEvent & event) {
   DOFManager::onNodesAdded(nodes_list, event);
 
   if (this->synchronizer) {
     this->synchronizer->onNodesAdded(nodes_list);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::resizeGlobalArrays() {
   DOFManager::resizeGlobalArrays();
 
   this->global_blocked_dofs.resize(this->local_system_size, 1);
   this->previous_global_blocked_dofs.resize(this->local_system_size, 1);
 
   matrix_profiled_dofs.clear();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerDefault::updateGlobalBlockedDofs() {
   DOFManager::updateGlobalBlockedDofs();
 
   if (this->global_blocked_dofs_release ==
       this->previous_global_blocked_dofs_release) {
     return;
   }
 
   global_blocked_dofs_uint.resize(local_system_size);
   global_blocked_dofs_uint.set(false);
   for (const auto & dof : global_blocked_dofs) {
     global_blocked_dofs_uint[dof] = true;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 Array<bool> & DOFManagerDefault::getBlockedDOFs() {
   return global_blocked_dofs_uint;
 }
 
 /* -------------------------------------------------------------------------- */
 const Array<bool> & DOFManagerDefault::getBlockedDOFs() const {
   return global_blocked_dofs_uint;
 }
 
 /* -------------------------------------------------------------------------- */
 static bool dof_manager_is_registered [[gnu::unused]] =
     DOFManagerFactory::getInstance().registerAllocator(
         "default",
         [](Mesh & mesh, const ID & id) -> std::unique_ptr<DOFManager> {
           return std::make_unique<DOFManagerDefault>(mesh, id);
         });
 
 static bool dof_manager_is_registered_mumps [[gnu::unused]] =
     DOFManagerFactory::getInstance().registerAllocator(
         "mumps",
         [](Mesh & mesh, const ID & id) -> std::unique_ptr<DOFManager> {
           return std::make_unique<DOFManagerDefault>(mesh, id);
         });
 
 } // namespace akantu
diff --git a/src/model/common/dof_manager/dof_manager_default.hh b/src/model/common/dof_manager/dof_manager_default.hh
index f12072ff8..1cf8d7699 100644
--- a/src/model/common/dof_manager/dof_manager_default.hh
+++ b/src/model/common/dof_manager/dof_manager_default.hh
@@ -1,255 +1,255 @@
 /**
  * @file   dof_manager_default.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Aug 18 2015
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Default implementation of the dof manager
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 <functional>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_DOF_MANAGER_DEFAULT_HH_
 #define AKANTU_DOF_MANAGER_DEFAULT_HH_
 
 namespace akantu {
 class SparseMatrixAIJ;
 class NonLinearSolverDefault;
 class TimeStepSolverDefault;
 class DOFSynchronizer;
 } // namespace akantu
 
 namespace akantu {
 
 class DOFManagerDefault : public DOFManager {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DOFManagerDefault(const ID & id = "dof_manager_default");
   DOFManagerDefault(Mesh & mesh, const ID & id = "dof_manager_default");
   ~DOFManagerDefault() override;
 
 protected:
   struct DOFDataDefault : public DOFData {
     explicit DOFDataDefault(const ID & dof_id);
   };
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 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 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, ElementType type,
-      GhostType ghost_type, const MatrixType & elemental_matrix_type,
-      const Array<UInt> & filter_elements) override;
+      const Array<Real> & elementary_mat, const ElementType & type,
+      const GhostType & ghost_type, const MatrixType & elemental_matrix_type,
+      const Array<Int> & filter_elements) override;
 
   void assembleMatMulVectToArray(const ID & dof_id, const ID & A_id,
                                  const Array<Real> & x, Array<Real> & array,
                                  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:
   void assembleToGlobalArray(const ID & dof_id,
                              const Array<Real> & array_to_assemble,
                              SolverVector & global_array,
                              Real scale_factor) override;
 
   template <typename T>
   void assembleToGlobalArray(const ID & dof_id,
                              const Array<T> & array_to_assemble,
                              Array<T> & global_array, T scale_factor);
 
   void getArrayPerDOFs(const ID & dof_id, const SolverVector & global,
                        Array<Real> & local) override;
 
   template <typename T>
   void getArrayPerDOFs(const ID & dof_id, const Array<T> & global_array,
                        Array<T> & local_array) const;
   void makeConsistentForPeriodicity(const ID & dof_id,
                                     SolverVector & array) override;
 
 public:
   /// update the global dofs vector
   void updateGlobalBlockedDofs() override;
 
   //   /// apply boundary conditions to jacobian matrix
   //   void applyBoundary(const ID & matrix_id = "J") override;
 
 private:
   /// Add a symmetric matrices to a symmetric sparse matrix
   void addSymmetricElementalMatrixToSymmetric(
       SparseMatrixAIJ & matrix, const Matrix<Real> & element_mat,
       const Vector<Int> & 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<Int> & equation_numbers, UInt max_size);
 
   /// Add a matrices to a unsymmetric sparse matrix
   void addElementalMatrixToUnsymmetric(SparseMatrixAIJ & matrix,
                                        const Matrix<Real> & element_mat,
                                        const Vector<Int> & equation_numbers,
                                        UInt max_size);
 
   void addToProfile(const ID & matrix_id, const ID & dof_id,
                     ElementType type, GhostType ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler interface                                               */
   /* ------------------------------------------------------------------------ */
 protected:
   std::tuple<UInt, UInt, UInt>
   registerDOFsInternal(const ID & dof_id, Array<Real> & dofs_array) override;
 
   // std::pair<UInt, UInt>
   // updateNodalDOFs(const ID & dof_id, const Array<UInt> & nodes_list)
   // override;
 
   void resizeGlobalArrays() override;
 
 public:
   /// function to implement to react on  akantu::NewNodesEvent
-  void onNodesAdded(const Array<UInt> & nodes_list,
+  void onNodesAdded(const Array<Idx> & 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);
 
   /// Get an instance of a new lumped matrix
   SolverVector & getNewLumpedMatrix(const ID & matrix_id) override;
 
   /* ------------------------------------------------------------------------ */
   /* 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,
                        SolverCallback & solver_callback) override;
 
   /* ------------------------------------------------------------------------ */
 private:
   /// Get the solution array
   Array<Real> & getSolutionArray();
 
   /// Get the residual array
   const Array<Real> & getResidualArray() const;
 
   /// Get the residual array
   Array<Real> & getResidualArray();
 
 public:
   /// access the internal dof_synchronizer
   AKANTU_GET_MACRO_NOT_CONST(Synchronizer, *synchronizer, DOFSynchronizer &);
 
   /// access the internal dof_synchronizer
   bool hasSynchronizer() const { return synchronizer != nullptr; }
 
   Array<bool> & getBlockedDOFs();
   const Array<bool> & getBlockedDOFs() const;
 
 protected:
   std::unique_ptr<DOFData> getNewDOFData(const ID & dof_id) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   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;
 
   /// synchronizer to maintain coherency in dof fields
   std::unique_ptr<DOFSynchronizer> synchronizer;
 
   friend class DOFSynchronizer;
 
   /// Array containing the true or false if the node is in global_blocked_dofs
   Array<bool> global_blocked_dofs_uint;
 };
 
 } // namespace akantu
 
 #include "dof_manager_default_inline_impl.hh"
 
 #endif /* AKANTU_DOF_MANAGER_DEFAULT_HH_ */
diff --git a/src/model/common/dof_manager/dof_manager_inline_impl.hh b/src/model/common/dof_manager/dof_manager_inline_impl.hh
index b8430b4a1..9a2d577b9 100644
--- a/src/model/common/dof_manager/dof_manager_inline_impl.hh
+++ b/src/model/common/dof_manager/dof_manager_inline_impl.hh
@@ -1,337 +1,337 @@
 /**
  * @file   dof_manager_inline_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  inline functions of the dof manager
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "solver_vector.hh"
 #include "sparse_matrix.hh"
 #include "terms_to_assemble.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_DOF_MANAGER_INLINE_IMPL_HH_
 #define AKANTU_DOF_MANAGER_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasDOFs(const ID & dof_id) const {
   auto it = this->dofs.find(dof_id);
   return it != this->dofs.end();
 }
 
 /* -------------------------------------------------------------------------- */
 inline DOFManager::DOFData & DOFManager::getDOFData(const ID & dof_id) {
   auto it = this->dofs.find(dof_id);
   if (it == this->dofs.end()) {
     AKANTU_EXCEPTION("The dof " << dof_id << " does not exists in "
                                 << this->id);
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 const DOFManager::DOFData & DOFManager::getDOFData(const ID & dof_id) const {
   auto it = this->dofs.find(dof_id);
   if (it == this->dofs.end()) {
     AKANTU_EXCEPTION("The dof " << dof_id << " does not exists in "
                                 << this->id);
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void DOFManager::extractElementEquationNumber(
     const Array<Int> & equation_numbers, const Vector<UInt> & connectivity,
     UInt nb_degree_of_freedom, Vector<Int> & element_equation_number) {
   for (Int i = 0, ld = 0; i < connectivity.size(); ++i) {
     UInt n = connectivity(i);
     for (UInt d = 0; d < nb_degree_of_freedom; ++d, ++ld) {
       element_equation_number(ld) =
           equation_numbers(n * nb_degree_of_freedom + d);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class DOFData_>
 inline DOFData_ & DOFManager::getDOFDataTyped(const ID & dof_id) {
   return aka::as_type<DOFData_>(this->getDOFData(dof_id));
 }
 
 /* -------------------------------------------------------------------------- */
 template <class DOFData_>
 inline const DOFData_ & DOFManager::getDOFDataTyped(const ID & dof_id) const {
   return aka::as_type<DOFData_>(this->getDOFData(dof_id));
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Real> & DOFManager::getDOFs(const ID & dofs_id) {
   return *(this->getDOFData(dofs_id).dof);
 }
 
 /* -------------------------------------------------------------------------- */
 inline DOFSupportType DOFManager::getSupportType(const ID & dofs_id) const {
   return this->getDOFData(dofs_id).support_type;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Real> & DOFManager::getPreviousDOFs(const ID & dofs_id) {
   return *(this->getDOFData(dofs_id).previous);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasPreviousDOFs(const ID & dofs_id) const {
   return (this->getDOFData(dofs_id).previous != nullptr);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Real> & DOFManager::getDOFsIncrement(const ID & dofs_id) {
   return *(this->getDOFData(dofs_id).increment);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasDOFsIncrement(const ID & dofs_id) const {
   return (this->getDOFData(dofs_id).increment != nullptr);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Real> & DOFManager::getDOFsDerivatives(const ID & dofs_id,
                                                     UInt order) {
 
   if (order == 0) {
     return getDOFs(dofs_id);
   }
 
   std::vector<Array<Real> *> & derivatives =
       this->getDOFData(dofs_id).dof_derivatives;
   if ((order > derivatives.size()) || (derivatives[order - 1] == nullptr)) {
     AKANTU_EXCEPTION("No derivatives of order " << order << " present in "
                                                 << this->id << " for dof "
                                                 << dofs_id);
   }
 
   return *derivatives[order - 1];
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasDOFsDerivatives(const ID & dofs_id,
                                            UInt order) const {
   const std::vector<Array<Real> *> & derivatives =
       this->getDOFData(dofs_id).dof_derivatives;
   return ((order < derivatives.size()) && (derivatives[order - 1] != nullptr));
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Real> & DOFManager::getSolution(const ID & dofs_id) const {
   return this->getDOFData(dofs_id).solution;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Real> & DOFManager::getSolution(const ID & dofs_id) {
   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);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::isLocalOrMasterDOF(UInt dof_num) {
   auto dof_flag = this->dofs_flag(dof_num);
   return (dof_flag & NodeFlag::_local_master_mask) == NodeFlag::_normal;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::isSlaveDOF(UInt dof_num) {
   auto dof_flag = this->dofs_flag(dof_num);
   return (dof_flag & NodeFlag::_shared_mask) == NodeFlag::_slave;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::isPureGhostDOF(UInt dof_num) {
   auto dof_flag = this->dofs_flag(dof_num);
   return (dof_flag & NodeFlag::_shared_mask) == NodeFlag::_pure_ghost;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Int DOFManager::localToGlobalEquationNumber(Int local) const {
   return this->global_equation_number(local);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool DOFManager::hasGlobalEquationNumber(Int global) const {
   auto it = this->global_to_local_mapping.find(global);
   return (it != this->global_to_local_mapping.end());
 }
 
 /* -------------------------------------------------------------------------- */
 inline Int DOFManager::globalToLocalEquationNumber(Int global) const {
   auto it = this->global_to_local_mapping.find(global);
   AKANTU_DEBUG_ASSERT(it != this->global_to_local_mapping.end(),
                       "This global equation number "
                           << global << " does not exists in " << this->id);
 
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 inline NodeFlag DOFManager::getDOFFlag(Int local_id) const {
   return this->dofs_flag(local_id);
 }
 
 /* -------------------------------------------------------------------------- */
-inline const Array<UInt> &
+inline decltype(auto)
 DOFManager::getDOFsAssociatedNodes(const ID & dof_id) const {
   const auto & dof_data = this->getDOFData(dof_id);
   return dof_data.associated_nodes;
 }
 
 /* -------------------------------------------------------------------------- */
-const Array<Int> &
+decltype(auto)
 DOFManager::getLocalEquationsNumbers(const ID & dof_id) const {
   return getDOFData(dof_id).local_equation_number;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename Vec>
 void DOFManager::assembleMatMulVectToArray_(const ID & dof_id, const ID & A_id,
                                             const Array<Real> & x,
                                             Array<Real> & array,
                                             Real scale_factor) {
   Vec tmp_array(aka::as_type<Vec>(*data_cache), this->id + ":tmp_array");
   tmp_array.zero();
   assembleMatMulVectToGlobalArray(dof_id, A_id, x, tmp_array, scale_factor);
   getArrayPerDOFs(dof_id, tmp_array, array);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename Mat>
 void DOFManager::assembleElementalMatricesToMatrix_(
     Mat & A, const ID & dof_id, const Array<Real> & elementary_mat,
     ElementType type, GhostType ghost_type,
     const MatrixType & elemental_matrix_type,
-    const Array<UInt> & filter_elements) {
+    const Array<Int> & filter_elements) {
   AKANTU_DEBUG_IN();
 
   auto & dof_data = this->getDOFData(dof_id);
 
   AKANTU_DEBUG_ASSERT(dof_data.support_type == _dst_nodal,
                       "This function applies only on Nodal dofs");
 
   const auto & equation_number = this->getLocalEquationsNumbers(dof_id);
 
   UInt nb_element;
   UInt * filter_it = nullptr;
   if (filter_elements != empty_filter) {
     nb_element = filter_elements.size();
     filter_it = filter_elements.storage();
   } else {
     if (dof_data.group_support != "__mesh__") {
       const auto & 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;
   auto size_mat = nb_nodes_per_element * nb_degree_of_freedom;
 
   Vector<Int> element_eq_nb(nb_degree_of_freedom * nb_nodes_per_element);
   auto 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.begin(), element_eq_nb.end(),
                    element_eq_nb.begin(), [&](auto && local) {
                      return this->localToGlobalEquationNumber(local);
                    });
 
     if (filter_it) {
       ++filter_it;
     } else {
       ++conn_it;
     }
 
     A.addValues(element_eq_nb, element_eq_nb, *el_mat_it,
                 elemental_matrix_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename Mat>
 void DOFManager::assemblePreassembledMatrix_(Mat & A, const ID & dof_id_m,
                                              const ID & dof_id_n,
                                              const TermsToAssemble & terms) {
   const auto & equation_number_m = this->getLocalEquationsNumbers(dof_id_m);
   const auto & equation_number_n = this->getLocalEquationsNumbers(dof_id_n);
 
   for (const auto & term : terms) {
     auto gi = this->localToGlobalEquationNumber(equation_number_m(term.i()));
     auto gj = this->localToGlobalEquationNumber(equation_number_n(term.j()));
     A.add(gi, gj, term);
   }
 }
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* AKANTU_DOF_MANAGER_INLINE_IMPL_HH_ */
diff --git a/src/model/common/dof_manager/dof_manager_petsc.cc b/src/model/common/dof_manager/dof_manager_petsc.cc
index 32a0e5568..45f47d521 100644
--- a/src/model/common/dof_manager/dof_manager_petsc.cc
+++ b/src/model/common/dof_manager/dof_manager_petsc.cc
@@ -1,305 +1,305 @@
 /**
  * @file   dof_manager_petsc.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Oct 07 2015
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  DOFManaterPETSc is the PETSc implementation of the DOFManager
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_petsc.hh"
 #include "aka_iterators.hh"
 #include "communicator.hh"
 #include "cppargparse.hh"
 #include "non_linear_solver_petsc.hh"
 #include "solver_vector_petsc.hh"
 #include "sparse_matrix_petsc.hh"
 #include "time_step_solver_default.hh"
 #if defined(AKANTU_USE_MPI)
 #include "mpi_communicator_data.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 #include <petscis.h>
 #include <petscsys.h>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class PETScSingleton {
 private:
   PETScSingleton() {
     PETSc_call(PetscInitialized, &is_initialized);
 
     if (is_initialized == 0U) {
       cppargparse::ArgumentParser & argparser = getStaticArgumentParser();
       int & argc = argparser.getArgC();
       char **& argv = argparser.getArgV();
       PETSc_call(PetscInitialize, &argc, &argv, nullptr, nullptr);
       PETSc_call(
           PetscPopErrorHandler); // remove the default PETSc signal handler
       PETSc_call(PetscPushErrorHandler, PetscIgnoreErrorHandler, nullptr);
     }
   }
 
 public:
   PETScSingleton(const PETScSingleton &) = delete;
   PETScSingleton & operator=(const PETScSingleton &) = delete;
 
   ~PETScSingleton() {
     if (is_initialized == 0U) {
       PetscFinalize();
     }
   }
 
   static PETScSingleton & getInstance() {
     static PETScSingleton instance;
     return instance;
   }
 
 private:
   PetscBool is_initialized;
 };
 
 /* -------------------------------------------------------------------------- */
 DOFManagerPETSc::DOFDataPETSc::DOFDataPETSc(const ID & dof_id)
     : DOFData(dof_id) {}
 
 /* -------------------------------------------------------------------------- */
 DOFManagerPETSc::DOFManagerPETSc(const ID & id)
     : DOFManager(id) {
   init();
 }
 
 /* -------------------------------------------------------------------------- */
 DOFManagerPETSc::DOFManagerPETSc(Mesh & mesh, const ID & id)
     : DOFManager(mesh, id) {
   init();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerPETSc::init() {
   // check if the akantu types and PETSc one are consistant
   static_assert(sizeof(Int) == sizeof(PetscInt),
                 "The integer type of Akantu does not match the one from PETSc");
   static_assert(sizeof(Real) == sizeof(PetscReal),
                 "The integer type of Akantu does not match the one from PETSc");
 
 #if defined(AKANTU_USE_MPI)
 
   const auto & mpi_data =
       aka::as_type<MPICommunicatorData>(communicator.getCommunicatorData());
   MPI_Comm mpi_comm = mpi_data.getMPICommunicator();
   this->mpi_communicator = mpi_comm;
 #else
   this->mpi_communicator = PETSC_COMM_SELF;
 #endif
 
   PETScSingleton & instance [[gnu::unused]] = PETScSingleton::getInstance();
 }
 
 /* -------------------------------------------------------------------------- */
 auto DOFManagerPETSc::getNewDOFData(const ID & dof_id)
     -> std::unique_ptr<DOFData> {
   return std::make_unique<DOFDataPETSc>(dof_id);
 }
 
 /* -------------------------------------------------------------------------- */
 std::tuple<UInt, UInt, UInt>
 DOFManagerPETSc::registerDOFsInternal(const ID & dof_id,
                                       Array<Real> & dofs_array) {
   dofs_ids.push_back(dof_id);
   auto ret = DOFManager::registerDOFsInternal(dof_id, dofs_array);
   UInt nb_dofs;
   UInt nb_pure_local_dofs;
   std::tie(nb_dofs, nb_pure_local_dofs, std::ignore) = ret;
 
   auto && vector = std::make_unique<SolverVectorPETSc>(*this, id + ":solution");
   auto *x = vector->getVec();
   PETSc_call(VecGetLocalToGlobalMapping, x, &is_ltog_map);
 
   // redoing the indexes based on the petsc numbering
   for (auto & dof_id : dofs_ids) {
     auto & dof_data = this->getDOFDataTyped<DOFDataPETSc>(dof_id);
 
     Array<PetscInt> gidx(dof_data.local_equation_number.size());
     for (auto && data : zip(dof_data.local_equation_number, gidx)) {
       std::get<1>(data) = localToGlobalEquationNumber(std::get<0>(data));
     }
 
     auto & lidx = dof_data.local_equation_number_petsc;
     if (is_ltog_map != nullptr) {
       lidx.resize(gidx.size());
 
       PetscInt n;
       PETSc_call(ISGlobalToLocalMappingApply, is_ltog_map, IS_GTOLM_MASK,
                  gidx.size(), gidx.storage(), &n, lidx.storage());
     }
   }
 
   residual = std::make_unique<SolverVectorPETSc>(*vector, id + ":residual");
   data_cache = std::make_unique<SolverVectorPETSc>(*vector, id + ":data_cache");
   solution = std::move(vector);
 
   for (auto & mat : matrices) {
     auto & A = this->getMatrix(mat.first);
     A.resize();
   }
 
   return ret;
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerPETSc::assembleToGlobalArray(
     const ID & dof_id, const Array<Real> & array_to_assemble,
     SolverVector & global_array, Real scale_factor) {
   const auto & dof_data = getDOFDataTyped<DOFDataPETSc>(dof_id);
   auto & g = aka::as_type<SolverVectorPETSc>(global_array);
 
   AKANTU_DEBUG_ASSERT(array_to_assemble.size() *
                               array_to_assemble.getNbComponent() ==
                           dof_data.local_nb_dofs,
                       "The array to assemble does not have the proper size");
 
   g.addValuesLocal(dof_data.local_equation_number_petsc, array_to_assemble,
                    scale_factor);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerPETSc::getArrayPerDOFs(const ID & dof_id,
                                       const SolverVector & global_array,
                                       Array<Real> & local) {
   const auto & dof_data = getDOFDataTyped<DOFDataPETSc>(dof_id);
   const auto & petsc_vector = aka::as_type<SolverVectorPETSc>(global_array);
 
   AKANTU_DEBUG_ASSERT(
       local.size() * local.getNbComponent() == dof_data.local_nb_dofs,
       "The array to get the values does not have the proper size");
 
   petsc_vector.getValuesLocal(dof_data.local_equation_number_petsc, local);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerPETSc::assembleElementalMatricesToMatrix(
     const ID & matrix_id, const ID & dof_id, const Array<Real> & elementary_mat,
     ElementType type, GhostType ghost_type,
     const MatrixType & elemental_matrix_type,
-    const Array<UInt> & filter_elements) {
+    const Array<Int> & filter_elements) {
   auto & A = getMatrix(matrix_id);
   DOFManager::assembleElementalMatricesToMatrix_(
       A, dof_id, elementary_mat, type, ghost_type, elemental_matrix_type,
       filter_elements);
 
   A.applyModifications();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerPETSc::assemblePreassembledMatrix(
     const ID & dof_id_m, const ID & dof_id_n, const ID & matrix_id,
     const TermsToAssemble & terms) {
   auto & A = getMatrix(matrix_id);
   DOFManager::assemblePreassembledMatrix_(A, dof_id_m, dof_id_n, terms);
 
   A.applyModifications();
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerPETSc::assembleMatMulVectToArray(const ID & dof_id,
                                                 const ID & A_id,
                                                 const Array<Real> & x,
                                                 Array<Real> & array,
                                                 Real scale_factor) {
   DOFManager::assembleMatMulVectToArray_<SolverVectorPETSc>(
       dof_id, A_id, x, array, scale_factor);
 }
 
 /* -------------------------------------------------------------------------- */
 void DOFManagerPETSc::makeConsistentForPeriodicity(const ID & /*dof_id*/,
                                                    SolverVector & /*array*/) {}
 
 /* -------------------------------------------------------------------------- */
 NonLinearSolver &
 DOFManagerPETSc::getNewNonLinearSolver(const ID & id,
                                        const NonLinearSolverType & type) {
   return this->registerNonLinearSolver<NonLinearSolverPETSc>(*this, id, type);
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolver & DOFManagerPETSc::getNewTimeStepSolver(
     const ID & id, const TimeStepSolverType & type,
     NonLinearSolver & non_linear_solver, SolverCallback & callback) {
   return this->registerTimeStepSolver<TimeStepSolverDefault>(
       *this, id, type, non_linear_solver, callback);
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix & DOFManagerPETSc::getNewMatrix(const ID & id,
                                              const MatrixType & matrix_type) {
   return this->registerSparseMatrix<SparseMatrixPETSc>(*this, id, matrix_type);
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrix & DOFManagerPETSc::getNewMatrix(const ID & id,
                                              const ID & matrix_to_copy_id) {
   return this->registerSparseMatrix<SparseMatrixPETSc>(id, matrix_to_copy_id);
 }
 
 /* -------------------------------------------------------------------------- */
 SparseMatrixPETSc & DOFManagerPETSc::getMatrix(const ID & id) {
   auto & matrix = DOFManager::getMatrix(id);
   return aka::as_type<SparseMatrixPETSc>(matrix);
 }
 
 /* -------------------------------------------------------------------------- */
 SolverVector & DOFManagerPETSc::getNewLumpedMatrix(const ID & id) {
   return this->registerLumpedMatrix<SolverVectorPETSc>(*this, id);
 }
 
 /* -------------------------------------------------------------------------- */
 SolverVectorPETSc & DOFManagerPETSc::getSolution() {
   return aka::as_type<SolverVectorPETSc>(*this->solution);
 }
 
 const SolverVectorPETSc & DOFManagerPETSc::getSolution() const {
   return aka::as_type<SolverVectorPETSc>(*this->solution);
 }
 
 SolverVectorPETSc & DOFManagerPETSc::getResidual() {
   return aka::as_type<SolverVectorPETSc>(*this->residual);
 }
 
 const SolverVectorPETSc & DOFManagerPETSc::getResidual() const {
   return aka::as_type<SolverVectorPETSc>(*this->residual);
 }
 
 /* -------------------------------------------------------------------------- */
 static bool dof_manager_is_registered [[gnu::unused]] =
     DOFManagerFactory::getInstance().registerAllocator(
         "petsc",
         [](Mesh & mesh, const ID & id) -> std::unique_ptr<DOFManager> {
           return std::make_unique<DOFManagerPETSc>(mesh, id);
         });
 
 } // namespace akantu
diff --git a/src/model/model.hh b/src/model/model.hh
index c7b75fe07..147baa986 100644
--- a/src/model/model.hh
+++ b/src/model/model.hh
@@ -1,391 +1,391 @@
 /**
  * @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 Apr 09 2021
  *
  * @brief  Interface of a model
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_named_argument.hh"
 #include "fe_engine.hh"
 #include "mesh.hh"
 #include "model_options.hh"
 #include "model_solver.hh"
 /* -------------------------------------------------------------------------- */
 #include <typeindex>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MODEL_HH_
 #define AKANTU_MODEL_HH_
 
 namespace akantu {
 class SynchronizerRegistry;
 class Parser;
 class DumperIOHelper;
 class DOFManager;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class Model : public ModelSolver, public MeshEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   /// Normal constructor where the DOFManager is created internally
-  Model(Mesh & mesh, const ModelType & type, UInt dim = _all_dimensions,
+  Model(Mesh & mesh, const ModelType & type, Int dim = _all_dimensions,
         const ID & id = "model");
 
   /// Model constructor the the dof manager is created externally, for example
   /// in a ModelCoupler
   Model(Mesh & mesh, const ModelType & type,
-        std::shared_ptr<DOFManager> dof_manager, UInt dim = _all_dimensions,
+        std::shared_ptr<DOFManager> dof_manager, Int dim = _all_dimensions,
         const ID & id = "model");
 
   ~Model() override;
 
   using FEEngineMap = std::map<std::string, std::unique_ptr<FEEngine>>;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   virtual void initFullImpl(const ModelOptions & options);
 
 public:
   template <typename... pack>
   std::enable_if_t<are_named_argument<pack...>::value>
   initFull(pack &&... _pack) {
     switch (this->model_type) {
 #ifdef AKANTU_SOLID_MECHANICS
     case ModelType::_solid_mechanics_model:
       this->initFullImpl(SolidMechanicsModelOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
 #ifdef AKANTU_COHESIVE_ELEMENT
     case ModelType::_solid_mechanics_model_cohesive:
       this->initFullImpl(SolidMechanicsModelCohesiveOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
 #ifdef AKANTU_HEAT_TRANSFER
     case ModelType::_heat_transfer_model:
       this->initFullImpl(HeatTransferModelOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
 #ifdef AKANTU_PHASE_FIELD
     case ModelType::_phase_field_model:
       this->initFullImpl(PhaseFieldModelOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif      
 #ifdef AKANTU_EMBEDDED
     case ModelType::_embedded_model:
       this->initFullImpl(EmbeddedInterfaceModelOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
 #ifdef AKANTU_CONTACT_MECHANICS
     case ModelType::_contact_mechanics_model:
       this->initFullImpl(ContactMechanicsModelOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
 #ifdef AKANTU_MODEL_COUPLERS
     case ModelType::_coupler_solid_contact:
       this->initFullImpl(CouplerSolidContactOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
     case ModelType::_coupler_solid_cohesive_contact:
       this->initFullImpl(CouplerSolidCohesiveContactOptions{
           use_named_args, std::forward<decltype(_pack)>(_pack)...});
       break;
 #endif
     default:
       this->initFullImpl(ModelOptions{use_named_args,
                                       std::forward<decltype(_pack)>(_pack)...});
     }
   }
 
   template <typename... pack>
   std::enable_if_t<not are_named_argument<pack...>::value>
   initFull(pack &&... _pack) {
     this->initFullImpl(std::forward<decltype(_pack)>(_pack)...);
   }
 
   /// 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() {};
 
   virtual void initFEEngineBoundary();
 
   /// function to print the containt of the class
   void printself(std::ostream & /*stream*/,
                  int /*indent*/ = 0) const override{};
 
 public:
   /* ------------------------------------------------------------------------ */
   /* Access to the dumpable interface of the boundaries                       */
   /* ------------------------------------------------------------------------ */
   /// Dump the data for a given group
   void dumpGroup(const std::string & group_name);
   void dumpGroup(const std::string & group_name,
                  const std::string & dumper_name);
   /// Dump the data for all boundaries
   void dumpGroup();
   /// Set the directory for a given group
   void setGroupDirectory(const std::string & directory,
                          const std::string & group_name);
   /// Set the directory for all boundaries
   void setGroupDirectory(const std::string & directory);
   /// Set the base name for a given group
   void setGroupBaseName(const std::string & basename,
                         const std::string & group_name);
   /// Get the internal dumper of a given group
   DumperIOHelper & getGroupDumper(const std::string & group_name);
 
   /* ------------------------------------------------------------------------ */
   /* Function for non local capabilities                                      */
   /* ------------------------------------------------------------------------ */
   virtual void updateDataForNonLocalCriterion(__attribute__((unused))
                                               ElementTypeMapReal & criterion) {
     AKANTU_TO_IMPLEMENT();
   }
 
 protected:
   template <typename T>
-  void allocNodalField(std::unique_ptr<Array<T>> & array, UInt nb_component,
+  void allocNodalField(std::unique_ptr<Array<T>> & array, Int nb_component,
                        const ID & name) const;
 
   /* ------------------------------------------------------------------------ */
   /* 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 = "");
 
   inline bool hasFEEngineBoundary(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);
+                                     Int 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 type of analysis method used
   AKANTU_GET_MACRO(AnalysisMethod, method, AnalysisMethod);
 
   /// return the dimension of the system space
   AKANTU_GET_MACRO(SpatialDimension, Model::spatial_dimension, UInt);
 
   /* ------------------------------------------------------------------------ */
   /* Pack and unpack hexlper functions                                         */
   /* ------------------------------------------------------------------------ */
 public:
-  inline UInt getNbIntegrationPoints(const Array<Element> & elements,
+  inline Int 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,
                                          std::shared_ptr<dumpers::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 & field_id);
 
   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,
                                          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,
-                                         ElementKind element_kind,
+                                         Int 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 std::shared_ptr<dumpers::Field>
   createNodalFieldReal(const std::string & /*field_name*/,
                        const std::string & /*group_name*/,
                        bool /*padding_flag*/) {
     return nullptr;
   }
 
   virtual std::shared_ptr<dumpers::Field>
-  createNodalFieldUInt(const std::string & /*field_name*/,
+  createNodalFieldInt(const std::string & /*field_name*/,
                        const std::string & /*group_name*/,
                        bool /*padding_flag*/) {
     return nullptr;
   }
 
   virtual std::shared_ptr<dumpers::Field>
   createNodalFieldBool(const std::string & /*field_name*/,
                        const std::string & /*group_name*/,
                        bool /*padding_flag*/) {
     return nullptr;
   }
 
   virtual std::shared_ptr<dumpers::Field> createElementalField(
       const std::string & /*field_name*/, const std::string & /*group_name*/,
-      bool /*padding_flag*/, UInt /*spatial_dimension*/, ElementKind /*kind*/) {
+      bool /*padding_flag*/, Int /*spatial_dimension*/, ElementKind /*kind*/) {
     return nullptr;
   }
 
   void setDirectory(const std::string & directory);
   void setDirectoryToDumper(const std::string & dumper_name,
                             const std::string & directory);
 
 
   /* ------------------------------------------------------------------------ */
   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);
   /* ------------------------------------------------------------------------ */
   virtual void dump();
   virtual void dump(UInt step);
   virtual void dump(Real time, UInt step);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   friend std::ostream & operator<<(std::ostream & /*stream*/,
                                    const Model & /*_this*/);
 
   ID id;
 
   /// analysis method check the list in akantu::AnalysisMethod
   AnalysisMethod method;
 
   /// Mesh
   Mesh & mesh;
 
   /// Spatial dimension of the problem
-  UInt spatial_dimension;
+  Int 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;
 
   /// parser to the pointer to use
   Parser & parser;
 
   /// default ElementKind for dumper
   ElementKind dumper_default_element_kind{_ek_regular};
 };
 
 /// 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.hh"
 
 #endif /* AKANTU_MODEL_HH_ */
diff --git a/src/model/model_inline_impl.hh b/src/model/model_inline_impl.hh
index 1563a3a2a..e1498581a 100644
--- a/src/model/model_inline_impl.hh
+++ b/src/model/model_inline_impl.hh
@@ -1,177 +1,177 @@
 /**
  * @file   model_inline_impl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 25 2010
  * @date last modification: Wed Mar 10 2021
  *
  * @brief  inline implementation of the model class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_HH_
 #define AKANTU_MODEL_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <typename FEEngineClass>
 inline FEEngineClass & Model::getFEEngineClassBoundary(std::string name) {
   if (name.empty()) {
     name = default_fem;
   }
 
   auto it_boun = fems_boundary.find(name);
 
   if (it_boun == fems_boundary.end()) {
     AKANTU_DEBUG_INFO("Creating FEEngine boundary " << name);
 
     auto it = fems.find(name);
     if (it == fems.end()) {
       AKANTU_EXCEPTION("The FEEngine " << name << " is not registered");
     }
 
     auto spatial_dimension = it->second->getElementDimension();
     fems_boundary[name] = std::make_unique<FEEngineClass>(
         it->second->getMesh(), spatial_dimension - 1,
         id + ":fem_boundary:" + name);
   }
 
   return aka::as_type<FEEngineClass>(*fems_boundary[name]);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename FEEngineClass>
 inline FEEngineClass & Model::getFEEngineClass(std::string name) const {
   if (name.empty()) {
     name = default_fem;
   }
 
   auto it = fems.find(name);
   if (it == fems.end()) {
     AKANTU_EXCEPTION("The FEEngine " << name << " is not registered");
   }
 
   return aka::as_type<FEEngineClass>(*(it->second));
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Model::unRegisterFEEngineObject(const std::string & name) {
   auto it = fems.find(name);
   if (it == fems.end()) {
     AKANTU_EXCEPTION("FEEngine object with name " << name << " was not found");
   }
 
   fems.erase(it);
   if (not fems.empty() and default_fem == name) {
     default_fem = (*fems.begin()).first;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename FEEngineClass>
 inline void Model::registerFEEngineObject(const std::string & name, Mesh & mesh,
-                                          UInt spatial_dimension) {
+                                          Int spatial_dimension) {
   if (fems.empty()) {
     default_fem = name;
   }
 
   auto it = fems.find(name);
   if (it != fems.end()) {
     AKANTU_EXCEPTION("FEEngine object with name " << name
                                                   << " was already created");
   }
 
   fems[name] = std::make_unique<FEEngineClass>(
       mesh, spatial_dimension, id + ":fem:" + name);
 }
 
 /* -------------------------------------------------------------------------- */
 inline FEEngine & Model::getFEEngine(const ID & name) const {
   ID tmp_name = (name.empty()) ? default_fem : name;
 
   auto it = fems.find(tmp_name);
 
   if (it == fems.end()) {
     AKANTU_EXCEPTION("The FEEngine " << tmp_name << " is not registered");
   }
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 inline FEEngine & Model::getFEEngineBoundary(const ID & name) {
   ID tmp_name = (name.empty()) ? default_fem : name;
 
   auto it = fems_boundary.find(tmp_name);
   if (it == fems_boundary.end()) {
     AKANTU_EXCEPTION("The FEEngine boundary  " << tmp_name
                                                << " is not registered");
   }
   AKANTU_DEBUG_ASSERT(it->second != nullptr, "The FEEngine boundary "
                                                  << tmp_name
                                                  << " was not created");
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Model::hasFEEngineBoundary(const ID & name) {
   ID tmp_name = (name.empty()) ? default_fem : name;
   auto it = fems_boundary.find(tmp_name);
   return (it != fems_boundary.end());
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Model::allocNodalField(std::unique_ptr<Array<T>> & array,
-                            UInt nb_component, const ID & name) const {
+                            Int nb_component, const ID & name) const {
   if (array) {
     return;
   }
 
-  UInt nb_nodes = mesh.getNbNodes();
+  auto nb_nodes = mesh.getNbNodes();
   array =
       std::make_unique<Array<T>>(nb_nodes, nb_component, T(), id + ":" + name);
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt Model::getNbIntegrationPoints(const Array<Element> & elements,
+inline Int Model::getNbIntegrationPoints(const Array<Element> & elements,
                                           const ID & fem_id) const {
-  UInt nb_quad = 0;
+  Int nb_quad = 0;
   for (auto && el : elements) {
     nb_quad +=
         getFEEngine(fem_id).getNbIntegrationPoints(el.type, el.ghost_type);
   }
   return nb_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #endif /* AKANTU_MODEL_INLINE_IMPL_HH_ */
diff --git a/src/model/solid_mechanics/material.cc b/src/model/solid_mechanics/material.cc
index deb835bdf..66b024064 100644
--- a/src/model/solid_mechanics/material.cc
+++ b/src/model/solid_mechanics/material.cc
@@ -1,1214 +1,1215 @@
 /**
  * @file   material.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Jul 27 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Implementation of the common part of the material class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "mesh_iterators.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Material::Material(SolidMechanicsModel & model, const ID & id)
     : Parsable(ParserType::_material, id), id(id), fem(model.getFEEngine()),
       model(model), spatial_dimension(this->model.getSpatialDimension()),
       element_filter("element_filter", 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),
       interpolation_inverse_coordinates("interpolation inverse coordinates",
                                         *this),
       interpolation_points_matrices("interpolation points matrices", *this),
       eigen_grad_u(model.getSpatialDimension(), model.getSpatialDimension(),
                    0.) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("eigen_grad_u", eigen_grad_u, _pat_parsable,
                       "EigenGradU");
 
   /// for each connectivity types allocate the element filer array of the
   /// material
   element_filter.initialize(model.getMesh(),
                             _spatial_dimension = spatial_dimension,
                             _element_kind = _ek_regular);
   this->initialize();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Material::Material(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
                    FEEngine & fe_engine, const ID & id)
     : Parsable(ParserType::_material, id), id(id), fem(fe_engine), model(model),
       spatial_dimension(dim), element_filter("element_filter", id),
       stress("stress", *this, dim, fe_engine, this->element_filter),
       eigengradu("eigen_grad_u", *this, dim, fe_engine, this->element_filter),
       gradu("gradu", *this, dim, fe_engine, this->element_filter),
       green_strain("green_strain", *this, dim, fe_engine, this->element_filter),
       piola_kirchhoff_2("piola_kirchhoff_2", *this, dim, fe_engine,
                         this->element_filter),
       potential_energy("potential_energy", *this, dim, fe_engine,
                        this->element_filter),
       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),
       eigen_grad_u(dim, dim, 0.) {
 
   AKANTU_DEBUG_IN();
 
   element_filter.initialize(mesh, _spatial_dimension = spatial_dimension,
                             _element_kind = _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();
   }
 
   this->resizeInternals();
 
   auto dim = spatial_dimension;
   for (const auto & type :
        element_filter.elementTypes(_element_kind = _ek_regular)) {
     for (auto & eigen_gradu : make_view(eigengradu(type), dim, dim)) {
       eigen_gradu = eigen_grad_u;
     }
   }
 
   is_init = true;
 
   updateInternalParameters();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::savePreviousState() {
   AKANTU_DEBUG_IN();
 
   for (auto pair : internal_vectors_real) {
     if (pair.second->hasHistory()) {
       pair.second->saveCurrentValues();
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::restorePreviousState() {
   AKANTU_DEBUG_IN();
 
   for (auto pair : internal_vectors_real) {
     if (pair.second->hasHistory()) {
       pair.second->restorePreviousValues();
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Compute the internal forces by assembling @f$\int_{e} \sigma_e \frac{\partial
  * \varphi}{\partial X} dX @f$
  *
  * @param[in] ghost_type compute the internal forces for _ghost or _not_ghost
  * element
  */
 void Material::assembleInternalForces(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   if (!finite_deformation) {
 
     auto & internal_force = const_cast<Array<Real> &>(model.getInternalForce());
 
     // Mesh & mesh = fem.getMesh();
     for (auto && type :
          element_filter.elementTypes(spatial_dimension, ghost_type)) {
       Array<UInt> & elem_filter = element_filter(type, ghost_type);
       UInt nb_element = elem_filter.size();
 
       if (nb_element == 0) {
         continue;
       }
 
       const Array<Real> & shapes_derivatives =
           fem.getShapesDerivatives(type, ghost_type);
 
       UInt size_of_shapes_derivatives = shapes_derivatives.getNbComponent();
       UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
       /// compute @f$\sigma \frac{\partial \varphi}{\partial X}@f$ by
       /// @f$\mathbf{B}^t \mathbf{\sigma}_q@f$
       auto * sigma_dphi_dx =
           new Array<Real>(nb_element * nb_quadrature_points,
                           size_of_shapes_derivatives, "sigma_x_dphi_/_dX");
 
       fem.computeBtD(stress(type, ghost_type), *sigma_dphi_dx, type, ghost_type,
                      elem_filter);
 
       /**
        * compute @f$\int \sigma  * \frac{\partial \varphi}{\partial X}dX@f$ by
        * @f$ \sum_q \mathbf{B}^t
        * \mathbf{\sigma}_q \overline w_q J_q@f$
        */
       auto * int_sigma_dphi_dx =
           new Array<Real>(nb_element, nb_nodes_per_element * spatial_dimension,
                           "int_sigma_x_dphi_/_dX");
 
       fem.integrate(*sigma_dphi_dx, *int_sigma_dphi_dx,
                     size_of_shapes_derivatives, type, ghost_type, elem_filter);
       delete sigma_dphi_dx;
 
       /// assemble
       model.getDOFManager().assembleElementalArrayLocalArray(
           *int_sigma_dphi_dx, internal_force, type, ghost_type, -1,
           elem_filter);
       delete int_sigma_dphi_dx;
     }
   } else {
     switch (spatial_dimension) {
     case 1:
       this->assembleInternalForces<1>(ghost_type);
       break;
     case 2:
       this->assembleInternalForces<2>(ghost_type);
       break;
     case 3:
       this->assembleInternalForces<3>(ghost_type);
       break;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Compute  the  stress from the gradu
  *
  * @param[in] 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.empty()) {
       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->StoCauchy<1>(type, ghost_type);
       break;
     case 2:
       this->StoCauchy<2>(type, ghost_type);
       break;
     case 3:
       this->StoCauchy<3>(type, ghost_type);
       break;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void Material::StoCauchy(ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto gradu_it = this->gradu(el_type, ghost_type).begin(dim, dim);
   auto gradu_end = this->gradu(el_type, ghost_type).end(dim, dim);
 
   auto piola_it = this->piola_kirchhoff_2(el_type, ghost_type).begin(dim, dim);
   auto stress_it = this->stress(el_type, ghost_type).begin(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;
 
     auto F_tensor = gradUToF<dim>(grad_u);
     this->StoCauchy<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] 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(ElementType type, GhostType ghost_type) {
+template <Int 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.empty()) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   // const Array<Real> & shapes_derivatives =
   //     fem.getShapesDerivatives(type, ghost_type);
 
   Array<Real> & gradu_vect = gradu(type, ghost_type);
 
   UInt nb_element = elem_filter.size();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = fem.getNbIntegrationPoints(type, ghost_type);
 
   gradu_vect.resize(nb_quadrature_points * nb_element);
 
   fem.gradientOnIntegrationPoints(model.getDisplacement(), gradu_vect, dim,
                                   type, ghost_type, elem_filter);
 
   UInt tangent_size = getTangentStiffnessVoigtSize(dim);
 
   auto * tangent_stiffness_matrix =
       new Array<Real>(nb_element * nb_quadrature_points,
                       tangent_size * tangent_size, "tangent_stiffness_matrix");
 
   tangent_stiffness_matrix->zero();
 
   computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
 
   /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   UInt bt_d_b_size = dim * nb_nodes_per_element;
 
   auto * bt_d_b = new Array<Real>(nb_element * nb_quadrature_points,
                                   bt_d_b_size * bt_d_b_size, "B^t*D*B");
 
   fem.computeBtDB(*tangent_stiffness_matrix, *bt_d_b, 4, type, ghost_type,
                   elem_filter);
 
   delete tangent_stiffness_matrix;
 
   /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   auto * 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(ElementType type,
+template <Int 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);
 
   auto * shapes_derivatives_filtered = new Array<Real>(
       nb_element * nb_quadrature_points, dim * nb_nodes_per_element,
       "shapes derivatives filtered");
 
   FEEngine::filterElementalData(fem.getMesh(), shapes_derivatives,
                                 *shapes_derivatives_filtered, type, ghost_type,
                                 elem_filter);
 
   /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   UInt bt_s_b_size = dim * nb_nodes_per_element;
 
   auto * bt_s_b = new Array<Real>(nb_element * nb_quadrature_points,
                                   bt_s_b_size * bt_s_b_size, "B^t*D*B");
 
   UInt piola_matrix_size = getCauchyStressMatrixSize(dim);
 
   Matrix<Real> B(piola_matrix_size, bt_s_b_size);
   Matrix<Real> Bt_S(bt_s_b_size, piola_matrix_size);
   Matrix<Real> S(piola_matrix_size, piola_matrix_size);
 
   auto shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(
       spatial_dimension, nb_nodes_per_element);
 
   auto Bt_S_B_it = bt_s_b->begin(bt_s_b_size, bt_s_b_size);
   auto Bt_S_B_end = bt_s_b->end(bt_s_b_size, bt_s_b_size);
   auto piola_it = piola_kirchhoff_2(type, ghost_type).begin(dim, dim);
 
   for (; Bt_S_B_it != Bt_S_B_end;
        ++Bt_S_B_it, ++shapes_derivatives_filtered_it, ++piola_it) {
     auto & Bt_S_B = *Bt_S_B_it;
     const auto & Piola_kirchhoff_matrix = *piola_it;
 
     setCauchyStressMatrix<dim>(Piola_kirchhoff_matrix, S);
     VoigtHelper<dim>::transferBMatrixToBNL(*shapes_derivatives_filtered_it, B,
                                            nb_nodes_per_element);
     Bt_S.template mul<true, false>(B, S);
     Bt_S_B.template mul<false, false>(Bt_S, B);
   }
 
   delete shapes_derivatives_filtered;
 
   /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   auto * 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(ElementType type,
+template <Int 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);
 
   auto * tangent_stiffness_matrix =
       new Array<Real>(nb_element * nb_quadrature_points,
                       tangent_size * tangent_size, "tangent_stiffness_matrix");
 
   tangent_stiffness_matrix->zero();
 
   computeTangentModuli(type, *tangent_stiffness_matrix, ghost_type);
 
   auto * shapes_derivatives_filtered = new Array<Real>(
       nb_element * nb_quadrature_points, dim * nb_nodes_per_element,
       "shapes derivatives filtered");
   FEEngine::filterElementalData(fem.getMesh(), shapes_derivatives,
                                 *shapes_derivatives_filtered, type, ghost_type,
                                 elem_filter);
 
   /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   UInt bt_d_b_size = dim * nb_nodes_per_element;
 
   auto * bt_d_b = new Array<Real>(nb_element * nb_quadrature_points,
                                   bt_d_b_size * bt_d_b_size, "B^t*D*B");
 
   Matrix<Real> B(tangent_size, dim * nb_nodes_per_element);
   Matrix<Real> B2(tangent_size, dim * nb_nodes_per_element);
   Matrix<Real> Bt_D(dim * nb_nodes_per_element, tangent_size);
 
   auto shapes_derivatives_filtered_it = shapes_derivatives_filtered->begin(
       spatial_dimension, nb_nodes_per_element);
 
   auto Bt_D_B_it = bt_d_b->begin(bt_d_b_size, bt_d_b_size);
   auto grad_u_it = gradu_vect.begin(dim, dim);
   auto D_it = tangent_stiffness_matrix->begin(tangent_size, tangent_size);
   auto D_end = tangent_stiffness_matrix->end(tangent_size, tangent_size);
 
   for (; D_it != D_end;
        ++D_it, ++Bt_D_B_it, ++shapes_derivatives_filtered_it, ++grad_u_it) {
     const auto & grad_u = *grad_u_it;
     const auto & D = *D_it;
     auto & Bt_D_B = *Bt_D_B_it;
 
     // transferBMatrixToBL1<dim > (*shapes_derivatives_filtered_it, B,
     // nb_nodes_per_element);
     VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(
         *shapes_derivatives_filtered_it, B, nb_nodes_per_element);
     VoigtHelper<dim>::transferBMatrixToBL2(*shapes_derivatives_filtered_it,
                                            grad_u, B2, nb_nodes_per_element);
     B += B2;
     Bt_D.template mul<true, false>(B, D);
     Bt_D_B.template mul<false, false>(Bt_D, B);
   }
 
   delete tangent_stiffness_matrix;
   delete shapes_derivatives_filtered;
 
   /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   auto * 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>
+template <Int 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(_ghost_type = ghost_type)) {
     const Array<Real> & shapes_derivatives =
         fem.getShapesDerivatives(type, ghost_type);
 
     Array<UInt> & elem_filter = element_filter(type, ghost_type);
     if (elem_filter.empty()) {
       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);
 
     auto * 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;
 
     auto * bt_s =
         new Array<Real>(nb_element * nb_quadrature_points, bt_s_size, "B^t*S");
 
     auto grad_u_it = this->gradu(type, ghost_type).begin(dim, dim);
     auto grad_u_end = this->gradu(type, ghost_type).end(dim, dim);
     auto stress_it = this->piola_kirchhoff_2(type, ghost_type).begin(dim, dim);
     shapes_derivatives_filtered_it =
         shapesd_filtered->begin(dim, nb_nodes_per_element);
 
     Array<Real>::matrix_iterator bt_s_it = bt_s->begin(bt_s_size, 1);
 
     Matrix<Real> B_tensor(stress_size, bt_s_size);
     Matrix<Real> B2_tensor(stress_size, bt_s_size);
 
     for (; grad_u_it != grad_u_end; ++grad_u_it, ++stress_it,
                                     ++shapes_derivatives_filtered_it,
                                     ++bt_s_it) {
       auto & grad_u = *grad_u_it;
       auto & r = *bt_s_it;
       auto & S = *stress_it;
 
       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;
 
       auto S_vect = Material::stressToVoigt<dim>(S);
       Matrix<Real> S_voigt(S_vect.storage(), stress_size, 1);
 
       r.template mul<true, false>(B_tensor, S_voigt);
     }
 
     delete shapesd_filtered;
 
     /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
     auto * r_e = new Array<Real>(nb_element, bt_s_size, "r_e");
 
     fem.integrate(*bt_s, *r_e, bt_s_size, type, ghost_type, elem_filter);
 
     delete bt_s;
 
     model.getDOFManager().assembleElementalArrayLocalArray(
         *r_e, internal_force, type, ghost_type, -1., elem_filter);
     delete r_e;
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::computePotentialEnergyByElements() {
   AKANTU_DEBUG_IN();
 
   for (auto type : element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     computePotentialEnergy(type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::computePotentialEnergy(ElementType /*unused*/) {
   AKANTU_DEBUG_IN();
   AKANTU_TO_IMPLEMENT();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Real Material::getPotentialEnergy() {
   AKANTU_DEBUG_IN();
   Real epot = 0.;
 
   computePotentialEnergyByElements();
 
   /// integrate the potential energy for each type of elements
   for (auto type : element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     epot += fem.integrate(potential_energy(type, _not_ghost), type, _not_ghost,
                           element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return epot;
 }
 
 /* -------------------------------------------------------------------------- */
 Real Material::getPotentialEnergy(ElementType & type, UInt index) {
   AKANTU_DEBUG_IN();
   Real epot = 0.;
 
   Vector<Real> epot_on_quad_points(fem.getNbIntegrationPoints(type));
 
   computePotentialEnergyByElement(type, index, epot_on_quad_points);
 
   epot = fem.integrate(epot_on_quad_points, type, element_filter(type)(index));
 
   AKANTU_DEBUG_OUT();
   return epot;
 }
 
 /* -------------------------------------------------------------------------- */
 Real Material::getEnergy(const std::string & type) {
   AKANTU_DEBUG_IN();
   if (type == "potential") {
     return getPotentialEnergy();
   }
   AKANTU_DEBUG_OUT();
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 Real Material::getEnergy(const std::string & energy_id, ElementType type,
                          UInt index) {
   AKANTU_DEBUG_IN();
   if (energy_id == "potential") {
     return getPotentialEnergy(type, index);
   }
   AKANTU_DEBUG_OUT();
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::initElementalFieldInterpolation(
     const ElementTypeMapArray<Real> & interpolation_points_coordinates) {
   AKANTU_DEBUG_IN();
 
   this->fem.initElementalFieldInterpolationFromIntegrationPoints(
       interpolation_points_coordinates, this->interpolation_points_matrices,
       this->interpolation_inverse_coordinates, &(this->element_filter));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::interpolateStress(ElementTypeMapArray<Real> & result,
                                  const GhostType ghost_type) {
 
   this->fem.interpolateElementalFieldFromIntegrationPoints(
       this->stress, this->interpolation_points_matrices,
       this->interpolation_inverse_coordinates, result, ghost_type,
       &(this->element_filter));
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::interpolateStressOnFacets(
     ElementTypeMapArray<Real> & result,
     ElementTypeMapArray<Real> & by_elem_result, const GhostType ghost_type) {
 
   interpolateStress(by_elem_result, ghost_type);
 
   UInt stress_size = this->stress.getNbComponent();
 
   const Mesh & mesh = this->model.getMesh();
   const Mesh & mesh_facets = mesh.getMeshFacets();
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type)) {
     Array<UInt> & elem_fil = element_filter(type, ghost_type);
     Array<Real> & by_elem_res = by_elem_result(type, ghost_type);
     UInt nb_element = elem_fil.size();
     UInt nb_element_full = this->model.getMesh().getNbElement(type, ghost_type);
     UInt nb_interpolation_points_per_elem =
         by_elem_res.size() / nb_element_full;
 
     const Array<Element> & facet_to_element =
         mesh_facets.getSubelementToElement(type, ghost_type);
     ElementType type_facet = Mesh::getFacetType(type);
     UInt nb_facet_per_elem = facet_to_element.getNbComponent();
     UInt nb_quad_per_facet =
         nb_interpolation_points_per_elem / nb_facet_per_elem;
     Element element_for_comparison{type, 0, ghost_type};
     const Array<std::vector<Element>> * element_to_facet = nullptr;
     GhostType current_ghost_type = _casper;
     Array<Real> * result_vec = nullptr;
 
     Array<Real>::const_matrix_iterator result_it =
         by_elem_res.begin_reinterpret(
             stress_size, nb_interpolation_points_per_elem, nb_element_full);
 
     for (UInt el = 0; el < nb_element; ++el) {
       UInt global_el = elem_fil(el);
       element_for_comparison.element = global_el;
       for (UInt f = 0; f < nb_facet_per_elem; ++f) {
 
         Element facet_elem = facet_to_element(global_el, f);
         UInt global_facet = facet_elem.element;
         if (facet_elem.ghost_type != current_ghost_type) {
           current_ghost_type = facet_elem.ghost_type;
           element_to_facet = &mesh_facets.getElementToSubelement(
               type_facet, current_ghost_type);
           result_vec = &result(type_facet, current_ghost_type);
         }
 
         bool is_second_element =
             (*element_to_facet)(global_facet)[0] != element_for_comparison;
 
         for (UInt q = 0; q < nb_quad_per_facet; ++q) {
           Vector<Real> result_local(result_vec->storage() +
                                         (global_facet * nb_quad_per_facet + q) *
                                             result_vec->getNbComponent() +
                                         static_cast<UInt>(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);
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::addElements(const Array<Element> & elements_to_add) {
   AKANTU_DEBUG_IN();
 
   UInt mat_id = model.getMaterialIndex(name);
   for (const auto & element : elements_to_add) {
     auto index = this->addElement(element);
     model.material_index(element) = mat_id;
     model.material_local_numbering(element) = index;
   }
 
   this->resizeInternals();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::removeElements(const Array<Element> & elements_to_remove) {
   AKANTU_DEBUG_IN();
 
   auto el_begin = elements_to_remove.begin();
   auto el_end = elements_to_remove.end();
 
   if (elements_to_remove.empty()) {
     return;
   }
 
   auto & mesh = this->model.getMesh();
 
   ElementTypeMapArray<UInt> material_local_new_numbering(
       "remove mat filter elem", id);
 
   material_local_new_numbering.initialize(
       mesh, _element_filter = &element_filter, _element_kind = _ek_not_defined,
       _with_nb_element = true);
 
   ElementTypeMapArray<UInt> element_filter_tmp("element_filter_tmp", id);
 
   element_filter_tmp.initialize(mesh, _element_filter = &element_filter,
                                 _element_kind = _ek_not_defined);
 
   ElementTypeMap<UInt> new_ids, element_ids;
 
   for_each_element(
       mesh,
       [&](auto && el) {
         if (not new_ids(el.type, el.ghost_type)) {
           element_ids(el.type, el.ghost_type) = 0;
         }
 
         auto & element_id = element_ids(el.type, el.ghost_type);
         auto l_el = Element{el.type, element_id, el.ghost_type};
         if (std::find(el_begin, el_end, el) != el_end) {
           material_local_new_numbering(l_el) = UInt(-1);
           return;
         }
 
         element_filter_tmp(el.type, el.ghost_type).push_back(el.element);
         if (not new_ids(el.type, el.ghost_type)) {
           new_ids(el.type, el.ghost_type) = 0;
         }
 
         auto & new_id = new_ids(el.type, el.ghost_type);
 
         material_local_new_numbering(l_el) = new_id;
         model.material_local_numbering(el) = new_id;
 
         ++new_id;
         ++element_id;
       },
       _element_filter = &element_filter, _element_kind = _ek_not_defined);
 
   for (auto ghost_type : ghost_types) {
     for (const auto & type : element_filter.elementTypes(
              _ghost_type = ghost_type, _element_kind = _ek_not_defined)) {
       element_filter(type, ghost_type)
           .copy(element_filter_tmp(type, ghost_type));
     }
   }
 
   for (auto it = internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it) {
     it->second->removeIntegrationPoints(material_local_new_numbering);
   }
 
   for (auto it = internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it) {
     it->second->removeIntegrationPoints(material_local_new_numbering);
   }
 
   for (auto it = internal_vectors_bool.begin();
        it != internal_vectors_bool.end(); ++it) {
     it->second->removeIntegrationPoints(material_local_new_numbering);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::resizeInternals() {
   AKANTU_DEBUG_IN();
   for (auto it = internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it) {
     it->second->resize();
   }
 
   for (auto it = internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it) {
     it->second->resize();
   }
 
   for (auto it = internal_vectors_bool.begin();
        it != internal_vectors_bool.end(); ++it) {
     it->second->resize();
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::onElementsAdded(const Array<Element> & /*unused*/,
                                const NewElementsEvent & /*unused*/) {
   this->resizeInternals();
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::onElementsRemoved(
     const Array<Element> & element_list,
     const ElementTypeMapArray<UInt> & new_numbering,
     [[gnu::unused]] const RemovedElementsEvent & event) {
   UInt my_num = model.getInternalIndexFromID(getID());
 
   ElementTypeMapArray<UInt> material_local_new_numbering(
       "remove mat filter elem", getID());
 
   auto el_begin = element_list.begin();
   auto el_end = element_list.end();
 
   for (auto && gt : ghost_types) {
     for (auto && type :
          new_numbering.elementTypes(_all_dimensions, gt, _ek_not_defined)) {
 
       if (not element_filter.exists(type, gt) ||
           element_filter(type, gt).empty()) {
         continue;
       }
 
       auto & elem_filter = element_filter(type, gt);
       auto & mat_indexes = this->model.material_index(type, gt);
       auto & mat_loc_num = this->model.material_local_numbering(type, gt);
       auto nb_element = this->model.getMesh().getNbElement(type, gt);
 
       // all materials will resize of the same size...
       mat_indexes.resize(nb_element);
       mat_loc_num.resize(nb_element);
 
       if (!material_local_new_numbering.exists(type, gt)) {
         material_local_new_numbering.alloc(elem_filter.size(), 1, type, gt);
       }
 
       auto & mat_renumbering = material_local_new_numbering(type, gt);
       const auto & renumbering = new_numbering(type, gt);
       Array<UInt> elem_filter_tmp;
       UInt ni = 0;
       Element el{type, 0, gt};
 
       for (UInt i = 0; i < elem_filter.size(); ++i) {
         el.element = elem_filter(i);
         if (std::find(el_begin, el_end, el) == el_end) {
           UInt new_el = renumbering(el.element);
           AKANTU_DEBUG_ASSERT(new_el != UInt(-1),
                               "A not removed element as been badly renumbered");
           elem_filter_tmp.push_back(new_el);
           mat_renumbering(i) = ni;
 
           mat_indexes(new_el) = my_num;
           mat_loc_num(new_el) = ni;
           ++ni;
         } else {
           mat_renumbering(i) = UInt(-1);
         }
       }
 
       elem_filter.resize(elem_filter_tmp.size());
       elem_filter.copy(elem_filter_tmp);
     }
   }
 
   for (auto it = internal_vectors_real.begin();
        it != internal_vectors_real.end(); ++it) {
     it->second->removeIntegrationPoints(material_local_new_numbering);
   }
 
   for (auto it = internal_vectors_uint.begin();
        it != internal_vectors_uint.end(); ++it) {
     it->second->removeIntegrationPoints(material_local_new_numbering);
   }
 
   for (auto it = internal_vectors_bool.begin();
        it != internal_vectors_bool.end(); ++it) {
     it->second->removeIntegrationPoints(material_local_new_numbering);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::beforeSolveStep() { this->savePreviousState(); }
 
 /* -------------------------------------------------------------------------- */
 void Material::afterSolveStep(bool converged) {
   if (not converged) {
     this->restorePreviousState();
     return;
   }
 
   for (const auto & type : element_filter.elementTypes(
            _all_dimensions, _not_ghost, _ek_not_defined)) {
     this->updateEnergies(type);
   }
 }
 /* -------------------------------------------------------------------------- */
 void Material::onDamageIteration() { this->savePreviousState(); }
 
 /* -------------------------------------------------------------------------- */
 void Material::onDamageUpdate() {
   for (const auto & type : element_filter.elementTypes(
            _all_dimensions, _not_ghost, _ek_not_defined)) {
     this->updateEnergiesAfterDamage(type);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::onDump() {
   if (this->isFiniteDeformation()) {
     this->computeAllCauchyStresses(_not_ghost);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Material::printself(std::ostream & stream, int indent) const {
   std::string space(indent, 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,
                                    [[gnu::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).empty()) {
       continue;
     }
 
     for (auto & eigengradu : make_view(this->eigengradu(type, ghost_type),
                                        spatial_dimension, spatial_dimension)) {
       eigengradu = prescribed_eigen_grad_u;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 MaterialFactory & Material::getFactory() {
   return MaterialFactory::getInstance();
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/material.hh b/src/model/solid_mechanics/material.hh
index 58e4eb16c..2bc71ab7a 100644
--- a/src/model/solid_mechanics/material.hh
+++ b/src/model/solid_mechanics/material.hh
@@ -1,712 +1,712 @@
 /**
  * @file   material.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Enrico Milanese <enrico.milanese@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Mother class for all materials
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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;
 class Material;
 } // namespace akantu
 
 namespace akantu {
 
 using MaterialFactory =
     Factory<Material, ID, UInt, const ID &, SolidMechanicsModel &, const ID &>;
 
 /**
  * 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(ElementType el_type,
  *                                       Array<Real> & tangent_matrix,
  *                                       GhostType ghost_type = _not_ghost);
  * \endcode
  *
  */
 class Material : public DataAccessor<Element>,
                  public Parsable,
                  public MeshEventHandler,
                  protected SolidMechanicsModelEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Material(const Material & mat) = delete;
   Material & operator=(const Material & mat) = delete;
 
   /// Initialize material with defaults
   Material(SolidMechanicsModel & model, const ID & id = "");
 
   /// Initialize material with custom mesh & fe_engine
   Material(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
            FEEngine & fe_engine, const ID & id = "");
 
   /// Destructor
   ~Material() override;
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Function that materials can/should reimplement                           */
   /* ------------------------------------------------------------------------ */
 protected:
   /// constitutive law
   virtual void computeStress(ElementType /* el_type */,
                              GhostType /* ghost_type */ = _not_ghost) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the tangent stiffness matrix
   virtual void computeTangentModuli(ElementType /*el_type*/,
                                     Array<Real> & /*tangent_matrix*/,
                                     GhostType /*ghost_type*/ = _not_ghost) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the potential energy
   virtual void computePotentialEnergy(ElementType el_type);
 
   /// compute the potential energy for an element
   virtual void
   computePotentialEnergyByElement(ElementType /*type*/, UInt /*index*/,
                                   Vector<Real> & /*epot_on_quad_points*/) {
     AKANTU_TO_IMPLEMENT();
   }
 
   virtual void updateEnergies(ElementType /*el_type*/) {}
 
   virtual void updateEnergiesAfterDamage(ElementType /*el_type*/) {}
 
   /// set the material to steady state (to be implemented for materials that
   /// need it)
   virtual void setToSteadyState(ElementType /*el_type*/,
                                 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(const Element & /*element*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the s-wave speed in the material
   virtual Real getShearWaveSpeed(const Element & /*element*/) const {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// get a material celerity to compute the stable time step (default: is the
   /// push wave speed)
   virtual Real getCelerity(const Element & element) const {
     return getPushWaveSpeed(element);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T> void registerInternal(InternalField<T> & /*vect*/) {
     AKANTU_TO_IMPLEMENT();
   }
 
   template <typename T> void unregisterInternal(InternalField<T> & /*vect*/) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// initialize the material computed parameter
   virtual void initMaterial();
 
   /// compute the residual for this material
   //  virtual void updateResidual(GhostType ghost_type = _not_ghost);
 
   /// assemble the residual for this material
   virtual void assembleInternalForces(GhostType ghost_type);
 
   /// save the internals in the previous_stress if needed
   virtual void savePreviousState();
 
   /// restore the internals from previous_stress if needed
   virtual void restorePreviousState();
 
   /// 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(ElementType type, UInt element, GhostType ghost_type);
-  inline UInt addElement(const Element & element);
+  inline auto addElement(const ElementType & type, Int element,
+                         const GhostType & ghost_type);
+  inline auto addElement(const Element & element);
 
   /// add many elements at once
   void addElements(const Array<Element> & elements_to_add);
 
   /// remove many element at once
   void removeElements(const Array<Element> & elements_to_remove);
 
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /**
    * interpolate stress on given positions for each element by means
    * of a geometrical interpolation on quadrature points
    */
   void interpolateStress(ElementTypeMapArray<Real> & result,
                          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,
                                  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:
   /* ------------------------------------------------------------------------ */
   static inline UInt getTangentStiffnessVoigtSize(UInt dim);
 
   /// 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);
+  template <Int dim> void assembleInternalForces(GhostType ghost_type);
 
-  template <UInt dim>
-  void computeAllStressesFromTangentModuli(ElementType type,
+  template <Int dim>
+  void computeAllStressesFromTangentModuli(const ElementType & type,
                                            GhostType ghost_type);
 
-  template <UInt dim>
-  void assembleStiffnessMatrix(ElementType type, GhostType ghost_type);
+  template <Int dim>
+  void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type);
 
   /// assembling in finite deformation
-  template <UInt dim>
-  void assembleStiffnessMatrixNL(ElementType type, GhostType ghost_type);
+  template <Int dim>
+  void assembleStiffnessMatrixNL(const ElementType & type,
+                                 GhostType ghost_type);
 
-  template <UInt dim>
-  void assembleStiffnessMatrixL2(ElementType type, GhostType ghost_type);
+  template <Int dim>
+  void assembleStiffnessMatrixL2(const ElementType & type,
+                                 GhostType ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* Conversion functions                                                     */
   /* ------------------------------------------------------------------------ */
 public:
   /// Size of the Stress matrix for the case of finite deformation see: Bathe et
   /// al, IJNME, Vol 9, 353-386, 1975
   static inline UInt getCauchyStressMatrixSize(UInt dim);
 
   /// Sets the stress matrix according to Bathe et al, IJNME, Vol 9, 353-386,
   /// 1975
-  template <UInt dim>
+  template <Int dim>
   static inline void setCauchyStressMatrix(const Matrix<Real> & S_t,
                                            Matrix<Real> & sigma);
 
   /// write the stress tensor in the Voigt notation.
-  template <UInt dim>
+  template <Int dim>
   static inline decltype(auto) stressToVoigt(const Matrix<Real> & stress) {
     return VoigtHelper<dim>::matrixToVoigt(stress);
   }
 
   /// write the strain tensor in the Voigt notation.
-  template <UInt dim>
+  template <Int dim>
   static inline decltype(auto) strainToVoigt(const Matrix<Real> & strain) {
     return VoigtHelper<dim>::matrixToVoigtWithFactors(strain);
   }
 
   /// write a voigt vector to stress
-  template <UInt dim>
+  template <Int dim>
   static inline void voigtToStress(const Vector<Real> & voigt,
                                    Matrix<Real> & stress) {
     VoigtHelper<dim>::voigtToMatrix(voigt, stress);
   }
 
   /// Computation of Cauchy stress tensor in the case of finite deformation from
   /// the 2nd Piola-Kirchhoff for a given element type
-  template <UInt dim>
+  template <Int dim>
   void StoCauchy(ElementType el_type, GhostType ghost_type = _not_ghost);
 
   /// Computation the Cauchy stress the 2nd Piola-Kirchhoff and the deformation
   /// gradient
-  template <UInt dim>
+  template <Int dim>
   inline void StoCauchy(const Matrix<Real> & F, const Matrix<Real> & S,
                         Matrix<Real> & sigma, const Real & C33 = 1.0) const;
 
-  template <UInt dim>
+  template <Int dim>
   static inline void gradUToF(const Matrix<Real> & grad_u, Matrix<Real> & F);
 
-  template <UInt dim>
+  template <Int dim>
   static inline decltype(auto) gradUToF(const Matrix<Real> & grad_u);
 
   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>
+  template <Int dim>
   static inline void gradUToEpsilon(const Matrix<Real> & grad_u,
                                     Matrix<Real> & epsilon);
-  template <UInt dim>
+  template <Int dim>
   static inline decltype(auto) gradUToEpsilon(const Matrix<Real> & grad_u);
 
-  template <UInt dim>
+  template <Int dim>
   static inline void gradUToE(const Matrix<Real> & grad_u,
                               Matrix<Real> & epsilon);
 
-  template <UInt dim>
+  template <Int dim>
   static inline decltype(auto) gradUToE(const Matrix<Real> & grad_u);
 
   static inline Real stressToVonMises(const Matrix<Real> & stress);
 
 protected:
   /// converts global element to local element
   inline Element convertToLocalElement(const Element & global_element) const;
   /// converts local element to global element
   inline Element convertToGlobalElement(const Element & local_element) const;
 
   /// converts global quadrature point to local quadrature point
   inline IntegrationPoint
   convertToLocalPoint(const IntegrationPoint & global_point) const;
   /// converts local quadrature point to global quadrature point
   inline IntegrationPoint
   convertToGlobalPoint(const IntegrationPoint & local_point) const;
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
 public:
-  inline UInt getNbData(const Array<Element> & elements,
-                        const SynchronizationTag & tag) const override;
+  inline Int getNbData(const Array<Element> & elements,
+                       const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   template <typename T>
   inline void packElementDataHelper(const ElementTypeMapArray<T> & data_to_pack,
                                     CommunicationBuffer & buffer,
                                     const Array<Element> & elements,
                                     const ID & fem_id = ID()) const;
 
   template <typename T>
   inline void unpackElementDataHelper(ElementTypeMapArray<T> & data_to_unpack,
                                       CommunicationBuffer & buffer,
                                       const Array<Element> & elements,
                                       const ID & fem_id = ID());
 
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler inherited members                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
-  void onNodesAdded(const Array<UInt> & /*unused*/,
-                    const NewNodesEvent & /*unused*/) override{};
-  void onNodesRemoved(const Array<UInt> & /*unused*/,
-                      const Array<UInt> & /*unused*/,
-                      const RemovedNodesEvent & /*unused*/) override{};
+  void onNodesAdded(const Array<Idx> &, const NewNodesEvent &) override{};
+  void onNodesRemoved(const Array<Idx> &, const Array<Idx> &,
+                      const RemovedNodesEvent &) override{};
   void onElementsAdded(const Array<Element> & element_list,
                        const NewElementsEvent & event) override;
   void onElementsRemoved(const Array<Element> & element_list,
-                         const ElementTypeMapArray<UInt> & new_numbering,
+                         const ElementTypeMapArray<Idx> & new_numbering,
                          const RemovedElementsEvent & event) override;
-  void onElementsChanged(const Array<Element> & /*unused*/,
-                         const Array<Element> & /*unused*/,
-                         const ElementTypeMapArray<UInt> & /*unused*/,
-                         const ChangedElementsEvent & /*unused*/) override{};
+  void onElementsChanged(const Array<Element> &, const Array<Element> &,
+                         const ElementTypeMapArray<Idx> &,
+                         const ChangedElementsEvent &) override{};
 
   /* ------------------------------------------------------------------------ */
   /* SolidMechanicsModelEventHandler inherited members                        */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void beforeSolveStep();
   virtual void afterSolveStep(bool converged = true);
 
   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, id, const ID &);
   AKANTU_GET_MACRO(Rho, rho, Real);
   AKANTU_SET_MACRO(Rho, rho, Real);
 
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
 
   /// return the potential energy for the subset of elements contained by the
   /// material
   Real getPotentialEnergy();
   /// return the potential energy for the provided element
   Real getPotentialEnergy(ElementType & type, UInt index);
 
   /// return the energy (identified by id) for the subset of elements contained
   /// by the material
   virtual Real getEnergy(const std::string & type);
   /// return the energy (identified by id) for the provided element
   virtual Real getEnergy(const std::string & energy_id, ElementType type,
-                         UInt index);
+                         Idx index);
 
-  AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, UInt);
+  AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, Idx);
   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> &);
+                   const ElementTypeMapArray<Int> &);
   AKANTU_GET_MACRO(FEEngine, fem, FEEngine &);
 
   bool isNonLocal() const { return is_non_local; }
 
   template <typename T>
   const Array<T> & getArray(const ID & id, ElementType type,
                             GhostType ghost_type = _not_ghost) const;
   template <typename T>
   Array<T> & getArray(const ID & id, ElementType type,
                       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, ElementKind element_kind) const;
 
   template <typename T>
   ElementTypeMap<UInt> getInternalDataPerElem(const ID & id,
                                               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,
                        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,
                                GhostType /*ghost_type*/ = _not_ghost);
 
   bool hasMatrixChanged(const ID & id) {
     if (id == "K") {
       return hasStiffnessMatrixChanged() or finite_deformation;
     }
 
     return true;
   }
 
   MatrixType getMatrixType(const ID & id) {
     if (id == "K") {
       return getTangentType();
     }
 
     if (id == "M") {
       return _symmetric;
     }
 
     return _mt_not_defined;
   }
 
   /// specify if the matrix need to be recomputed for this material
   virtual bool hasStiffnessMatrixChanged() { return true; }
 
   /// specify the type of matrix, if not overloaded the material is not valid
   /// for static or implicit computations
   virtual MatrixType getTangentType() { return _mt_not_defined; }
 
   /// static method to reteive the material factory
   static MaterialFactory & getFactory();
 
 protected:
   bool isInit() const { return is_init; }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// boolean to know if the material has been initialized
   bool is_init{false};
 
   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:
   ID id;
 
   /// Link to the fem object in the model
   FEEngine & fem;
 
   /// Finite deformation
   bool finite_deformation{false};
 
   /// Finite deformation
   bool inelastic_deformation{false};
 
   /// material name
   std::string name;
 
   /// The model to witch the material belong
   SolidMechanicsModel & model;
 
   /// density : rho
   Real rho{0.};
 
   /// spatial dimension
-  UInt spatial_dimension;
+  Int spatial_dimension;
 
   /// list of element handled by the material
-  ElementTypeMapArray<UInt> element_filter;
+  ElementTypeMapArray<Idx> 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{false};
 
   /// tell if the material need the previous stress state
   bool use_previous_stress{false};
 
   /// tell if the material need the previous strain state
   bool use_previous_gradu{false};
 
   /// 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;
 private:
   /// eigen_grad_u for the parser
   Matrix<Real> eigen_grad_u;
 };
 
 /// 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.hh"
 
 #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)       \
   auto && grad_u_view =                                                        \
       make_view(this->gradu(el_type, ghost_type), this->spatial_dimension,     \
                 this->spatial_dimension);                                      \
                                                                                \
   auto stress_view =                                                           \
       make_view(this->stress(el_type, ghost_type), this->spatial_dimension,    \
                 this->spatial_dimension);                                      \
                                                                                \
   if (this->isFiniteDeformation()) {                                           \
     stress_view = make_view(this->piola_kirchhoff_2(el_type, ghost_type),      \
                             this->spatial_dimension, this->spatial_dimension); \
   }                                                                            \
                                                                                \
   for (auto && data : zip(grad_u_view, stress_view)) {                         \
     [[gnu::unused]] Matrix<Real> & grad_u = std::get<0>(data);                 \
     [[gnu::unused]] Matrix<Real> & sigma = std::get<1>(data)
 
 #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)              \
   auto && grad_u_view =                                                        \
       make_view(this->gradu(el_type, ghost_type), this->spatial_dimension,     \
                 this->spatial_dimension);                                      \
                                                                                \
   auto && stress_view =                                                        \
       make_view(this->stress(el_type, ghost_type), this->spatial_dimension,    \
                 this->spatial_dimension);                                      \
                                                                                \
   auto tangent_size =                                                          \
       this->getTangentStiffnessVoigtSize(this->spatial_dimension);             \
                                                                                \
   auto && tangent_view = make_view(tangent_mat, tangent_size, tangent_size);   \
                                                                                \
   for (auto && data : zip(grad_u_view, stress_view, tangent_view)) {           \
     [[gnu::unused]] Matrix<Real> & grad_u = std::get<0>(data);                 \
     [[gnu::unused]] Matrix<Real> & sigma = std::get<1>(data);                  \
     Matrix<Real> & tangent = std::get<2>(data);
 
 #define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END }
 
 /* -------------------------------------------------------------------------- */
 
 #define INSTANTIATE_MATERIAL_ONLY(mat_name)                                    \
   template class mat_name<1>; /* NOLINT */                                     \
   template class mat_name<2>; /* NOLINT */                                     \
   template class mat_name<3>  /* NOLINT */
 
 #define MATERIAL_DEFAULT_PER_DIM_ALLOCATOR(id, mat_name)                       \
   [](UInt dim, const ID &, SolidMechanicsModel & model,                        \
      const ID & id) /* NOLINT */                                               \
       -> std::unique_ptr<                                                      \
           Material> { /* NOLINT */                                             \
                       switch (dim) {                                           \
                       case 1:                                                  \
                         return std::make_unique<mat_name<1>>(/* NOLINT */      \
                                                              model, id);       \
                       case 2:                                                  \
                         return std::make_unique<mat_name<2>>(/* NOLINT */      \
                                                              model, id);       \
                       case 3:                                                  \
                         return std::make_unique<mat_name<3>>(/* NOLINT */      \
                                                              model, id);       \
                       default:                                                 \
                         AKANTU_EXCEPTION(                                      \
                             "The dimension "                                   \
                             << dim                                             \
                             << "is not a valid dimension for the material "    \
                             << #id);                                           \
                       }                                                        \
   }
 
 #define INSTANTIATE_MATERIAL(id, mat_name)                                     \
   INSTANTIATE_MATERIAL_ONLY(mat_name);                                         \
   static bool material_is_alocated_##id [[gnu::unused]] =                      \
       MaterialFactory::getInstance().registerAllocator(                        \
           #id, MATERIAL_DEFAULT_PER_DIM_ALLOCATOR(id, mat_name))
 
 #endif /* AKANTU_MATERIAL_HH_ */
diff --git a/src/model/solid_mechanics/material_inline_impl.hh b/src/model/solid_mechanics/material_inline_impl.hh
index 7e78bd167..4e4a4efd0 100644
--- a/src/model/solid_mechanics/material_inline_impl.hh
+++ b/src/model/solid_mechanics/material_inline_impl.hh
@@ -1,541 +1,541 @@
 /**
  * @file   material_inline_impl.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Enrico Milanese <enrico.milanese@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: Fri Apr 09 2021
  *
  * @brief  Implementation of the inline functions of the class material
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model.hh"
 #include "integration_point.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_INLINE_IMPL_HH_
 #define AKANTU_MATERIAL_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-inline UInt Material::addElement(ElementType type, UInt element,
-                                 GhostType ghost_type) {
-  Array<UInt> & el_filter = this->element_filter(type, ghost_type);
+inline auto Material::addElement(const ElementType & type, Int element,
+                                 const GhostType & ghost_type) {
+  auto & el_filter = this->element_filter(type, ghost_type);
   el_filter.push_back(element);
   return el_filter.size() - 1;
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt Material::addElement(const Element & element) {
+inline auto Material::addElement(const Element & element) {
   return this->addElement(element.type, element.element, element.ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::getTangentStiffnessVoigtSize(UInt dim) {
   return (dim * (dim - 1) / 2 + dim);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::getCauchyStressMatrixSize(UInt dim) {
   return (dim * dim);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void Material::gradUToF(const Matrix<Real> & grad_u, Matrix<Real> & F) {
   AKANTU_DEBUG_ASSERT(F.size() >= grad_u.size() && grad_u.size() == dim * dim,
                       "The dimension of the tensor F should be greater or "
                       "equal to the dimension of the tensor grad_u.");
 
   F.Identity();
 
   for (UInt i = 0; i < dim; ++i) {
     for (UInt j = 0; j < dim; ++j) {
       F(i, j) += grad_u(i, j);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline decltype(auto) Material::gradUToF(const Matrix<Real> & grad_u) {
   Matrix<Real> F(dim, dim);
   gradUToF<dim>(grad_u, F);
   return F;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void Material::StoCauchy(const Matrix<Real> & F, const Matrix<Real> & S,
                                 Matrix<Real> & sigma, const Real & C33) const {
   Real J = F.determinant() * std::sqrt(C33);
 
   Matrix<Real, dim, dim> F_S;
   F_S = F * piola;
   Real constant = J ? 1. / J : 0;
   sigma = constant * F_S * F.transpose();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::rightCauchy(const Matrix<Real> & F, Matrix<Real> & C) {
   C = F.transpose() * F;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::leftCauchy(const Matrix<Real> & F, Matrix<Real> & B) {
   B = F * F.transpose();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void Material::gradUToEpsilon(const Matrix<Real> & grad_u,
                                      Matrix<Real> & epsilon) {
   for (UInt i = 0; i < dim; ++i) {
     for (UInt j = 0; j < dim; ++j) {
       epsilon(i, j) = 0.5 * (grad_u(i, j) + grad_u(j, i));
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline decltype(auto) Material::gradUToEpsilon(const Matrix<Real> & grad_u) {
   Matrix<Real> epsilon(dim, dim);
   Material::template gradUToEpsilon<dim>(grad_u, epsilon);
   return epsilon;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void Material::gradUToE(const Matrix<Real> & grad_u, Matrix<Real> & E) {
     E = grad_u.transpose() * grad_u / 2.;
     E += (grad_u.transpose() + grad_u)/ 2.;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline decltype(auto) Material::gradUToE(const Matrix<Real> & grad_u) {
   Matrix<Real> E(dim, dim);
   gradUToE<dim>(grad_u, E);
   return E;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Material::stressToVonMises(const Matrix<Real> & stress) {
   // compute deviatoric stress
   auto dim = stress.cols();
   auto && deviatoric_stress =
       stress - Matrix<Real>::Identity(dim, dim) * stress.trace() / 3.;
 
   // return Von Mises stress
   return std::sqrt(3. * deviatoric_stress.doubleDot(deviatoric_stress) / 2.);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void Material::setCauchyStressMatrix(const Matrix<Real> & S_t,
                                             Matrix<Real> & sigma) {
   AKANTU_DEBUG_IN();
 
   sigma.zero();
 
   /// see Finite ekement formulations for large deformation dynamic analysis,
   /// Bathe et al. IJNME vol 9, 1975, page 364 ^t \f$\tau\f$
   for (UInt i = 0; i < dim; ++i) {
     for (UInt m = 0; m < dim; ++m) {
       for (UInt n = 0; n < dim; ++n) {
         sigma(i * dim + m, i * dim + n) = S_t(m, n);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline Element
 Material::convertToLocalElement(const Element & global_element) const {
-  UInt ge = global_element.element;
+  auto ge = global_element.element;
 #ifndef AKANTU_NDEBUG
-  UInt model_mat_index = this->model.getMaterialByElement(
+  auto model_mat_index = this->model.getMaterialByElement(
       global_element.type, global_element.ghost_type)(ge);
 
-  UInt mat_index = this->model.getMaterialIndex(this->name);
+  auto mat_index = this->model.getMaterialIndex(this->name);
   AKANTU_DEBUG_ASSERT(model_mat_index == mat_index,
                       "Conversion of a global  element in a local element for "
                       "the wrong material "
                           << this->name << std::endl);
 #endif
-  UInt le = this->model.getMaterialLocalNumbering(
+  auto le = this->model.getMaterialLocalNumbering(
       global_element.type, global_element.ghost_type)(ge);
 
   Element tmp_quad{global_element.type, le, global_element.ghost_type};
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Element
 Material::convertToGlobalElement(const Element & local_element) const {
-  UInt le = local_element.element;
-  UInt ge =
+  auto le = local_element.element;
+  auto ge =
       this->element_filter(local_element.type, local_element.ghost_type)(le);
 
   Element tmp_quad{local_element.type, ge, local_element.ghost_type};
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline IntegrationPoint
 Material::convertToLocalPoint(const IntegrationPoint & global_point) const {
   const FEEngine & fem = this->model.getFEEngine();
   auto && nb_quad = fem.getNbIntegrationPoints(global_point.type);
   auto && el =
       this->convertToLocalElement(static_cast<const Element &>(global_point));
   return IntegrationPoint(el, global_point.num_point, nb_quad);
 }
 
 /* -------------------------------------------------------------------------- */
 inline IntegrationPoint
 Material::convertToGlobalPoint(const IntegrationPoint & local_point) const {
   const FEEngine & fem = this->model.getFEEngine();
-  UInt nb_quad = fem.getNbIntegrationPoints(local_point.type);
+  auto nb_quad = fem.getNbIntegrationPoints(local_point.type);
   Element el =
       this->convertToGlobalElement(static_cast<const Element &>(local_point));
   IntegrationPoint tmp_quad(el, local_point.num_point, nb_quad);
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt Material::getNbData(const Array<Element> & elements,
+inline Int Material::getNbData(const Array<Element> & elements,
                                 const SynchronizationTag & tag) const {
   if (tag == SynchronizationTag::_smm_stress) {
     return (this->isFiniteDeformation() ? 3 : 1) * spatial_dimension *
            spatial_dimension * sizeof(Real) *
            this->getModel().getNbIntegrationPoints(elements);
   }
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::packData(CommunicationBuffer & buffer,
                                const Array<Element> & elements,
                                const SynchronizationTag & tag) const {
   if (tag == SynchronizationTag::_smm_stress) {
     if (this->isFiniteDeformation()) {
       packElementDataHelper(piola_kirchhoff_2, buffer, elements);
       packElementDataHelper(gradu, buffer, elements);
     }
     packElementDataHelper(stress, buffer, elements);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::unpackData(CommunicationBuffer & buffer,
                                  const Array<Element> & elements,
                                  const SynchronizationTag & tag) {
   if (tag == SynchronizationTag::_smm_stress) {
     if (this->isFiniteDeformation()) {
       unpackElementDataHelper(piola_kirchhoff_2, buffer, elements);
       unpackElementDataHelper(gradu, buffer, elements);
     }
     unpackElementDataHelper(stress, buffer, elements);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Parameter & Material::getParam(const ID & param) const {
   try {
     return get(param);
   } catch (...) {
     AKANTU_EXCEPTION("No parameter " << param << " in the material "
                                      << getID());
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::setParam(const ID & param, T value) {
   try {
     set<T>(param, value);
   } catch (...) {
     AKANTU_EXCEPTION("No parameter " << param << " in the material "
                                      << getID());
   }
   updateInternalParameters();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::packElementDataHelper(
     const ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & elements, const ID & fem_id) const {
   DataAccessor::packElementalDataHelper<T>(data_to_pack, buffer, elements, true,
                                            model.getFEEngine(fem_id));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::unpackElementDataHelper(
     ElementTypeMapArray<T> & data_to_unpack, CommunicationBuffer & buffer,
     const Array<Element> & elements, const ID & fem_id) {
   DataAccessor::unpackElementalDataHelper<T>(data_to_unpack, buffer, elements,
                                              true, model.getFEEngine(fem_id));
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Material::registerInternal<Real>(InternalField<Real> & vect) {
   internal_vectors_real[vect.getID()] = &vect;
 }
 
 template <>
 inline void Material::registerInternal<UInt>(InternalField<UInt> & vect) {
   internal_vectors_uint[vect.getID()] = &vect;
 }
 
 template <>
 inline void Material::registerInternal<bool>(InternalField<bool> & vect) {
   internal_vectors_bool[vect.getID()] = &vect;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Material::unregisterInternal<Real>(InternalField<Real> & vect) {
   internal_vectors_real.erase(vect.getID());
 }
 
 template <>
 inline void Material::unregisterInternal<UInt>(InternalField<UInt> & vect) {
   internal_vectors_uint.erase(vect.getID());
 }
 
 template <>
 inline void Material::unregisterInternal<bool>(InternalField<bool> & vect) {
   internal_vectors_bool.erase(vect.getID());
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline bool Material::isInternal(const ID & /*id*/,
                                  ElementKind /*element_kind*/) const {
   AKANTU_TO_IMPLEMENT();
 }
 
 template <>
 inline bool Material::isInternal<Real>(const ID & id,
                                        ElementKind element_kind) const {
   auto internal_array = internal_vectors_real.find(this->getID() + ":" + id);
 
   return not(internal_array == internal_vectors_real.end() ||
              internal_array->second->getElementKind() != element_kind);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline ElementTypeMap<UInt>
 Material::getInternalDataPerElem(const ID & field_id,
                                  ElementKind element_kind) const {
 
   if (!this->template isInternal<T>(field_id, element_kind)) {
     AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
                                                    << this->name);
   }
 
   const InternalField<T> & internal_field =
       this->template getInternal<T>(field_id);
   const FEEngine & fe_engine = internal_field.getFEEngine();
   UInt nb_data_per_quad = internal_field.getNbComponent();
 
   ElementTypeMap<UInt> res;
   for (auto ghost_type : ghost_types) {
     for (auto & type : internal_field.elementTypes(ghost_type)) {
       UInt nb_quadrature_points =
           fe_engine.getNbIntegrationPoints(type, ghost_type);
       res(type, ghost_type) = nb_data_per_quad * nb_quadrature_points;
     }
   }
 
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Material::flattenInternal(const std::string & field_id,
                                ElementTypeMapArray<T> & internal_flat,
                                const GhostType ghost_type,
                                ElementKind element_kind) const {
 
   if (!this->template isInternal<T>(field_id, element_kind)) {
     AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
                                                    << this->name);
   }
 
   const InternalField<T> & internal_field =
       this->template getInternal<T>(field_id);
 
   const FEEngine & fe_engine = internal_field.getFEEngine();
   const Mesh & mesh = fe_engine.getMesh();
 
   for (auto && type : internal_field.filterTypes(ghost_type)) {
     const Array<Real> & src_vect = internal_field(type, ghost_type);
     const Array<UInt> & filter = internal_field.getFilter(type, ghost_type);
 
     // total number of elements in the corresponding mesh
     UInt nb_element_dst = mesh.getNbElement(type, ghost_type);
     // number of element in the internal field
     UInt nb_element_src = filter.size();
     // number of quadrature points per elem
     UInt nb_quad_per_elem = fe_engine.getNbIntegrationPoints(type);
     // number of data per quadrature point
     UInt nb_data_per_quad = internal_field.getNbComponent();
 
     if (!internal_flat.exists(type, ghost_type)) {
       internal_flat.alloc(nb_element_dst * nb_quad_per_elem, nb_data_per_quad,
                           type, ghost_type);
     }
 
     if (nb_element_src == 0) {
       continue;
     }
 
     // number of data per element
     UInt nb_data = nb_quad_per_elem * nb_data_per_quad;
 
     Array<Real> & dst_vect = internal_flat(type, ghost_type);
     dst_vect.resize(nb_element_dst * nb_quad_per_elem);
 
     auto it_dst = make_view(dst_vect, nb_data).begin();
 
     for (auto && data : zip(filter, make_view(src_vect, nb_data))) {
       it_dst[std::get<0>(data)] = std::get<1>(data);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline const InternalField<T> &
 Material::getInternal([[gnu::unused]] const ID & int_id) const {
   AKANTU_TO_IMPLEMENT();
   return NULL;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline InternalField<T> &
 Material::getInternal([[gnu::unused]] const ID & int_id) {
   AKANTU_TO_IMPLEMENT();
   return NULL;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline const InternalField<Real> &
 Material::getInternal(const ID & int_id) const {
   auto it = internal_vectors_real.find(getID() + ":" + int_id);
   if (it == internal_vectors_real.end()) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain an internal "
                                             << int_id << " ("
                                             << (getID() + ":" + int_id) << ")");
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline InternalField<Real> & Material::getInternal(const ID & int_id) {
   auto it = internal_vectors_real.find(getID() + ":" + int_id);
   if (it == internal_vectors_real.end()) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain an internal "
                                             << int_id << " ("
                                             << (getID() + ":" + int_id) << ")");
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline const InternalField<UInt> &
 Material::getInternal(const ID & int_id) const {
   auto it = internal_vectors_uint.find(getID() + ":" + int_id);
   if (it == internal_vectors_uint.end()) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain an internal "
                                             << int_id << " ("
                                             << (getID() + ":" + int_id) << ")");
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline InternalField<UInt> & Material::getInternal(const ID & int_id) {
   auto it = internal_vectors_uint.find(getID() + ":" + int_id);
   if (it == internal_vectors_uint.end()) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain an internal "
                                             << int_id << " ("
                                             << (getID() + ":" + int_id) << ")");
   }
   return *it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline const Array<T> & Material::getArray(const ID & vect_id, ElementType type,
                                            GhostType ghost_type) const {
   try {
     return this->template getInternal<T>(vect_id)(type, ghost_type);
   } catch (debug::Exception & e) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain a vector "
                                             << vect_id << " [" << e << "]");
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline Array<T> & Material::getArray(const ID & vect_id, ElementType type,
                                      GhostType ghost_type) {
   try {
     return this->template getInternal<T>(vect_id)(type, ghost_type);
   } catch (debug::Exception & e) {
     AKANTU_SILENT_EXCEPTION("The material " << name << "(" << getID()
                                             << ") does not contain a vector "
                                             << vect_id << " [" << e << "]");
   }
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_INLINE_IMPL_HH_ */
diff --git a/src/model/solid_mechanics/material_selector.hh b/src/model/solid_mechanics/material_selector.hh
index 7c14637ad..cd03b7751 100644
--- a/src/model/solid_mechanics/material_selector.hh
+++ b/src/model/solid_mechanics/material_selector.hh
@@ -1,159 +1,159 @@
 /**
  * @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: Fri Apr 09 2021
  *
  * @brief  class describing how to choose a material for a given element
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_SELECTOR_HH_
 #define AKANTU_MATERIAL_SELECTOR_HH_
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class SolidMechanicsModel;
 
 /**
  * main class to assign same or different materials for different
  * elements
  */
 class MaterialSelector {
 public:
   MaterialSelector() = default;
   virtual ~MaterialSelector() = default;
-  virtual inline UInt operator()(const Element & element) {
+  virtual inline Int operator()(const Element & element) {
     if (fallback_selector) {
       return (*fallback_selector)(element);
     }
 
     return fallback_value;
   }
 
-  inline void setFallback(UInt f) { fallback_value = f; }
+  inline void setFallback(Int f) { fallback_value = f; }
   inline void
   setFallback(const std::shared_ptr<MaterialSelector> & fallback_selector) {
     this->fallback_selector = fallback_selector;
   }
 
   inline std::shared_ptr<MaterialSelector> & getFallbackSelector() {
     return this->fallback_selector;
   }
 
-  inline UInt getFallbackValue() const { return this->fallback_value; }
+  inline Int getFallbackValue() const { return this->fallback_value; }
 
 protected:
-  UInt fallback_value{0};
+  Int fallback_value{0};
   std::shared_ptr<MaterialSelector> fallback_selector;
 };
 
 /* -------------------------------------------------------------------------- */
 /**
  * class that assigns the first material to regular elements by default
  */
 class DefaultMaterialSelector : public MaterialSelector {
 public:
   explicit DefaultMaterialSelector(
-      const ElementTypeMapArray<UInt> & material_index)
+      const ElementTypeMapArray<Idx> & material_index)
       : material_index(material_index) {}
 
-  UInt operator()(const Element & element) override {
+  Int operator()(const Element & element) override {
     if (not material_index.exists(element.type, element.ghost_type)) {
       return MaterialSelector::operator()(element);
     }
 
     const auto & mat_indexes = material_index(element.type, element.ghost_type);
     if (element.element < mat_indexes.size()) {
       auto && tmp_mat = mat_indexes(element.element);
-      if (tmp_mat != UInt(-1)) {
+      if (tmp_mat != Int(-1)) {
         return tmp_mat;
       }
     }
 
     return MaterialSelector::operator()(element);
   }
 
 private:
-  const ElementTypeMapArray<UInt> & material_index;
+  const ElementTypeMapArray<Idx> & 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)
+                              Int first_index = 1)
       : element_data(element_data), model(model), first_index(first_index) {}
 
   inline T elementData(const Element & element) {
     DebugLevel dbl = debug::getDebugLevel();
     debug::setDebugLevel(dblError);
     T data = element_data(element.type, element.ghost_type)(element.element);
     debug::setDebugLevel(dbl);
     return data;
   }
 
-  inline UInt operator()(const Element & element) override;
+  inline Int operator()(const Element & element) override;
 
 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;
+  Int 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);
+                           Int first_index = 1);
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_SELECTOR_HH_ */
diff --git a/src/model/solid_mechanics/material_selector_tmpl.hh b/src/model/solid_mechanics/material_selector_tmpl.hh
index 7ed2c9f28..1dc38c21b 100644
--- a/src/model/solid_mechanics/material_selector_tmpl.hh
+++ b/src/model/solid_mechanics/material_selector_tmpl.hh
@@ -1,82 +1,82 @@
 /**
  * @file   material_selector_tmpl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Implementation of the template MaterialSelector
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_SELECTOR_TMPL_HH_
 #define AKANTU_MATERIAL_SELECTOR_TMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <>
-inline UInt
-ElementDataMaterialSelector<std::string>::operator()(const Element & element) {
+inline Int ElementDataMaterialSelector<std::string>::
+operator()(const Element & element) {
   try {
     std::string material_name = this->elementData(element);
     return model.getMaterialIndex(material_name);
   } catch (std::exception & e) {
     return MaterialSelector::operator()(element);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
-inline UInt
-ElementDataMaterialSelector<UInt>::operator()(const Element & element) {
+inline Int ElementDataMaterialSelector<UInt>::
+operator()(const Element & element) {
   try {
     return this->elementData(element) - first_index;
   } catch (...) {
     return MaterialSelector::operator()(element);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline UInt
 ElementDataMaterialSelector<T>::operator()(const Element & element) {
   return MaterialSelector::operator()(element);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 MeshDataMaterialSelector<T>::MeshDataMaterialSelector(
     const std::string & name, const SolidMechanicsModel & model,
-    UInt first_index)
+    Int first_index)
     : ElementDataMaterialSelector<T>(model.getMesh().getData<T>(name), model,
                                      first_index) {}
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_SELECTOR_TMPL_HH_ */
diff --git a/src/model/solid_mechanics/materials/internal_field.hh b/src/model/solid_mechanics/materials/internal_field.hh
index 9b6bd112c..bb827ded8 100644
--- a/src/model/solid_mechanics/materials/internal_field.hh
+++ b/src/model/solid_mechanics/materials/internal_field.hh
@@ -1,286 +1,286 @@
 /**
  * @file   internal_field.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Mar 26 2021
  *
  * @brief  Material internal properties
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 <class Material, typename T> class InternalFieldTmpl : public ElementTypeMapArray<T> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   InternalFieldTmpl(const ID & id, Material & material);
   ~InternalFieldTmpl() override;
 
   /// This constructor is only here to let cohesive elements compile
   InternalFieldTmpl(const ID & id, Material & material, FEEngine & fem,
-		    const ElementTypeMapArray<UInt> & element_filter);
+		    const ElementTypeMapArray<Idx> & element_filter);
 
   /// More general constructor
-  InternalFieldTmpl(const ID & id, Material & material, UInt dim, FEEngine & fem,
-		    const ElementTypeMapArray<UInt> & element_filter);
+  InternalFieldTmpl(const ID & id, Material & material, Int dim, FEEngine & fem,
+		    const ElementTypeMapArray<Idx> & element_filter);
 
-    InternalFieldTmpl(const ID & id, const InternalFieldTmpl<Material, T> & other);
+  InternalFieldTmpl(const ID & id, const InternalFieldTmpl<Material, T> & other);
 
 
 private:
   InternalFieldTmpl operator=(const InternalFieldTmpl &) = delete;
 
 
   /* ------------------------------------------------------------------------ */
   /* 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();
 
   /// restore the previous values from the history
   virtual void restorePreviousValues();
 
   /// remove the quadrature points corresponding to suppressed elements
   virtual void
-  removeIntegrationPoints(const ElementTypeMapArray<UInt> & new_numbering);
+  removeIntegrationPoints(const ElementTypeMapArray<Int> & new_numbering);
 
   /// print the content
   void printself(std::ostream & stream, int /*indent*/ = 0) const override;
 
   /// get the default value
   inline operator T() const;
 
   virtual FEEngine & getFEEngine() { return *fem; }
 
   virtual const FEEngine & getFEEngine() const { return *fem; }
 
   /// AKANTU_GET_MACRO(FEEngine, *fem, FEEngine &);
 
 protected:
   /// initialize the arrays in the ElementTypeMapArray<T>
-  void internalInitialize(UInt nb_component);
+  void internalInitialize(Int nb_component);
 
   /// set the values for new internals
   virtual void setArrayValues(T * begin, T * end);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   // using type_iterator = typename ElementTypeMapArray<T>::type_iterator;
   // using filter_type_iterator =
   //     typename ElementTypeMapArray<UInt>::type_iterator;
 
   // /// get the type iterator on all types contained in the internal field
   // type_iterator firstType(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(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(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(GhostType ghost_type = _not_ghost) const {
   //   return this->element_filter.lastType(this->spatial_dimension, ghost_type,
   //                                        this->element_kind);
   // }
 
   /// get filter types for range loop
   decltype(auto) elementTypes(GhostType ghost_type = _not_ghost) const {
     return ElementTypeMapArray<T>::elementTypes(
         _spatial_dimension = this->spatial_dimension,
         _element_kind = this->element_kind, _ghost_type = ghost_type);
   }
 
   /// get filter types for range loop
   decltype(auto) filterTypes(GhostType ghost_type = _not_ghost) const {
     return this->element_filter.elementTypes(
         _spatial_dimension = this->spatial_dimension,
         _element_kind = this->element_kind, _ghost_type = ghost_type);
   }
 
   /// get the array for a given type of the element_filter
-  const Array<UInt> &
-  getFilter(ElementType type,
-            GhostType ghost_type = _not_ghost) const {
-    return this->element_filter(type, ghost_type);
+  const decltype(auto)
+  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()(ElementType type,
                                 GhostType ghost_type = _not_ghost) {
     return ElementTypeMapArray<T>::operator()(type, ghost_type);
   }
 
   virtual const Array<T> &
   operator()(ElementType type,
              GhostType ghost_type = _not_ghost) const {
     return ElementTypeMapArray<T>::operator()(type, ghost_type);
   }
 
   virtual Array<T> & previous(ElementType type,
                               GhostType ghost_type = _not_ghost) {
     AKANTU_DEBUG_ASSERT(previous_values != nullptr,
                         "The history of the internal "
                             << this->getID() << " has not been activated");
     return this->previous_values->operator()(type, ghost_type);
   }
 
   virtual const Array<T> &
   previous(ElementType type,
            GhostType ghost_type = _not_ghost) const {
     AKANTU_DEBUG_ASSERT(previous_values != nullptr,
                         "The history of the internal "
                             << this->getID() << " has not been activated");
     return this->previous_values->operator()(type, ghost_type);
   }
 
   virtual InternalFieldTmpl<Material, T> & previous() {
     AKANTU_DEBUG_ASSERT(previous_values != nullptr,
                         "The history of the internal "
                             << this->getID() << " has not been activated");
     return *(this->previous_values);
   }
 
     virtual const InternalFieldTmpl<Material, T> & previous() const {
     AKANTU_DEBUG_ASSERT(previous_values != nullptr,
                         "The history of the internal "
                             << this->getID() << " has not been activated");
     return *(this->previous_values);
   }
 
   /// check if the history is used or not
   bool hasHistory() const { return (previous_values != nullptr); }
 
   /// get the kind treated by the internal
   ElementKind getElementKind() const { return element_kind; }
 
   /// return the number of components
-  UInt getNbComponent() const { return nb_component; }
+  Int getNbComponent() const { return nb_component; }
 
   /// return the spatial dimension corresponding to the internal element type
   /// loop filter
-  UInt getSpatialDimension() const { return this->spatial_dimension; }
+  Int 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{nullptr};
 
   /// Element filter if needed
-  const ElementTypeMapArray<UInt> & element_filter;
+  const ElementTypeMapArray<Int> & element_filter;
 
   /// default value
   T default_value{};
 
   /// spatial dimension of the element to consider
-  UInt spatial_dimension{0};
+  Int spatial_dimension{0};
 
   /// ElementKind of the element to consider
   ElementKind element_kind{_ek_regular};
 
   /// Number of component of the internal field
-  UInt nb_component{0};
+  Int nb_component{0};
 
   /// Is the field initialized
   bool is_init{false};
 
   /// previous values
   std::unique_ptr<InternalFieldTmpl<Material, T>> previous_values;
 };
 
   
 /// standard output stream operator
 template <class Material, typename T>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const InternalFieldTmpl<Material, T> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 template<typename T>  
 using InternalField = InternalFieldTmpl<Material, T>;  
 
 } // namespace 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 79fc29283..e73ad9b70 100644
--- a/src/model/solid_mechanics/materials/internal_field_tmpl.hh
+++ b/src/model/solid_mechanics/materials/internal_field_tmpl.hh
@@ -1,334 +1,334 @@
 /**
  * @file   internal_field_tmpl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
  * @date last modification: Fri Apr 02 2021
  *
  * @brief  Material internal properties
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 <class Material, typename T>
 InternalFieldTmpl<Material, T>::InternalFieldTmpl(const ID & id, Material & material)
   : ElementTypeMapArray<T>(id, material.getID()), 
   material(material), fem(&(material.getModel().getFEEngine())),
   element_filter(material.getElementFilter()),
   spatial_dimension(material.getModel().getSpatialDimension()) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 InternalFieldTmpl<Material, T>::InternalFieldTmpl(
     const ID & id, Material & material, FEEngine & fem,
-    const ElementTypeMapArray<UInt> & element_filter)
+    const ElementTypeMapArray<Idx> & element_filter)
     : ElementTypeMapArray<T>(id, material.getID()),
       material(material), fem(&fem), element_filter(element_filter),
       spatial_dimension(material.getSpatialDimension()) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 InternalFieldTmpl<Material, T>::InternalFieldTmpl(
     const ID & id, Material & material, UInt dim, FEEngine & fem,
-    const ElementTypeMapArray<UInt> & element_filter)
+    const ElementTypeMapArray<Idx> & element_filter)
     : ElementTypeMapArray<T>(id, material.getID()),
       material(material), fem(&fem), element_filter(element_filter),
       spatial_dimension(dim) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 InternalFieldTmpl<Material, T>::InternalFieldTmpl(const ID & id,
 						  const InternalFieldTmpl<Material, T> & other)
     : ElementTypeMapArray<T>(id, other.material.getID()),
       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) {
 
   AKANTU_DEBUG_ASSERT(other.is_init,
                       "Cannot create a copy of a non initialized field");
   this->internalInitialize(this->nb_component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 InternalFieldTmpl<Material, T>::~InternalFieldTmpl() {
   if (this->is_init) {
     this->material.unregisterInternal(*this);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::setFEEngine(FEEngine & fe_engine) {
   this->fem = &fe_engine;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::setElementKind(ElementKind element_kind) {
   this->element_kind = element_kind;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::initialize(UInt nb_component) {
   internalInitialize(nb_component);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::initializeHistory() {
   if (!previous_values)
     previous_values =
       std::make_unique<InternalFieldTmpl<Material, T>>("previous_" + this->getID(), *this);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::resize() {
   if (!this->is_init){
     return;
   }
 
   for (auto ghost : ghost_types) {
     for (const auto & type : this->filterTypes(ghost)) {
       UInt nb_element = this->element_filter(type, ghost).size();
 
       UInt nb_quadrature_points =
           this->fem->getNbIntegrationPoints(type, ghost);
       UInt new_size = nb_element * nb_quadrature_points;
 
       UInt old_size = 0;
       Array<T> * vect = nullptr;
 
       if (this->exists(type, ghost)) {
         vect = &(this->operator()(type, ghost));
         old_size = vect->size();
         vect->resize(new_size);
       } else {
         vect = &(this->alloc(nb_element * nb_quadrature_points, nb_component,
                              type, ghost));
       }
 
       this->setArrayValues(vect->data() + old_size * vect->getNbComponent(),
                            vect->data() + new_size * vect->getNbComponent());
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::setDefaultValue(const T & value) {
   this->default_value = value;
   this->reset();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::reset() {
   for (auto ghost_type : ghost_types){
     for (const auto & type : this->elementTypes(ghost_type)) {
       Array<T> & vect = (*this)(type, ghost_type);
       //vect.zero();
       this->setArrayValues(
           vect.data(), vect.data() + vect.size() * vect.getNbComponent());
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
-void InternalFieldTmpl<Material, T>::internalInitialize(UInt nb_component) {
+void InternalFieldTmpl<Material, T>::internalInitialize(Int nb_component) {
   if (!this->is_init) {
     this->nb_component = nb_component;
 
     for (auto ghost : ghost_types) {
       for (const auto & type : this->filterTypes(ghost)) {
-        UInt nb_element = this->element_filter(type, ghost).size();
-        UInt nb_quadrature_points =
+        auto nb_element = this->element_filter(type, ghost).size();
+        auto nb_quadrature_points =
             this->fem->getNbIntegrationPoints(type, ghost);
         if (this->exists(type, ghost)) {
           this->operator()(type, ghost)
               .resize(nb_element * nb_quadrature_points);
         } else {
           this->alloc(nb_element * nb_quadrature_points, nb_component, type,
                       ghost);
         }
       }
     }
 
     this->material.registerInternal(*this);
     this->is_init = true;
   }
   this->reset();
 
   if (this->previous_values) {
     this->previous_values->internalInitialize(nb_component);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::setArrayValues(T * begin, T * end) {
   for (; begin < end; ++begin){
     *begin = this->default_value;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::saveCurrentValues() {
   AKANTU_DEBUG_ASSERT(this->previous_values != nullptr,
                       "The history of the internal "
                           << this->getID() << " has not been activated");
 
   if (not this->is_init) {
     return;
   }
 
   for (auto ghost_type : ghost_types) {
     for (const auto & type : this->elementTypes(ghost_type)) {
       (*this->previous_values)(type, ghost_type)
           .copy((*this)(type, ghost_type));
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::restorePreviousValues() {
   AKANTU_DEBUG_ASSERT(this->previous_values != nullptr,
                       "The history of the internal "
                           << this->getID() << " has not been activated");
 
   if (not this->is_init) {
     return;
   }
 
   for (auto ghost_type : ghost_types) {
     for (const auto & type : this->elementTypes(ghost_type)) {
       (*this)(type, ghost_type)
           .copy((*this->previous_values)(type, ghost_type));
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 void InternalFieldTmpl<Material, T>::removeIntegrationPoints(
-    const ElementTypeMapArray<UInt> & new_numbering) {
+    const ElementTypeMapArray<Idx> & new_numbering) {
   for (auto ghost_type : ghost_types) {
     for (auto type : new_numbering.elementTypes(_all_dimensions, ghost_type,
                                                 _ek_not_defined)) {
       if (not this->exists(type, ghost_type)) {
         continue;
       }
 
       Array<T> & vect = (*this)(type, ghost_type);
       if (vect.empty()) {
         continue;
       }
 
-      const Array<UInt> & renumbering = new_numbering(type, ghost_type);
+      const auto & renumbering = new_numbering(type, ghost_type);
 
-      UInt nb_quad_per_elem = fem->getNbIntegrationPoints(type, ghost_type);
-      UInt nb_component = vect.getNbComponent();
+      auto nb_quad_per_elem = fem->getNbIntegrationPoints(type, ghost_type);
+      auto 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)) {
+      for (Int i = 0; i < renumbering.size(); ++i) {
+        auto new_i = renumbering(i);
+        if (new_i != Int(-1)) {
           memcpy(tmp.data() + new_i * nb_component * nb_quad_per_elem,
                  vect.data() + 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 <class Material, typename T>
 void InternalFieldTmpl<Material, T>::printself(std::ostream & stream,
                                  int indent [[gnu::unused]]) const {
   stream << "InternalField [ " << this->getID();
 #if !defined(AKANTU_NDEBUG)
   if (AKANTU_DEBUG_TEST(dblDump)) {
     stream << std::endl;
     ElementTypeMapArray<T>::printself(stream, indent + 3);
   } else {
 #endif
     stream << " {" << this->getData(_not_ghost).size() << " types - "
            << this->getData(_ghost).size() << " ghost types"
            << "}";
 #if !defined(AKANTU_NDEBUG)
   }
 #endif
   stream << " ]";
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 ParameterTyped<InternalField<Real>>::setAuto(const ParserParameter & in_param) {
   Parameter::setAuto(in_param);
   Real r = in_param;
   param.setDefaultValue(r);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Material, typename T>
 inline InternalFieldTmpl<Material, T>::operator T() const {
   return default_value;
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_INTERNAL_FIELD_TMPL_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_anisotropic_damage.cc b/src/model/solid_mechanics/materials/material_damage/material_anisotropic_damage.cc
index 9e3da3aba..bc36bc41e 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_anisotropic_damage.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_anisotropic_damage.cc
@@ -1,84 +1,84 @@
 /**
  * @file   material_anisotropic_damage.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Jul 03 2019
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Base class for anisotropic damage materials
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_anisotropic_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 namespace {
-  template <UInt dim>
+  template <Int dim>
   std::unique_ptr<Material>
   materialAnisotropicDamage(std::integral_constant<UInt, dim> /*unused*/,
                             const ID & option, SolidMechanicsModel & model,
                             const ID & id) {
     if (option.empty() or option == "mazars") {
       return std::make_unique<MaterialAnisotropicDamage<
           dim, EquivalentStrainMazars, DamageThresholdTan>>(model, id);
     }
     if (option == "mazars-drucker-prager") {
       return std::make_unique<MaterialAnisotropicDamage<
           dim, EquivalentStrainMazarsDruckerPrager, DamageThresholdTan>>(model,
                                                                          id);
     }
     AKANTU_EXCEPTION("The option " << option
                                    << " is not valid for the material " << id);
   }
 
   template <class... Args>
   decltype(auto) dimensionDispatch(UInt dim, Args &&... args) {
     switch (dim) {
     case 1:
       return materialAnisotropicDamage(std::integral_constant<UInt, 1>{},
                                        std::forward<Args>(args)...);
     case 2:
       return materialAnisotropicDamage(std::integral_constant<UInt, 2>{},
                                        std::forward<Args>(args)...);
     case 3:
       return materialAnisotropicDamage(std::integral_constant<UInt, 3>{},
                                        std::forward<Args>(args)...);
     default: {
       AKANTU_EXCEPTION("In what dimension are you leaving ?");
     }
     }
   }
 } // namespace
 static bool material_is_alocated_anisotropic_damage [[gnu::unused]] =
     MaterialFactory::getInstance().registerAllocator(
         "anisotropic_damage",
         [](UInt dim, const ID & option, SolidMechanicsModel & model,
            const ID & id) -> std::unique_ptr<Material> {
           return dimensionDispatch(dim, option, model, id);
         });
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_anisotropic_damage_tmpl.hh b/src/model/solid_mechanics/materials/material_damage/material_anisotropic_damage_tmpl.hh
index 3c8516d07..393f3e338 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_anisotropic_damage_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_anisotropic_damage_tmpl.hh
@@ -1,380 +1,380 @@
 /**
  * @file   material_anisotropic_damage_tmpl.hh
  *
  * @author Emil Gallyamov <emil.gallyamov@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Jul 03 2019
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Base class for anisotropic damage materials
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "material_anisotropic_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_ANISOTROPIC_DAMAGE_TMPL_HH_
 #define AKANTU_MATERIAL_ANISOTROPIC_DAMAGE_TMPL_HH_
 
 namespace akantu {
 struct EmptyIteratorContainer {
   struct iterator {
     auto & operator++() { return *this; }
     Real operator*() { return 0; }
     bool operator!=(const iterator & /*unused*/) const { return true; }
     bool operator==(const iterator & /*unused*/) const { return false; }
   };
 
   auto begin() const // NOLINT(readability-convert-member-functions-to-static)
   {
     return iterator();
   }
   
   auto end() const // NOLINT(readability-convert-member-functions-to-static)
   {
     return iterator();
   }
 };
 } // namespace akantu
 
 namespace std {
 template <> struct iterator_traits<::akantu::EmptyIteratorContainer::iterator> {
   using iterator_category = forward_iterator_tag;
   using value_type = akantu::Real;
   using difference_type = std::ptrdiff_t;
   using pointer = akantu::Real *;
   using reference = akantu::Real &;
 };
 } // namespace std
 
 namespace akantu {
 namespace {
   template <UInt dim, class Op>
   void tensorPlus_(const Matrix<Real> & A, Op && oper) {
     Vector<Real> A_eigs(dim);
     A.eig(A_eigs);
 
     for (auto & ap : A_eigs) {
       oper(ap);
     }
   }
 
-  template <UInt dim> auto tensorPlus2(const Matrix<Real> & A) {
+  template <Int dim> auto tensorPlus2(const Matrix<Real> & A) {
     Real square = 0;
     tensorPlus_<dim>(A, [&](Real eig) {
       eig = std::max(eig, 0.);
       square += eig * eig;
     });
 
     return square;
   }
 
-  template <UInt dim> auto tensorPlusTrace(const Matrix<Real> & A) {
+  template <Int dim> auto tensorPlusTrace(const Matrix<Real> & A) {
     Real trace_plus = 0;
     Real trace_minus = 0;
     tensorPlus_<dim>(A, [&](Real eig) {
       trace_plus += std::max(eig, 0.);
       trace_minus += std::min(eig, 0.);
     });
 
     return std::make_pair(trace_plus, trace_minus);
   }
 
   template <UInt dim, class Op>
   auto tensorPlusOp(const Matrix<Real> & A, Matrix<Real> & A_directions,
                     Op && oper, bool sorted = false) {
     Vector<Real> A_eigs(dim);
     Matrix<Real> A_diag(dim, dim);
     A.eig(A_eigs, A_directions, sorted);
 
     for (auto && data : enumerate(A_eigs)) {
       auto i = std::get<0>(data);
       A_diag(i, i) = oper(std::max(std::get<1>(data), 0.), i);
     }
 
     return A_directions * A_diag * A_directions.transpose();
   }
 
   template <UInt dim, class Op>
   auto tensorPlus(const Matrix<Real> & A, Matrix<Real> & A_directions,
                   bool sorted = false) {
     return tensorPlusOp<dim>(
         A, A_directions, [](Real x, Real /*unused*/) { return x; }, sorted);
   }
 
   template <UInt dim, class Op>
   auto tensorPlusOp(const Matrix<Real> & A, Op && oper) {
     Matrix<Real> A_directions(dim, dim);
     return tensorPlusOp<dim>(A, A_directions, std::forward<Op>(oper));
   }
 
-  template <UInt dim> auto tensorPlus(const Matrix<Real> & A) {
+  template <Int dim> auto tensorPlus(const Matrix<Real> & A) {
     return tensorPlusOp<dim>(A, [](Real x, Real /*unused*/) { return x; });
   }
 
-  template <UInt dim> auto tensorSqrt(const Matrix<Real> & A) {
+  template <Int dim> auto tensorSqrt(const Matrix<Real> & A) {
     return tensorPlusOp<dim>(
         A, [](Real x, UInt /*unused*/) { return std::sqrt(x); });
   }
 
 } // namespace
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim, template <UInt> class EquivalentStrain,
           template <UInt> class DamageThreshold, template <UInt> class Parent>
 MaterialAnisotropicDamage<dim, EquivalentStrain, DamageThreshold, Parent>::
     MaterialAnisotropicDamage(SolidMechanicsModel & model, const ID & id)
     : Parent<dim>(model, id), damage("damage_tensor", *this),
       elastic_stress("elastic_stress", *this),
       equivalent_strain("equivalent_strain", *this),
       trace_damage("trace_damage", *this), equivalent_strain_function(*this),
       damage_threshold_function(*this) {
   this->registerParam("Dc", Dc, _pat_parsable, "Critical damage");
 
   this->damage.initialize(dim * dim);
   this->elastic_stress.initialize(dim * dim);
   this->equivalent_strain.initialize(1);
 
   this->trace_damage.initialize(1);
   this->trace_damage.initializeHistory();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim, template <UInt> class EquivalentStrain,
           template <UInt> class DamageThreshold, template <UInt> class Parent>
 void MaterialAnisotropicDamage<dim, EquivalentStrain, DamageThreshold, Parent>::
     damageStress(Matrix<Real> & sigma, const Matrix<Real> & sigma_el,
                  const Matrix<Real> & D, Real TrD) {
   // σ_(n + 1) = (1 − D_(n + 1))^(1/2) σ~_(n + 1) (1 − D_(n + 1))^(1 / 2)
   //         - ((1 − D_(n + 1)) : σ~_(n + 1))/ (3 - Tr(D_(n+1))) (1 − D_(n + 1))
   //         + 1/3 (1 - Tr(D_(n+1)) <Tr(σ~_(n + 1))>_+ + <Tr(σ~_(n + 1))>_-) I
 
   auto one_D = Matrix<Real>::eye(dim) - D;
   auto sqrt_one_D = tensorSqrt<dim>(one_D);
 
   Real Tr_sigma_plus;
   Real Tr_sigma_minus;
   std::tie(Tr_sigma_plus, Tr_sigma_minus) = tensorPlusTrace<dim>(sigma_el);
 
   auto I = Matrix<Real>::eye(dim);
 
   sigma = sqrt_one_D * sigma_el * sqrt_one_D -
           (one_D.doubleDot(sigma_el) / (dim - TrD) * one_D) +
           1. / dim * ((1 - TrD) * Tr_sigma_plus - Tr_sigma_minus) * I;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim, template <UInt> class EquivalentStrain,
           template <UInt> class DamageThreshold, template <UInt> class Parent>
 void MaterialAnisotropicDamage<dim, EquivalentStrain, DamageThreshold,
                                Parent>::computeStress(ElementType type,
                                                       GhostType ghost_type) {
 
   for (auto && data :
        zip(make_view(this->stress(type, ghost_type), dim, dim),
            make_view(this->gradu(type, ghost_type), dim, dim),
            make_view(this->sigma_th(type, ghost_type)),
            make_view(this->elastic_stress(type, ghost_type), dim, dim),
            make_view(this->equivalent_strain(type, ghost_type)),
            make_view(this->damage(type, ghost_type), dim, dim),
            make_view(this->trace_damage(type, ghost_type)),
            make_view(this->trace_damage.previous(type, ghost_type)),
            equivalent_strain_function, damage_threshold_function)) {
     auto & sigma = std::get<0>(data);
     auto & grad_u = std::get<1>(data);
     auto & sigma_th = std::get<2>(data);
     auto & sigma_el = std::get<3>(data);
     auto & epsilon_hat = std::get<4>(data);
     auto & D = std::get<5>(data);
     auto & TrD_n_1 = std::get<6>(data);
     auto & TrD = std::get<7>(data);
     auto & equivalent_strain_data = std::get<8>(data);
     auto & damage_threshold_data = std::get<9>(data);
 
     Matrix<Real> Dtmp(dim, dim);
     Real TrD_n_1_tmp;
     Matrix<Real> epsilon(dim, dim);
 
     // yes you read properly this is a label for a goto
     auto computeDamage = [&]() {
       MaterialElastic<dim>::computeStressOnQuad(grad_u, sigma_el, sigma_th);
 
       this->template gradUToEpsilon<dim>(grad_u, epsilon);
 
       // evaluate the damage criteria
       epsilon_hat = equivalent_strain_function(epsilon, equivalent_strain_data);
 
       // evolve the damage if needed
       auto K_TrD = damage_threshold_function.K(TrD, damage_threshold_data);
 
       auto f = epsilon_hat - K_TrD;
 
       // if test function > 0 evolve the damage
       if (f > 0) {
         TrD_n_1_tmp =
             damage_threshold_function.K_inv(epsilon_hat, damage_threshold_data);
 
         auto epsilon_plus = tensorPlus<dim>(epsilon);
         auto delta_lambda = (TrD_n_1_tmp - TrD) / (epsilon_hat * epsilon_hat);
 
         Dtmp = D + delta_lambda * epsilon_plus;
         return true;
       }
       return false;
     };
 
     // compute a temporary version of the new damage
     auto is_damage_updated = computeDamage();
 
     if (is_damage_updated) {
       /// Check and correct for broken case
       if (Dtmp.trace() > Dc) {
         if (epsilon.trace() > 0) { // tensile loading
           auto kpa = this->kpa;
           auto lambda = this->lambda;
 
           // change kappa to Kappa_broken = (1-Dc) Kappa
           kpa = (1 - Dc) * kpa;
           this->E = 9 * kpa * (kpa - lambda) / (3 * kpa - lambda);
           this->nu = lambda / (3 * kpa - lambda);
           this->updateInternalParameters();
 
           computeDamage();
         } else if (std::abs(epsilon.trace()) < 1e-10) { // deviatoric case
           Matrix<Real> n(dim, dim);
           std::vector<UInt> ns;
           tensorPlusOp<dim>(
               Dtmp, n,
               [&](Real x, UInt i) {
                 if (x > this->Dc) {
                   ns.push_back(i);
                   return this->Dc;
                 }
 
                 return x;
               },
               true);
         }
       }
 
       TrD_n_1 = TrD_n_1_tmp;
       D = Dtmp;
     } else {
       TrD_n_1 = TrD;
     }
 
     // apply the damage to the stress
     damageStress(sigma, sigma_el, D, TrD_n_1);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /* EquivalentStrain functions                                                 */
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 class EquivalentStrainMazars : public EmptyIteratorContainer {
 public:
   EquivalentStrainMazars(Material & /*mat*/) {}
 
   template <class... Other>
   Real operator()(const Matrix<Real> & epsilon, Other &&... /*other*/) {
     Real epsilon_hat = 0.;
     std::tie(epsilon_hat, std::ignore) = tensorPlusTrace<dim>(epsilon);
     return std::sqrt(epsilon_hat);
   }
 };
 
-template <UInt dim>
+template <Int dim>
 class EquivalentStrainMazarsDruckerPrager : public EquivalentStrainMazars<dim> {
 public:
   EquivalentStrainMazarsDruckerPrager(Material & mat)
       : EquivalentStrainMazars<dim>(mat) {
     mat.registerParam("k", k, _pat_parsable, "k");
   }
 
   template <class... Other>
   Real operator()(const Matrix<Real> & epsilon, Real /*unused*/) {
     Real epsilon_hat = EquivalentStrainMazars<dim>::operator()(epsilon);
     epsilon_hat += k * epsilon.trace();
     return epsilon_hat;
   }
 
 protected:
   Real k;
 };
 
 /* -------------------------------------------------------------------------- */
 /* DamageThreshold functions                                                  */
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 class DamageThresholdLinear : public EmptyIteratorContainer {
 public:
   DamageThresholdLinear(Material & mat) : mat(mat) {
     mat.registerParam("A", A, _pat_parsable, "A");
     mat.registerParam("K0", K0, _pat_parsable, "K0");
   }
 
   template <class... Other> Real K(Real x, Other &&... /*other*/) {
     return 1. / A * x + K0;
   }
 
   template <class... Other> Real K_inv(Real x, Other &&... /*other*/) {
     return A * (x - K0);
   }
 
 private:
   Material & mat;
   Real A;
   Real K0;
 };
 
-template <UInt dim> class DamageThresholdTan : public EmptyIteratorContainer {
+template <Int dim> class DamageThresholdTan : public EmptyIteratorContainer {
 public:
   DamageThresholdTan(Material & mat) : mat(mat) {
     mat.registerParam("a", a, _pat_parsable, "a");
     mat.registerParam("A", A, _pat_parsable, "A");
     mat.registerParam("K0", K0, _pat_parsable, "K0");
   }
 
   template <class... Other> Real K(Real x, Other &&... /*other*/) {
     return a * std::tan(std::atan2(x, a) - std::atan2(K0, a));
   }
 
   template <class... Other> Real K_inv(Real x, Other &&... /*other*/) {
     return a * A * (std::atan2(x, a) - std::atan2(K0, a));
   }
 
 private:
   Material & mat;
   Real a{2.93e-4};
   Real A{5e3};
   Real K0{5e-5};
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_ANISOTROPIC_DAMAGE_TMPL_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
index 621273af9..dfdbc56fe 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo.cc
@@ -1,104 +1,104 @@
 /**
  * @file   material_marigo.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Specialization of the material class for the marigo material
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_marigo.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialMarigo<spatial_dimension>::MaterialMarigo(SolidMechanicsModel & model,
                                                   const ID & id)
     : MaterialDamage<spatial_dimension>(model, id), Yd("Yd", *this),
       damage_in_y(false), yc_limit(false) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("Sd", Sd, Real(5000.), _pat_parsable | _pat_modifiable);
   this->registerParam("epsilon_c", epsilon_c, Real(0.), _pat_parsable,
                       "Critical strain");
   this->registerParam("Yc limit", yc_limit, false, _pat_internal,
                       "As the material a critical Y");
   this->registerParam("damage_in_y", damage_in_y, false, _pat_parsable,
                       "Use threshold (1-D)Y");
   this->registerParam("Yd", Yd, _pat_parsable, "Damaging energy threshold");
 
   this->Yd.initialize(1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMarigo<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   MaterialDamage<spatial_dimension>::initMaterial();
 
   updateInternalParameters();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMarigo<spatial_dimension>::updateInternalParameters() {
   MaterialDamage<spatial_dimension>::updateInternalParameters();
   Yc = .5 * epsilon_c * this->E * epsilon_c;
   yc_limit = (std::abs(epsilon_c) > std::numeric_limits<Real>::epsilon());
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMarigo<spatial_dimension>::computeStress(ElementType el_type,
                                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto dam = this->damage(el_type, ghost_type).begin();
   auto Yd_q = this->Yd(el_type, ghost_type).begin();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Real Y = 0.;
   computeStressOnQuad(grad_u, sigma, *dam, Y, *Yd_q);
 
   ++dam;
   ++Yd_q;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 INSTANTIATE_MATERIAL(marigo, MaterialMarigo);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo.hh b/src/model/solid_mechanics/materials/material_damage/material_marigo.hh
index 7102ac5f3..897dba582 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo.hh
@@ -1,124 +1,124 @@
 /**
  * @file   material_marigo.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Marigo damage law
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 #include "material_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_MARIGO_HH_
 #define AKANTU_MATERIAL_MARIGO_HH_
 
 namespace akantu {
 
 /**
  * Material marigo
  *
  * parameters in the material files :
  *   - Yd  : (default: 50)
  *   - Sd  : (default: 5000)
  *   - Ydrandomness  : (default:0)
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialMarigo : public MaterialDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialMarigo(SolidMechanicsModel & model, const ID & id = "");
   ~MaterialMarigo() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   void updateInternalParameters() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(Matrix<Real> & grad_u, Matrix<Real> & sigma,
                                   Real & dam, Real & Y, Real & Ydq);
 
   inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma, Real & dam,
                                            Real & Y, Real & Ydq);
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
 public:
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// resistance to damage
   RandomInternalField<Real> Yd;
 
   /// damage threshold
   Real Sd;
 
   /// critical epsilon when the material is considered as broken
   Real epsilon_c;
 
   Real Yc;
 
   bool damage_in_y;
   bool yc_limit;
 };
 
 } // namespace akantu
 
 #include "material_marigo_inline_impl.hh"
 
 #endif /* AKANTU_MATERIAL_MARIGO_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.hh b/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.hh
index 2eaebd93a..3e288a7e2 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.hh
@@ -1,135 +1,135 @@
 /**
  * @file   material_marigo_inline_impl.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Implementation of the inline functions of the material marigo
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_marigo.hh"
 
 #ifndef AKANTU_MATERIAL_MARIGO_INLINE_IMPL_HH_
 #define AKANTU_MATERIAL_MARIGO_INLINE_IMPL_HH_
 
 namespace akantu {
 
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialMarigo<spatial_dimension>::computeStressOnQuad(
     Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam, Real & Y,
     Real & Ydq) {
   MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
 
   Y = 0;
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       Y += sigma(i, j) * (grad_u(i, j) + grad_u(j, i)) / 2.;
     }
   }
   Y *= 0.5;
 
   if (damage_in_y) {
     Y *= (1 - dam);
   }
 
   if (yc_limit) {
     Y = std::min(Y, Yc);
   }
 
   if (!this->is_non_local) {
     computeDamageAndStressOnQuad(sigma, dam, Y, Ydq);
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialMarigo<spatial_dimension>::computeDamageAndStressOnQuad(
     Matrix<Real> & sigma, Real & dam, Real & Y, Real & Ydq) {
   Real Fd = Y - Ydq - Sd * dam;
 
   if (Fd > 0) {
     dam = (Y - Ydq) / Sd;
   }
   dam = std::min(dam, Real(1.));
 
   sigma *= 1 - dam;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline UInt MaterialMarigo<spatial_dimension>::getNbData(
     const Array<Element> & elements, const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   if (tag == SynchronizationTag::_smm_init_mat) {
     size += sizeof(Real) * this->getModel().getNbIntegrationPoints(elements);
   }
 
   size += MaterialDamage<spatial_dimension>::getNbData(elements, tag);
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialMarigo<spatial_dimension>::packData(
     CommunicationBuffer & buffer, const Array<Element> & elements,
     const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   if (tag == SynchronizationTag::_smm_init_mat) {
     this->packElementDataHelper(Yd, buffer, elements);
   }
 
   MaterialDamage<spatial_dimension>::packData(buffer, elements, tag);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void
 MaterialMarigo<spatial_dimension>::unpackData(CommunicationBuffer & buffer,
                                               const Array<Element> & elements,
                                               const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   if (tag == SynchronizationTag::_smm_init_mat) {
     this->unpackElementDataHelper(Yd, buffer, elements);
   }
 
   MaterialDamage<spatial_dimension>::unpackData(buffer, elements, tag);
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_MARIGO_INLINE_IMPL_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc
index aaf946f4a..747962496 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.cc
@@ -1,107 +1,107 @@
 /**
  * @file   material_marigo_non_local.cc
  *
  * @author Marion Estelle Chambart <mchambart@stucky.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Marigo non-local inline function implementation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_marigo_non_local.hh"
 #include "non_local_neighborhood_base.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialMarigoNonLocal<spatial_dimension>::MaterialMarigoNonLocal(
     SolidMechanicsModel & model, const ID & id)
     : MaterialMarigoNonLocalParent(model, id), Y("Y", *this),
       Ynl("Y non local", *this) {
   AKANTU_DEBUG_IN();
   this->is_non_local = true;
   this->Y.initialize(1);
   this->Ynl.initialize(1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMarigoNonLocal<spatial_dimension>::registerNonLocalVariables() {
   this->model.getNonLocalManager().registerNonLocalVariable(this->Y.getName(),
                                                             Ynl.getName(), 1);
   this->model.getNonLocalManager()
       .getNeighborhood(this->name)
       .registerNonLocalVariable(Ynl.getName());
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMarigoNonLocal<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(el_type, ghost_type).data();
   Real * Yt = this->Y(el_type, ghost_type).data();
   Real * Ydq = this->Yd(el_type, ghost_type).data();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   MaterialMarigo<spatial_dimension>::computeStressOnQuad(grad_u, sigma, *dam,
                                                          *Yt, *Ydq);
   ++dam;
   ++Yt;
   ++Ydq;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMarigoNonLocal<spatial_dimension>::computeNonLocalStress(
     ElementType type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(type, ghost_type).data();
   Real * Ydq = this->Yd(type, ghost_type).data();
   Real * Ynlt = this->Ynl(type, ghost_type).data();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(type, ghost_type);
   this->computeDamageAndStressOnQuad(sigma, *dam, *Ynlt, *Ydq);
 
   ++dam;
   ++Ynlt;
   ++Ydq;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 INSTANTIATE_MATERIAL(marigo_non_local, MaterialMarigoNonLocal);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
index 5dddcec10..cf9f53a2e 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_marigo_non_local.hh
@@ -1,93 +1,93 @@
 /**
  * @file   material_marigo_non_local.hh
  *
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Marigo non-local description
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_damage_non_local.hh"
 #include "material_marigo.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH_
 #define AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 
 /**
  * Material Marigo
  *
  * parameters in the material files :
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialMarigoNonLocal
     : public MaterialDamageNonLocal<spatial_dimension,
                                     MaterialMarigo<spatial_dimension>> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using MaterialMarigoNonLocalParent = MaterialDamageNonLocal<spatial_dimension,
                                  MaterialMarigo<spatial_dimension>>;
   MaterialMarigoNonLocal(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   void registerNonLocalVariables() override;
 
   /// constitutive law
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   void computeNonLocalStress(ElementType type,
                              GhostType ghost_type = _not_ghost) override;
 
 private:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Y, Y, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   InternalField<Real> Y;
   InternalField<Real> Ynl;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_MARIGO_NON_LOCAL_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars.cc b/src/model/solid_mechanics/materials/material_damage/material_mazars.cc
index 6e31b93b0..f87759649 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars.cc
@@ -1,82 +1,82 @@
 /**
  * @file   material_mazars.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Specialization of the material class for the damage material
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_mazars.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialMazars<spatial_dimension>::MaterialMazars(SolidMechanicsModel & model,
                                                   const ID & id)
     : MaterialDamage<spatial_dimension>(model, id), K0("K0", *this),
       damage_in_compute_stress(true) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("K0", K0, _pat_parsable, "K0");
   this->registerParam("At", At, Real(0.8), _pat_parsable, "At");
   this->registerParam("Ac", Ac, Real(1.4), _pat_parsable, "Ac");
   this->registerParam("Bc", Bc, Real(1900.), _pat_parsable, "Bc");
   this->registerParam("Bt", Bt, Real(12000.), _pat_parsable, "Bt");
   this->registerParam("beta", beta, Real(1.06), _pat_parsable, "beta");
 
   this->K0.initialize(1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMazars<spatial_dimension>::computeStress(ElementType el_type,
                                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * dam = this->damage(el_type, ghost_type).data();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Real Ehat = 0;
   computeStressOnQuad(grad_u, sigma, *dam, Ehat);
   ++dam;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(mazars, MaterialMazars);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars.hh b/src/model/solid_mechanics/materials/material_damage/material_mazars.hh
index 8d22b97af..0fc409420 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars.hh
@@ -1,126 +1,126 @@
 /**
  * @file   material_mazars.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Marion Estelle Chambart <mchambart@stucky.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Material Following the Mazars law for damage evolution
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 #include "material_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_MAZARS_HH_
 #define AKANTU_MATERIAL_MAZARS_HH_
 
 namespace akantu {
 
 /**
  * Material Mazars
  *
  * parameters in the material files :
  *   - rho  : density (default: 0)
  *   - E    : Young's modulus (default: 0)
  *   - nu   : Poisson's ratio (default: 1/2)
  *   - K0   : Damage threshold
  *   - At   : Parameter damage traction 1
  *   - Bt   : Parameter damage traction 2
  *   - Ac   : Parameter damage compression 1
  *   - Bc   : Parameter damage compression 2
  *   - beta : Parameter for shear
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialMazars : public MaterialDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialMazars(SolidMechanicsModel & model, const ID & id = "");
   ~MaterialMazars() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(const Matrix<Real> & grad_u,
                                   Matrix<Real> & sigma, Real & damage,
                                   Real & Ehat);
 
   inline void computeDamageAndStressOnQuad(const Matrix<Real> & grad_u,
                                            Matrix<Real> & sigma, Real & damage,
                                            Real & Ehat);
 
   inline void computeDamageOnQuad(const Real & epsilon_equ,
                                   const Matrix<Real> & sigma,
                                   const Vector<Real> & epsilon_princ,
                                   Real & dam);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// damage threshold
   RandomInternalField<Real> K0;
   /// parameter damage traction 1
   Real At;
   /// parameter damage traction 2
   Real Bt;
   /// parameter damage compression 1
   Real Ac;
   /// parameter damage compression 2
   Real Bc;
   /// parameter for shear
   Real beta;
 
   /// specify the variable to average false = ehat, true = damage (only valid
   /// for non local version)
   bool damage_in_compute_stress;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #include "material_mazars_inline_impl.hh"
 
 #endif /* AKANTU_MATERIAL_MAZARS_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.hh b/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.hh
index 68bd0d9b4..8679ae486 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.hh
@@ -1,165 +1,165 @@
 /**
  * @file   material_mazars_inline_impl.hh
  *
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Marion Estelle Chambart <mchambart@stucky.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Apr 06 2011
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Implementation of the inline functions of the material damage
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_mazars.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialMazars<spatial_dimension>::computeStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam,
     Real & Ehat) {
   Matrix<Real> epsilon(3, 3);
   epsilon.zero();
 
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       epsilon(i, j) = .5 * (grad_u(i, j) + grad_u(j, i));
     }
   }
 
   Vector<Real> Fdiag(3);
   Math::matrixEig(3, epsilon.data(), Fdiag.data());
 
   Ehat = 0.;
   for (UInt i = 0; i < 3; ++i) {
     Real epsilon_p = std::max(Real(0.), Fdiag(i));
     Ehat += epsilon_p * epsilon_p;
   }
   Ehat = sqrt(Ehat);
 
   MaterialElastic<spatial_dimension>::computeStressOnQuad(grad_u, sigma);
 
   if (damage_in_compute_stress) {
     computeDamageOnQuad(Ehat, sigma, Fdiag, dam);
   }
 
   if (not this->is_non_local) {
     computeDamageAndStressOnQuad(grad_u, sigma, dam, Ehat);
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialMazars<spatial_dimension>::computeDamageAndStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma, Real & dam,
     Real & Ehat) {
   if (!damage_in_compute_stress) {
     Vector<Real> Fdiag(3);
     Fdiag.zero();
 
     Matrix<Real> epsilon(3, 3);
     epsilon.zero();
     for (UInt i = 0; i < spatial_dimension; ++i) {
       for (UInt j = 0; j < spatial_dimension; ++j) {
         epsilon(i, j) = .5 * (grad_u(i, j) + grad_u(j, i));
       }
     }
 
     Math::matrixEig(3, epsilon.data(), Fdiag.data());
 
     computeDamageOnQuad(Ehat, sigma, Fdiag, dam);
   }
 
   sigma *= 1 - dam;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialMazars<spatial_dimension>::computeDamageOnQuad(
     const Real & epsilon_equ,
     __attribute__((unused)) const Matrix<Real> & sigma,
     const Vector<Real> & epsilon_princ, Real & dam) {
   Real Fs = epsilon_equ - K0;
   if (Fs > 0.) {
     Real dam_t;
     Real dam_c;
     dam_t =
         1 - K0 * (1 - At) / epsilon_equ - At * (exp(-Bt * (epsilon_equ - K0)));
     dam_c =
         1 - K0 * (1 - Ac) / epsilon_equ - Ac * (exp(-Bc * (epsilon_equ - K0)));
 
     Real Cdiag;
     Cdiag = this->E * (1 - this->nu) / ((1 + this->nu) * (1 - 2 * this->nu));
 
     Vector<Real> sigma_princ(3);
     sigma_princ(0) = Cdiag * epsilon_princ(0) +
                      this->lambda * (epsilon_princ(1) + epsilon_princ(2));
     sigma_princ(1) = Cdiag * epsilon_princ(1) +
                      this->lambda * (epsilon_princ(0) + epsilon_princ(2));
     sigma_princ(2) = Cdiag * epsilon_princ(2) +
                      this->lambda * (epsilon_princ(1) + epsilon_princ(0));
 
     Vector<Real> sigma_p(3);
     for (UInt i = 0; i < 3; i++) {
       sigma_p(i) = std::max(Real(0.), sigma_princ(i));
     }
     // sigma_p *= 1. - dam;
 
     Real trace_p = this->nu / this->E * (sigma_p(0) + sigma_p(1) + sigma_p(2));
 
     Real alpha_t = 0;
     for (UInt i = 0; i < 3; ++i) {
       Real epsilon_t = (1 + this->nu) / this->E * sigma_p(i) - trace_p;
       Real epsilon_p = std::max(Real(0.), epsilon_princ(i));
       alpha_t += epsilon_t * epsilon_p;
     }
 
     alpha_t /= epsilon_equ * epsilon_equ;
     alpha_t = std::min(alpha_t, Real(1.));
 
     Real alpha_c = 1. - alpha_t;
 
     alpha_t = std::pow(alpha_t, beta);
     alpha_c = std::pow(alpha_c, beta);
 
     Real damtemp;
     damtemp = alpha_t * dam_t + alpha_c * dam_c;
 
     dam = std::max(damtemp, dam);
     dam = std::min(dam, Real(1.));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 // template<UInt spatial_dimension>
 // inline void
 // MaterialMazars<spatial_dimension>::computeTangentModuliOnQuad(Matrix<Real> &
 // tangent) {
 //   MaterialElastic<spatial_dimension>::computeTangentModuliOnQuad(tangent);
 
 //   tangent *= (1-dam);
 // }
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
index b8b3f4547..0b886df44 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.cc
@@ -1,126 +1,126 @@
 /**
  * @file   material_mazars_non_local.cc
  *
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Specialization of the material class for the non-local mazars
  * material
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_mazars_non_local.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialMazarsNonLocal<spatial_dimension>::MaterialMazarsNonLocal(
     SolidMechanicsModel & model, const ID & id)
     : MaterialNonLocalParent(model, id), Ehat("epsilon_equ", *this),
       non_local_variable("mazars_non_local", *this) {
   AKANTU_DEBUG_IN();
 
   this->is_non_local = true;
   this->Ehat.initialize(1);
   this->non_local_variable.initialize(1);
 
   this->registerParam("average_on_damage", this->damage_in_compute_stress,
                       false, _pat_parsable | _pat_modifiable,
                       "Is D the non local variable");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMazarsNonLocal<spatial_dimension>::registerNonLocalVariables() {
   ID local;
   if (this->damage_in_compute_stress) {
     local = this->damage.getName();
   } else {
     local = this->Ehat.getName();
   }
 
   this->model.getNonLocalManager().registerNonLocalVariable(
       local, non_local_variable.getName(), 1);
   this->model.getNonLocalManager()
       .getNeighborhood(this->name)
       .registerNonLocalVariable(non_local_variable.getName());
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMazarsNonLocal<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real * damage = this->damage(el_type, ghost_type).data();
   Real * epsilon_equ = this->Ehat(el_type, ghost_type).data();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   MaterialMazars<spatial_dimension>::computeStressOnQuad(grad_u, sigma, *damage,
                                                          *epsilon_equ);
   ++damage;
   ++epsilon_equ;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialMazarsNonLocal<spatial_dimension>::computeNonLocalStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   auto & non_loc_var = non_local_variable(el_type, ghost_type);
   Real * damage;
   Real * epsilon_equ;
   if (this->damage_in_compute_stress) {
     damage = non_loc_var.data();
     epsilon_equ = this->Ehat(el_type, ghost_type).data();
   } else {
     damage = this->damage(el_type, ghost_type).data();
     epsilon_equ = non_loc_var.data();
   }
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   this->computeDamageAndStressOnQuad(grad_u, sigma, *damage, *epsilon_equ);
 
   ++damage;
   ++epsilon_equ;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 INSTANTIATE_MATERIAL(mazars_non_local, MaterialMazarsNonLocal);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
index a326996ae..98c325397 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_mazars_non_local.hh
@@ -1,92 +1,92 @@
 /**
  * @file   material_mazars_non_local.hh
  *
  * @author Marion Estelle Chambart <marion.chambart@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Mazars non-local description
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_damage_non_local.hh"
 #include "material_mazars.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH_
 #define AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH_
 
 namespace akantu {
 
 /**
  * Material Mazars Non local
  *
  * parameters in the material files :
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialMazarsNonLocal
     : public MaterialDamageNonLocal<spatial_dimension,
                                     MaterialMazars<spatial_dimension>> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   using MaterialNonLocalParent =
       MaterialDamageNonLocal<spatial_dimension,
                              MaterialMazars<spatial_dimension>>;
 
   MaterialMazarsNonLocal(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   void computeNonLocalStress(ElementType el_type,
                              GhostType ghost_type = _not_ghost) override;
 
   void registerNonLocalVariables() override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// the ehat per quadrature points to perform the averaging
   InternalField<Real> Ehat;
 
   InternalField<Real> non_local_variable;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_MAZARS_NON_LOCAL_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_elastic.cc b/src/model/solid_mechanics/materials/material_elastic.cc
index ac502199d..e8ef013bb 100644
--- a/src/model/solid_mechanics/materials/material_elastic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic.cc
@@ -1,260 +1,260 @@
 /**
  * @file   material_elastic.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Specialization of the material class for the elastic material
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_elastic.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model,
                                       const ID & id)
     : Parent(model, id), was_stiffness_assembled(false) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialElastic<dim>::MaterialElastic(SolidMechanicsModel & model,
                                       UInt /*a_dim*/,
                                       const Mesh & mesh, FEEngine & fe_engine,
                                       const ID & id)
     : Parent(model, dim, mesh, fe_engine, id), was_stiffness_assembled(false) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialElastic<dim>::initialize() {
+template <Int dim> void MaterialElastic<dim>::initialize() {
   this->registerParam("lambda", lambda, _pat_readable,
                       "First Lamé coefficient");
   this->registerParam("mu", mu, _pat_readable, "Second Lamé coefficient");
   this->registerParam("kapa", kpa, _pat_readable, "Bulk coefficient");
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialElastic<dim>::initMaterial() {
+template <Int dim> void MaterialElastic<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
   Parent::initMaterial();
 
   if (dim == 1) {
     this->nu = 0.;
   }
 
   this->updateInternalParameters();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialElastic<dim>::updateInternalParameters() {
+template <Int dim> void MaterialElastic<dim>::updateInternalParameters() {
   MaterialThermal<dim>::updateInternalParameters();
 
   this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2 * this->nu));
   this->mu = this->E / (2 * (1 + this->nu));
 
   this->kpa = this->lambda + 2. / 3. * this->mu;
 
   this->was_stiffness_assembled = false;
 }
 
 /* -------------------------------------------------------------------------- */
 template <> void MaterialElastic<2>::updateInternalParameters() {
   MaterialThermal<2>::updateInternalParameters();
 
   this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - 2 * this->nu));
   this->mu = this->E / (2 * (1 + this->nu));
 
   if (this->plane_stress) {
     this->lambda = this->nu * this->E / ((1 + this->nu) * (1 - this->nu));
   }
 
   this->kpa = this->lambda + 2. / 3. * this->mu;
 
   this->was_stiffness_assembled = false;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialElastic<dim>::computeStress(ElementType el_type,
                                          GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Parent::computeStress(el_type, ghost_type);
 
   Array<Real>::const_scalar_iterator sigma_th_it =
       this->sigma_th(el_type, ghost_type).begin();
 
   if (!this->finite_deformation) {
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
     const Real & sigma_th = *sigma_th_it;
     this->computeStressOnQuad(grad_u, sigma, sigma_th);
     ++sigma_th_it;
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   } else {
     /// finite gradus
     Matrix<Real> E(dim, dim);
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
     /// compute E
     this->template gradUToE<dim>(grad_u, E);
 
     const Real & sigma_th = *sigma_th_it;
 
     /// compute second Piola-Kirchhoff stress tensor
     this->computeStressOnQuad(E, sigma, sigma_th);
 
     ++sigma_th_it;
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
-void MaterialElastic<dim>::computeTangentModuli(ElementType el_type,
+template <Int dim>
+void MaterialElastic<dim>::computeTangentModuli(const ElementType & el_type,
                                                 Array<Real> & tangent_matrix,
                                                 GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
   this->computeTangentModuliOnQuad(tangent);
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   this->was_stiffness_assembled = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
-Real MaterialElastic<dim>::getPushWaveSpeed(const Element & /*unused*/) const {
+template <Int dim>
+Real MaterialElastic<dim>::getPushWaveSpeed(const Element &) const {
   return sqrt((lambda + 2 * mu) / this->rho);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
-Real MaterialElastic<dim>::getShearWaveSpeed(const Element & /*unused*/) const {
+template <Int dim>
+Real MaterialElastic<dim>::getShearWaveSpeed(const Element &) const {
   return sqrt(mu / this->rho);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialElastic<dim>::computePotentialEnergy(ElementType el_type) {
   AKANTU_DEBUG_IN();
 
   // MaterialThermal<dim>::computePotentialEnergy(ElementType)
   // needs to be implemented
   // MaterialThermal<dim>::computePotentialEnergy(el_type);
 
   auto epot = this->potential_energy(el_type, _not_ghost).begin();
 
   if (!this->finite_deformation) {
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
 
     this->computePotentialEnergyOnQuad(grad_u, sigma, *epot);
     ++epot;
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   } else {
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
     auto E = this->template gradUToE<dim>(grad_u);
 
     this->computePotentialEnergyOnQuad(E, sigma, *epot);
     ++epot;
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialElastic<dim>::computePotentialEnergyByElement(
     ElementType type, UInt index, Vector<Real> & epot_on_quad_points) {
   auto gradu_it = this->gradu(type).begin(dim, dim);
   auto gradu_end = this->gradu(type).begin(dim, dim);
   auto stress_it = this->stress(type).begin(dim, dim);
 
   if (this->finite_deformation) {
     stress_it = this->piola_kirchhoff_2(type).begin(dim, dim);
   }
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
 
   gradu_it += index * nb_quadrature_points;
   gradu_end += (index + 1) * nb_quadrature_points;
   stress_it += index * nb_quadrature_points;
 
   Real * epot_quad = epot_on_quad_points.data();
 
   Matrix<Real> grad_u(dim, dim);
 
   if (this->finite_deformation) {
     for (; gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
       auto E = this->template gradUToE<dim>(*gradu_it);
       this->computePotentialEnergyOnQuad(E, *stress_it, *epot_quad);
     }
   } else {
     for (; gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
       this->computePotentialEnergyOnQuad(*gradu_it, *stress_it, *epot_quad);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 Real MaterialElastic<1>::getPushWaveSpeed(const Element & /*element*/) const {
   return std::sqrt(this->E / this->rho);
 }
 
 template <>
 Real MaterialElastic<1>::getShearWaveSpeed(const Element & /*element*/) const {
   AKANTU_EXCEPTION("There is no shear wave speed in 1D");
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(elastic, MaterialElastic);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_elastic.hh b/src/model/solid_mechanics/materials/material_elastic.hh
index 1214316dc..f37521767 100644
--- a/src/model/solid_mechanics/materials/material_elastic.hh
+++ b/src/model/solid_mechanics/materials/material_elastic.hh
@@ -1,160 +1,160 @@
 /**
  * @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: Fri Apr 09 2021
  *
  * @brief  Material isotropic elastic
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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>
+template <Int spatial_dimension>
 class MaterialElastic
     : public PlaneStressToolbox<spatial_dimension,
                                 MaterialThermal<spatial_dimension>> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   using Parent =
       PlaneStressToolbox<spatial_dimension, MaterialThermal<spatial_dimension>>;
 
 public:
   MaterialElastic(SolidMechanicsModel & model, const ID & id = "");
   MaterialElastic(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
                   FEEngine & fe_engine, const ID & id = "");
 
   ~MaterialElastic() override = default;
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(ElementType el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
   /// compute the elastic potential energy
   void computePotentialEnergy(ElementType el_type) override;
 
   void
   computePotentialEnergyByElement(ElementType type, UInt index,
                                   Vector<Real> & epot_on_quad_points) override;
 
   /// compute the p-wave speed in the material
   Real getPushWaveSpeed(const Element & element) const override;
 
   /// compute the s-wave speed in the material
   Real getShearWaveSpeed(const Element & element) const override;
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(const Matrix<Real> & grad_u,
                                   Matrix<Real> & sigma,
                                   Real sigma_th = 0) const;
 
   /// compute the tangent stiffness matrix for an element
   inline void computeTangentModuliOnQuad(Matrix<Real> & tangent) const;
 
   /// recompute the lame coefficient if E or nu changes
   void updateInternalParameters() override;
 
   static inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
                                                   const Matrix<Real> & sigma,
                                                   Real & epot);
 
   bool hasStiffnessMatrixChanged() override {
     return (not was_stiffness_assembled);
   }
 
   MatrixType getTangentType() override {
     return _symmetric;
   }
   
   /* ------------------------------------------------------------------------ */
   /* 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;
 };
 
 } // namespace akantu
 
 #include "material_elastic_inline_impl.hh"
 
 #endif /* AKANTU_MATERIAL_ELASTIC_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_inline_impl.hh b/src/model/solid_mechanics/materials/material_elastic_inline_impl.hh
index 7e94d01b1..d67fb319c 100644
--- a/src/model/solid_mechanics/materials/material_elastic_inline_impl.hh
+++ b/src/model/solid_mechanics/materials/material_elastic_inline_impl.hh
@@ -1,122 +1,122 @@
 /**
  * @file   material_elastic_inline_impl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Implementation of the inline functions of the material elastic
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_ELASTIC_INLINE_IMPL_HH_
 #define AKANTU_MATERIAL_ELASTIC_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialElastic<spatial_dimension>::computeStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma,
     Real sigma_th) const {
   Real trace = grad_u.trace(); // trace = (\nabla u)_{kk}
 
   // \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla
   // u_{ij} + \nabla u_{ji})
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       sigma(i, j) = Math::kronecker(i, j) * lambda * trace +
           mu * (grad_u(i, j) + grad_u(j, i)) + Math::kronecker(i, j) * sigma_th;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void MaterialElastic<1>::computeStressOnQuad(const Matrix<Real> & grad_u,
                                                     Matrix<Real> & sigma,
                                                     Real sigma_th) const {
   sigma(0, 0) = this->E * grad_u(0, 0) + sigma_th;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 inline void MaterialElastic<spatial_dimension>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent) const {
   UInt n = tangent.cols();
 
   // Real Ep = E/((1+nu)*(1-2*nu));
   Real Miiii = lambda + 2 * mu;
   Real Miijj = lambda;
   Real Mijij = mu;
 
   if (spatial_dimension == 1) {
     tangent(0, 0) = this->E;
   } else {
     tangent(0, 0) = Miiii;
   }
 
   // test of dimension should by optimized out by the compiler due to the
   // template
   if (spatial_dimension >= 2) {
     tangent(1, 1) = Miiii;
     tangent(0, 1) = Miijj;
     tangent(1, 0) = Miijj;
 
     tangent(n - 1, n - 1) = Mijij;
   }
 
   if (spatial_dimension == 3) {
     tangent(2, 2) = Miiii;
     tangent(0, 2) = Miijj;
     tangent(1, 2) = Miijj;
     tangent(2, 0) = Miijj;
     tangent(2, 1) = Miijj;
 
     tangent(3, 3) = Mijij;
     tangent(4, 4) = Mijij;
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialElastic<dim>::computePotentialEnergyOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & sigma, Real & epot) {
   epot = .5 * sigma.doubleDot(grad_u);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 MaterialElastic<1>::computeTangentModuliOnQuad(Matrix<Real> & tangent) const {
   tangent(0, 0) = E;
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_ELASTIC_INLINE_IMPL_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
index e065dc3f7..970cab87c 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
@@ -1,262 +1,262 @@
 /**
  * @file   material_elastic_linear_anisotropic.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Till Junge <till.junge@epfl.ch>
  * @author Enrico Milanese <enrico.milanese@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Sep 25 2013
  * @date last modification: Fri Jul 24 2020
  *
  * @brief  Anisotropic elastic material
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_elastic_linear_anisotropic.hh"
 #include "solid_mechanics_model.hh"
 #include <algorithm>
 #include <sstream>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialElasticLinearAnisotropic<dim>::MaterialElasticLinearAnisotropic(
     SolidMechanicsModel & model, const ID & id, bool symmetric)
     : Material(model, id), rot_mat(dim, dim), Cprime(dim * dim, dim * dim),
       C(voigt_h::size, voigt_h::size), eigC(voigt_h::size),
       symmetric(symmetric), was_stiffness_assembled(false) {
   AKANTU_DEBUG_IN();
 
   this->dir_vecs.push_back(std::make_unique<Vector<Real>>(dim));
   (*this->dir_vecs.back())[0] = 1.;
   this->registerParam("n1", *(this->dir_vecs.back()), _pat_parsmod,
                       "Direction of main material axis");
 
   if (dim > 1) {
     this->dir_vecs.push_back(std::make_unique<Vector<Real>>(dim));
     (*this->dir_vecs.back())[1] = 1.;
     this->registerParam("n2", *(this->dir_vecs.back()), _pat_parsmod,
                         "Direction of secondary material axis");
   }
 
   if (dim > 2) {
     this->dir_vecs.push_back(std::make_unique<Vector<Real>>(dim));
     (*this->dir_vecs.back())[2] = 1.;
     this->registerParam("n3", *(this->dir_vecs.back()), _pat_parsmod,
                         "Direction of tertiary material axis");
   }
 
   for (UInt i = 0; i < voigt_h::size; ++i) {
     UInt start = 0;
     if (this->symmetric) {
       start = i;
     }
     for (UInt j = start; j < voigt_h::size; ++j) {
       std::stringstream param("C");
       param << "C" << i + 1 << j + 1;
       this->registerParam(param.str(), this->Cprime(i, j), Real(0.),
                           _pat_parsmod, "Coefficient " + param.str());
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialElasticLinearAnisotropic<dim>::initMaterial() {
+template <Int dim> void MaterialElasticLinearAnisotropic<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
   Material::initMaterial();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialElasticLinearAnisotropic<dim>::updateInternalParameters() {
 
   Material::updateInternalParameters();
   if (this->symmetric) {
     for (UInt i = 0; i < voigt_h::size; ++i) {
       for (UInt j = i + 1; j < voigt_h::size; ++j) {
         this->Cprime(j, i) = this->Cprime(i, j);
       }
     }
   }
   this->rotateCprime();
   this->C.eig(this->eigC);
 
   this->was_stiffness_assembled = false;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt Dim> void MaterialElasticLinearAnisotropic<Dim>::rotateCprime() {
   // start by filling the empty parts fo Cprime
   UInt diff = Dim * Dim - voigt_h::size;
   for (UInt i = voigt_h::size; i < Dim * Dim; ++i) {
     for (UInt j = 0; j < Dim * Dim; ++j) {
       this->Cprime(i, j) = this->Cprime(i - diff, j);
     }
   }
   for (UInt i = 0; i < Dim * Dim; ++i) {
     for (UInt j = voigt_h::size; j < Dim * Dim; ++j) {
       this->Cprime(i, j) = this->Cprime(i, j - diff);
     }
   }
   // construction of rotator tensor
   // normalise rotation matrix
   for (UInt j = 0; j < Dim; ++j) {
     Vector<Real> rot_vec = this->rot_mat(j);
     rot_vec = *this->dir_vecs[j];
     rot_vec.normalize();
   }
 
   // make sure the vectors form a right-handed base
   Vector<Real> test_axis(3);
   Vector<Real> v1(3);
   Vector<Real> v2(3);
   Vector<Real> v3(3, 0.);
 
   if (Dim == 2) {
     for (UInt i = 0; i < Dim; ++i) {
       v1[i] = this->rot_mat(0, i);
       v2[i] = this->rot_mat(1, i);
     }
 
     v3.crossProduct(v1, v2);
     if (v3.norm() < 8 * std::numeric_limits<Real>::epsilon()) {
       AKANTU_ERROR("The axis vectors parallel.");
     }
 
     v3.normalize();
   } else if (Dim == 3) {
     v1 = this->rot_mat(0);
     v2 = this->rot_mat(1);
     v3 = this->rot_mat(2);
   }
 
   test_axis.crossProduct(v1, v2);
   test_axis -= v3;
   if (test_axis.norm() > 8 * std::numeric_limits<Real>::epsilon()) {
     AKANTU_ERROR("The axis vectors do not form a right-handed coordinate "
                  << "system. I. e., ||n1 x n2 - n3|| should be zero, but "
                  << "it is " << test_axis.norm() << ".");
   }
 
   // create the rotator and the reverse rotator
   Matrix<Real> rotator(Dim * Dim, Dim * Dim);
   Matrix<Real> revrotor(Dim * Dim, Dim * Dim);
   for (UInt i = 0; i < Dim; ++i) {
     for (UInt j = 0; j < Dim; ++j) {
       for (UInt k = 0; k < Dim; ++k) {
         for (UInt l = 0; l < Dim; ++l) {
           UInt I = voigt_h::mat[i][j];
           UInt J = voigt_h::mat[k][l];
           rotator(I, J) = this->rot_mat(k, i) * this->rot_mat(l, j);
           revrotor(I, J) = this->rot_mat(i, k) * this->rot_mat(j, l);
         }
       }
     }
   }
 
   // create the full rotated matrix
   Matrix<Real> Cfull(Dim * Dim, Dim * Dim);
   Cfull = rotator * Cprime * revrotor;
 
   for (UInt i = 0; i < voigt_h::size; ++i) {
     for (UInt j = 0; j < voigt_h::size; ++j) {
       this->C(i, j) = Cfull(i, j);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialElasticLinearAnisotropic<dim>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   // Wikipedia convention:
   // 2*eps_ij (i!=j) = voigt_eps_I
   // http://en.wikipedia.org/wiki/Voigt_notation
   AKANTU_DEBUG_IN();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   this->computeStressOnQuad(grad_u, sigma);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialElasticLinearAnisotropic<dim>::computeTangentModuli(
     ElementType el_type, Array<Real> & tangent_matrix, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
 
   this->computeTangentModuliOnQuad(tangent);
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   this->was_stiffness_assembled = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialElasticLinearAnisotropic<dim>::computePotentialEnergy(
     ElementType el_type) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(!this->finite_deformation,
                       "finite deformation not possible in material anisotropic "
                       "(TO BE IMPLEMENTED)");
 
   Array<Real>::scalar_iterator epot =
       this->potential_energy(el_type, _not_ghost).begin();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
 
   computePotentialEnergyOnQuad(grad_u, sigma, *epot);
   ++epot;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 Real MaterialElasticLinearAnisotropic<dim>::getCelerity(
     __attribute__((unused)) const Element & element) const {
   return std::sqrt(this->eigC(0) / rho);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(elastic_anisotropic, MaterialElasticLinearAnisotropic);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.hh b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.hh
index 9fc848098..5d610fe0a 100644
--- a/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.hh
+++ b/src/model/solid_mechanics/materials/material_elastic_linear_anisotropic_inline_impl.hh
@@ -1,74 +1,74 @@
 /**
  * @file   material_elastic_linear_anisotropic_inline_impl.hh
  *
  * @author Enrico Milanese <enrico.milanese@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Feb 16 2018
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Implementation of the inline functions of the material elastic linear
  * anisotropic
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_elastic_linear_anisotropic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_INLINE_IMPL_HH_
 #define AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialElasticLinearAnisotropic<dim>::computeStressOnQuad(
     const Matrix<Real> & grad_u, Matrix<Real> & sigma) const {
   auto voigt_strain = strainToVoigt<dim>(gradUToEpsilon<dim>(grad_u));
   auto voigt_stress = this->C * voigt_strain;
   voigtToStress<dim>(voigt_stress, sigma);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialElasticLinearAnisotropic<dim>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent) const {
 
   tangent.copy(this->C);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialElasticLinearAnisotropic<dim>::computePotentialEnergyOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & sigma, Real & epot) {
 
   AKANTU_DEBUG_ASSERT(this->symmetric,
                       "The elastic constants matrix is not symmetric,"
                       "energy is not path independent.");
 
   epot = .5 * sigma.doubleDot(grad_u);
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_ELASTIC_LINEAR_ANISOTROPIC_INLINE_IMPL_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
index 9a4bdc16c..f7f929935 100644
--- a/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
+++ b/src/model/solid_mechanics/materials/material_elastic_orthotropic.cc
@@ -1,177 +1,177 @@
 /**
  * @file   material_elastic_orthotropic.cc
  *
  * @author Till Junge <till.junge@epfl.ch>
  * @author Enrico Milanese <enrico.milanese@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Orthotropic elastic material
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_elastic_orthotropic.hh"
 #include "solid_mechanics_model.hh"
 #include <algorithm>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt Dim>
 MaterialElasticOrthotropic<Dim>::MaterialElasticOrthotropic(
     SolidMechanicsModel & model, const ID & id)
     : MaterialElasticLinearAnisotropic<Dim>(model, id) {
   AKANTU_DEBUG_IN();
   this->registerParam("E1", E1, Real(0.), _pat_parsmod, "Young's modulus (n1)");
   this->registerParam("E2", E2, Real(0.), _pat_parsmod, "Young's modulus (n2)");
   this->registerParam("nu12", nu12, Real(0.), _pat_parsmod,
                       "Poisson's ratio (12)");
   this->registerParam("G12", G12, Real(0.), _pat_parsmod, "Shear modulus (12)");
 
   if (Dim > 2) {
     this->registerParam("E3", E3, Real(0.), _pat_parsmod,
                         "Young's modulus (n3)");
     this->registerParam("nu13", nu13, Real(0.), _pat_parsmod,
                         "Poisson's ratio (13)");
     this->registerParam("nu23", nu23, Real(0.), _pat_parsmod,
                         "Poisson's ratio (23)");
     this->registerParam("G13", G13, Real(0.), _pat_parsmod,
                         "Shear modulus (13)");
     this->registerParam("G23", G23, Real(0.), _pat_parsmod,
                         "Shear modulus (23)");
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt Dim> void MaterialElasticOrthotropic<Dim>::initMaterial() {
   AKANTU_DEBUG_IN();
   MaterialElasticLinearAnisotropic<Dim>::initMaterial();
 
   AKANTU_DEBUG_ASSERT(not this->finite_deformation,
                       "finite deformation not possible in material orthotropic "
                       "(TO BE IMPLEMENTED)");
 
   updateInternalParameters();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt Dim>
 void MaterialElasticOrthotropic<Dim>::updateInternalParameters() {
 
   this->C.zero();
   this->Cprime.zero();
 
   /* 1) construction of temporary material frame stiffness tensor------------ */
   // http://solidmechanics.org/Text/Chapter3_2/Chapter3_2.php#Sect3_2_13
   Real nu21 = nu12 * E2 / E1;
   Real nu31 = nu13 * E3 / E1;
   Real nu32 = nu23 * E3 / E2;
 
   // Full (i.e. dim^2 by dim^2) stiffness tensor in material frame
   if (Dim == 1) {
     AKANTU_ERROR("Dimensions 1 not implemented: makes no sense to have "
                  "orthotropy for 1D");
   }
 
   Real Gamma;
 
   if (Dim == 3) {
     Gamma = 1 / (1 - nu12 * nu21 - nu23 * nu32 - nu31 * nu13 -
                  2 * nu21 * nu32 * nu13);
   }
 
   if (Dim == 2) {
     Gamma = 1 / (1 - nu12 * nu21);
   }
 
   // Lamé's first parameters
   this->Cprime(0, 0) = E1 * (1 - nu23 * nu32) * Gamma;
   this->Cprime(1, 1) = E2 * (1 - nu13 * nu31) * Gamma;
   if (Dim == 3) {
     this->Cprime(2, 2) = E3 * (1 - nu12 * nu21) * Gamma;
   }
 
   // normalised poisson's ratio's
   this->Cprime(1, 0) = this->Cprime(0, 1) = E1 * (nu21 + nu31 * nu23) * Gamma;
   if (Dim == 3) {
     this->Cprime(2, 0) = this->Cprime(0, 2) = E1 * (nu31 + nu21 * nu32) * Gamma;
     this->Cprime(2, 1) = this->Cprime(1, 2) = E2 * (nu32 + nu12 * nu31) * Gamma;
   }
 
   // Lamé's second parameters (shear moduli)
   if (Dim == 3) {
     this->Cprime(3, 3) = G23;
     this->Cprime(4, 4) = G13;
     this->Cprime(5, 5) = G12;
   } else {
     this->Cprime(2, 2) = G12;
   }
 
   /* 1) rotation of C into the global frame */
   this->rotateCprime();
   this->C.eig(this->eigC);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialElasticOrthotropic<spatial_dimension>::
     computePotentialEnergyByElement(ElementType type, UInt index,
                                     Vector<Real> & epot_on_quad_points) {
 
   Array<Real>::matrix_iterator gradu_it =
       this->gradu(type).begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator gradu_end =
       this->gradu(type).begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator stress_it =
       this->stress(type).begin(spatial_dimension, spatial_dimension);
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
 
   gradu_it += index * nb_quadrature_points;
   gradu_end += (index + 1) * nb_quadrature_points;
   stress_it += index * nb_quadrature_points;
 
   Real * epot_quad = epot_on_quad_points.data();
 
   Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
 
   for (; gradu_it != gradu_end; ++gradu_it, ++stress_it, ++epot_quad) {
     grad_u.copy(*gradu_it);
 
     this->computePotentialEnergyOnQuad(grad_u, *stress_it, *epot_quad);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 INSTANTIATE_MATERIAL(elastic_orthotropic, MaterialElasticOrthotropic);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
index d886085a2..df158755a 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
@@ -1,275 +1,275 @@
 /**
  * @file   material_neohookean.cc
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Apr 08 2013
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Specialization of the material class for finite deformation
  * neo-hookean material
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_neohookean.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialNeohookean<spatial_dimension>::MaterialNeohookean(
     SolidMechanicsModel & model, const ID & id)
     : PlaneStressToolbox<spatial_dimension>(model, id) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("E", E, Real(0.), _pat_parsable | _pat_modifiable,
                       "Young's modulus");
   this->registerParam("nu", nu, Real(0.5), _pat_parsable | _pat_modifiable,
                       "Poisson's ratio");
   this->registerParam("lambda", lambda, _pat_readable,
                       "First Lamé coefficient");
   this->registerParam("mu", mu, _pat_readable, "Second Lamé coefficient");
   this->registerParam("kapa", kpa, _pat_readable, "Bulk coefficient");
 
   this->finite_deformation = true;
   this->initialize_third_axis_deformation = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialNeohookean<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
   PlaneStressToolbox<spatial_dimension>::initMaterial();
   if (spatial_dimension == 1) {
     nu = 0.;
   }
   this->updateInternalParameters();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <> void MaterialNeohookean<2>::initMaterial() {
   AKANTU_DEBUG_IN();
   PlaneStressToolbox<2>::initMaterial();
   this->updateInternalParameters();
 
   if (this->plane_stress) {
     this->third_axis_deformation.setDefaultValue(1.);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialNeohookean<spatial_dimension>::updateInternalParameters() {
   lambda = nu * E / ((1 + nu) * (1 - 2 * nu));
   mu = E / (2 * (1 + nu));
 
   kpa = lambda + 2. / 3. * mu;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialNeohookean<dim>::computeCauchyStressPlaneStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   PlaneStressToolbox<dim>::computeCauchyStressPlaneStress(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void MaterialNeohookean<2>::computeCauchyStressPlaneStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto gradu_it = this->gradu(el_type, ghost_type).begin(2, 2);
   auto gradu_end = this->gradu(el_type, ghost_type).end(2, 2);
   auto piola_it = this->piola_kirchhoff_2(el_type, ghost_type).begin(2, 2);
   auto stress_it = this->stress(el_type, ghost_type).begin(2, 2);
   auto c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
 
   for (; gradu_it != gradu_end; ++gradu_it, ++piola_it, ++stress_it, ++c33_it) {
     Matrix<Real> & grad_u = *gradu_it;
     Matrix<Real> & piola = *piola_it;
     Matrix<Real> & sigma = *stress_it;
 
     StoCauchy<2>(gradUToF<2>(grad_u), piola, sigma, *c33_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialNeohookean<dim>::computeStress(ElementType el_type,
                                             GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   computeStressOnQuad(grad_u, sigma);
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void MaterialNeohookean<2>::computeStress(ElementType el_type,
                                           GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if (this->plane_stress) {
     PlaneStressToolbox<2>::computeStress(el_type, ghost_type);
 
     auto c33_it = this->third_axis_deformation(el_type, ghost_type).begin();
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
     computeStressOnQuad(grad_u, sigma, *c33_it);
     ++c33_it;
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   } else {
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
     computeStressOnQuad(grad_u, sigma);
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialNeohookean<dim>::computeThirdAxisDeformation(
     ElementType /*el_type*/, GhostType /*ghost_type*/) {}
 
 /* -------------------------------------------------------------------------- */
 template <>
 void MaterialNeohookean<2>::computeThirdAxisDeformation(ElementType el_type,
                                                         GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(this->plane_stress, "The third component of the strain "
                                           "can only be computed for 2D "
                                           "problems in Plane Stress!!");
 
   Array<Real>::scalar_iterator c33_it =
       this->third_axis_deformation(el_type, ghost_type).begin();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
   computeThirdAxisDeformationOnQuad(grad_u, *c33_it);
   ++c33_it;
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialNeohookean<spatial_dimension>::computePotentialEnergy(
     ElementType el_type) {
   AKANTU_DEBUG_IN();
 
   Material::computePotentialEnergy(el_type);
 
   Array<Real>::scalar_iterator epot = this->potential_energy(el_type).begin();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
 
   computePotentialEnergyOnQuad(grad_u, *epot);
   ++epot;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialNeohookean<spatial_dimension>::computeTangentModuli(
     __attribute__((unused)) ElementType el_type,
     Array<Real> & tangent_matrix,
     __attribute__((unused)) GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
   computeTangentModuliOnQuad(tangent, grad_u);
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void MaterialNeohookean<2>::computeTangentModuli(__attribute__((unused))
                                                  ElementType el_type,
                                                  Array<Real> & tangent_matrix,
                                                  __attribute__((unused))
                                                  GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if (this->plane_stress) {
     PlaneStressToolbox<2>::computeStress(el_type, ghost_type);
 
     Array<Real>::const_scalar_iterator c33_it =
         this->third_axis_deformation(el_type, ghost_type).begin();
 
     MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
     computeTangentModuliOnQuad(tangent, grad_u, *c33_it);
     ++c33_it;
     MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   } else {
 
     MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
     computeTangentModuliOnQuad(tangent, grad_u);
     MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialNeohookean<spatial_dimension>::getPushWaveSpeed(
     __attribute__((unused)) const Element & element) const {
   return sqrt((this->lambda + 2 * this->mu) / this->rho);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialNeohookean<spatial_dimension>::getShearWaveSpeed(
     __attribute__((unused)) const Element & element) const {
   return sqrt(this->mu / this->rho);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(neohookean, MaterialNeohookean);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
index 3b9e1480d..350d5a477 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
@@ -1,171 +1,171 @@
 /**
  * @file   material_neohookean.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Material isotropic elastic
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 #include "plane_stress_toolbox.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_NEOHOOKEAN_HH_
 #define AKANTU_MATERIAL_NEOHOOKEAN_HH_
 
 namespace akantu {
 
 /**
  * Material elastic isotropic
  *
  * parameters in the material files :
  *   - rho : density (default: 0)
  *   - E   : Young's modulus (default: 0)
  *   - nu  : Poisson's ratio (default: 1/2)
  *   - Plane_Stress : if 0: plane strain, else: plane stress (default: 0)
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialNeohookean : public PlaneStressToolbox<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialNeohookean(SolidMechanicsModel & model, const ID & id = "");
 
   ~MaterialNeohookean() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   /// Computation of the cauchy stress for plane strain materials
   void
   computeCauchyStressPlaneStress(ElementType el_type,
                                  GhostType ghost_type = _not_ghost) override;
 
   /// Non linear computation of the third direction strain in 2D plane stress
   /// case
   void computeThirdAxisDeformation(ElementType el_type,
                                    GhostType ghost_type = _not_ghost) override;
 
   /// compute the elastic potential energy
   void computePotentialEnergy(ElementType el_type) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(ElementType el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
   /// compute the p-wave speed in the material
   Real getPushWaveSpeed(const Element & element) const override;
 
   /// compute the s-wave speed in the material
   Real getShearWaveSpeed(const Element & element) const override;
 
   MatrixType getTangentType() override {
     return _symmetric;
   }
 
 protected:
   /// constitutive law for a given quadrature point
   inline void computePiolaKirchhoffOnQuad(const Matrix<Real> & E,
                                           Matrix<Real> & S);
 
   /// constitutive law for a given quadrature point (first piola)
   inline void computeFirstPiolaKirchhoffOnQuad(const Matrix<Real> & grad_u,
                                                const Matrix<Real> & S,
                                                Matrix<Real> & P);
 
   /// constitutive law for a given quadrature point
   inline void computeDeltaStressOnQuad(const Matrix<Real> & grad_u,
                                        const Matrix<Real> & grad_delta_u,
                                        Matrix<Real> & delta_S);
 
   /// constitutive law for a given quadrature point
   inline void computeStressOnQuad(Matrix<Real> & grad_u, Matrix<Real> & S,
                                   const Real & C33 = 1.0);
 
   /// constitutive law for a given quadrature point
   inline void computeThirdAxisDeformationOnQuad(Matrix<Real> & grad_u,
                                                 Real & c33_value);
 
   /// constitutive law for a given quadrature point
   // inline void updateStressOnQuad(const Matrix<Real> & sigma,
   //                              Matrix<Real> & cauchy_sigma);
 
   /// compute the potential energy for a quadrature point
   inline void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u,
                                            Real & epot);
 
   /// compute the tangent stiffness matrix for an element
   void computeTangentModuliOnQuad(Matrix<Real> & tangent, Matrix<Real> & grad_u,
                                   const Real & C33 = 1.0);
 
   /// recompute the lame coefficient if E or nu changes
   void updateInternalParameters() override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// the young modulus
   Real E;
 
   /// Poisson coefficient
   Real nu;
 
   /// First Lamé coefficient
   Real lambda;
 
   /// Second Lamé coefficient (shear modulus)
   Real mu;
 
   /// Bulk modulus
   Real kpa;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "material_neohookean_inline_impl.hh"
 
 #endif /* AKANTU_MATERIAL_NEOHOOKEAN_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.hh b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.hh
index 2c2375613..5fa99bce8 100644
--- a/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.hh
+++ b/src/model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.hh
@@ -1,200 +1,200 @@
 /**
  * @file   material_neohookean_inline_impl.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  *
  * @date creation: Mon Apr 08 2013
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Implementation of the inline functions of the material elastic
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_neohookean.hh"
 /* -------------------------------------------------------------------------- */
 #include <cmath>
 #include <iostream>
 #include <utility>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialNeohookean<dim>::computeDeltaStressOnQuad(
     __attribute__((unused)) const Matrix<Real> & grad_u,
     __attribute__((unused)) const Matrix<Real> & grad_delta_u,
     __attribute__((unused)) Matrix<Real> & delta_S) {}
 
 //! computes the second piola kirchhoff stress, called S
-template <UInt dim>
+template <Int dim>
 inline void MaterialNeohookean<dim>::computeStressOnQuad(Matrix<Real> & grad_u,
                                                          Matrix<Real> & S,
                                                          const Real & C33) {
   // Neo hookean book
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim);      // Right green
   Matrix<Real> Cminus(dim, dim); // Right green
 
   this->template gradUToF<dim>(grad_u, F);
   this->rightCauchy(F, C);
   Real J = F.det() * sqrt(C33); // the term  sqrt(C33) corresponds to the off
                                 // plane strain (2D plane stress)
   //  std::cout<<"det(F) -> "<<J<<std::endl;
   Cminus.inverse(C);
 
   for (UInt i = 0; i < dim; ++i) {
     for (UInt j = 0; j < dim; ++j) {
       S(i, j) = Math::kronecker(i, j) * mu + (lambda * log(J) - mu) * Cminus(i, j);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 class C33_NR : public Math::NewtonRaphsonFunctor {
 public:
   C33_NR(std::string name, const Real & lambda, const Real & mu,
          const Matrix<Real> & C)
       : NewtonRaphsonFunctor(std::move(name)), lambda(lambda), mu(mu), C(C) {}
 
   inline Real f(Real x) const override {
     return (this->lambda / 2. *
                 (std::log(x) + std::log(this->C(0, 0) * this->C(1, 1) -
                                         Math::pow<2>(this->C(0, 1)))) +
             this->mu * (x - 1.));
   }
 
   inline Real f_prime(Real x) const override {
     AKANTU_DEBUG_ASSERT(std::abs(x) > Math::getTolerance(),
                         "x is zero (x should be the off plane right Cauchy"
                             << " measure in this function so you made a mistake"
                             << " somewhere else that lead to a zero here!!!");
     return (this->lambda / (2. * x) + this->mu);
   }
 
 private:
   const Real & lambda;
   const Real & mu;
   const Matrix<Real> & C;
 };
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialNeohookean<dim>::computeThirdAxisDeformationOnQuad(
     Matrix<Real> & grad_u, Real & c33_value) {
   // Neo hookean book
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim); // Right green
 
   this->template gradUToF<dim>(grad_u, F);
   this->rightCauchy(F, C);
 
   Math::NewtonRaphson nr(1e-5, 100);
   c33_value = nr.solve(
       C33_NR("Neohookean_plan_stress", this->lambda, this->mu, C), c33_value);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void
 MaterialNeohookean<dim>::computePiolaKirchhoffOnQuad(const Matrix<Real> & E,
                                                      Matrix<Real> & S) {
 
   Real trace = E.trace(); /// \f$ trace = (\nabla u)_{kk} \f$
 
   /// \f$ \sigma_{ij} = \lambda * (\nabla u)_{kk} * \delta_{ij} + \mu * (\nabla
   /// u_{ij} + \nabla u_{ji}) \f$
   for (UInt i = 0; i < dim; ++i) {
     for (UInt j = 0; j < dim; ++j) {
       S(i, j) = Math::kronecker(i, j) * lambda * trace + 2.0 * mu * E(i, j);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialNeohookean<dim>::computeFirstPiolaKirchhoffOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & S, Matrix<Real> & P) {
 
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim); // Right green
 
   this->template gradUToF<dim>(grad_u, F);
 
   // first Piola-Kirchhoff is computed as the product of the deformation
   // gracient
   // tensor and the second Piola-Kirchhoff stress tensor
 
   P = F * S;
 }
 
 /**************************************************************************************/
 /*  Computation of the potential energy for a this neo hookean material */
-template <UInt dim>
+template <Int dim>
 inline void MaterialNeohookean<dim>::computePotentialEnergyOnQuad(
     const Matrix<Real> & grad_u, Real & epot) {
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim); // Right green
 
   this->template gradUToF<dim>(grad_u, F);
   this->rightCauchy(F, C);
   Real J = F.det();
   //  std::cout<<"det(F) -> "<<J<<std::endl;
 
   epot =
       0.5 * lambda * pow(log(J), 2.) + mu * (-log(J) + 0.5 * (C.trace() - dim));
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialNeohookean<dim>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent, Matrix<Real> & grad_u, const Real & C33) {
 
   // Neo hookean book
   UInt cols = tangent.cols();
   UInt rows = tangent.rows();
   Matrix<Real> F(dim, dim);
   Matrix<Real> C(dim, dim);
   Matrix<Real> Cminus(dim, dim);
   this->template gradUToF<dim>(grad_u, F);
   this->rightCauchy(F, C);
   Real J = F.det() * sqrt(C33);
   //  std::cout<<"det(F) -> "<<J<<std::endl;
   Cminus.inverse(C);
 
   for (UInt m = 0; m < rows; m++) {
     UInt i = VoigtHelper<dim>::vec[m][0];
     UInt j = VoigtHelper<dim>::vec[m][1];
     for (UInt n = 0; n < cols; n++) {
       UInt k = VoigtHelper<dim>::vec[n][0];
       UInt l = VoigtHelper<dim>::vec[n][1];
 
       // book belytchko
       tangent(m, n) = lambda * Cminus(i, j) * Cminus(k, l) +
                       (mu - lambda * log(J)) * (Cminus(i, k) * Cminus(j, l) +
                                                 Cminus(i, l) * Cminus(k, j));
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
index afeb80be3..1acf29fbb 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
@@ -1,205 +1,205 @@
 /**
  * @file   material_linear_isotropic_hardening.cc
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Apr 07 2014
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Specialization of the material class for isotropic finite deformation
  * linear hardening plasticity
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_linear_isotropic_hardening.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialLinearIsotropicHardening<dim>::MaterialLinearIsotropicHardening(
     SolidMechanicsModel & model, const ID & id)
     : MaterialPlastic<dim>(model, id) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialLinearIsotropicHardening<spatial_dimension>::
     MaterialLinearIsotropicHardening(SolidMechanicsModel & model, UInt dim,
                                      const Mesh & mesh, FEEngine & fe_engine,
                                      const ID & id)
     : MaterialPlastic<spatial_dimension>(model, dim, mesh, fe_engine, id) {}
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialLinearIsotropicHardening<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   // NOLINTNEXTLINE(bugprone-parent-virtual-call)
   MaterialThermal<spatial_dimension>::computeStress(el_type, ghost_type);
 
   // infinitesimal and finite deformation
   auto sigma_th_it = this->sigma_th(el_type, ghost_type).begin();
 
   auto previous_sigma_th_it =
       this->sigma_th.previous(el_type, ghost_type).begin();
 
   auto previous_gradu_it = this->gradu.previous(el_type, ghost_type)
                                .begin(spatial_dimension, spatial_dimension);
 
   auto previous_stress_it = this->stress.previous(el_type, ghost_type)
                                 .begin(spatial_dimension, spatial_dimension);
 
   auto inelastic_strain_it = this->inelastic_strain(el_type, ghost_type)
                                  .begin(spatial_dimension, spatial_dimension);
 
   auto previous_inelastic_strain_it =
       this->inelastic_strain.previous(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension);
 
   auto iso_hardening_it = this->iso_hardening(el_type, ghost_type).begin();
 
   auto previous_iso_hardening_it =
       this->iso_hardening.previous(el_type, ghost_type).begin();
 
   //
   // Finite Deformations
   //
   if (this->finite_deformation) {
     auto previous_piola_kirchhoff_2_it =
         this->piola_kirchhoff_2.previous(el_type, ghost_type)
             .begin(spatial_dimension, spatial_dimension);
 
     auto green_strain_it = this->green_strain(el_type, ghost_type)
                                .begin(spatial_dimension, spatial_dimension);
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
     auto & inelastic_strain_tensor = *inelastic_strain_it;
     auto & previous_inelastic_strain_tensor = *previous_inelastic_strain_it;
     auto & previous_grad_u = *previous_gradu_it;
     auto & previous_sigma = *previous_piola_kirchhoff_2_it;
 
     auto & green_strain = *green_strain_it;
     this->template gradUToE<spatial_dimension>(grad_u, green_strain);
     Matrix<Real> previous_green_strain(spatial_dimension, spatial_dimension);
     this->template gradUToE<spatial_dimension>(previous_grad_u,
                                                          previous_green_strain);
     Matrix<Real> F_tensor(spatial_dimension, spatial_dimension);
     this->template gradUToF<spatial_dimension>(grad_u, F_tensor);
 
     computeStressOnQuad(green_strain, previous_green_strain, sigma,
                         previous_sigma, inelastic_strain_tensor,
                         previous_inelastic_strain_tensor, *iso_hardening_it,
                         *previous_iso_hardening_it, *sigma_th_it,
                         *previous_sigma_th_it, F_tensor);
 
     ++sigma_th_it;
     ++inelastic_strain_it;
     ++iso_hardening_it;
     ++previous_sigma_th_it;
     //++previous_stress_it;
     ++previous_gradu_it;
     ++green_strain_it;
     ++previous_inelastic_strain_it;
     ++previous_iso_hardening_it;
     ++previous_piola_kirchhoff_2_it;
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   }
   // Infinitesimal deformations
   else {
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
     auto & inelastic_strain_tensor = *inelastic_strain_it;
     auto & previous_inelastic_strain_tensor = *previous_inelastic_strain_it;
     auto & previous_grad_u = *previous_gradu_it;
     auto & previous_sigma = *previous_stress_it;
 
     computeStressOnQuad(
         grad_u, previous_grad_u, sigma, previous_sigma, inelastic_strain_tensor,
         previous_inelastic_strain_tensor, *iso_hardening_it,
         *previous_iso_hardening_it, *sigma_th_it, *previous_sigma_th_it);
     ++sigma_th_it;
     ++inelastic_strain_it;
     ++iso_hardening_it;
     ++previous_sigma_th_it;
     ++previous_stress_it;
     ++previous_gradu_it;
     ++previous_inelastic_strain_it;
     ++previous_iso_hardening_it;
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialLinearIsotropicHardening<spatial_dimension>::computeTangentModuli(
     ElementType el_type, Array<Real> & tangent_matrix,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto previous_gradu_it = this->gradu.previous(el_type, ghost_type)
                                .begin(spatial_dimension, spatial_dimension);
 
   auto previous_stress_it = this->stress.previous(el_type, ghost_type)
                                 .begin(spatial_dimension, spatial_dimension);
 
   auto iso_hardening = this->iso_hardening(el_type, ghost_type).begin();
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
 
   computeTangentModuliOnQuad(tangent, grad_u, *previous_gradu_it, sigma,
                              *previous_stress_it, *iso_hardening);
 
   ++previous_gradu_it;
   ++previous_stress_it;
   ++iso_hardening;
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   this->was_stiffness_assembled = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(plastic_linear_isotropic_hardening,
                      MaterialLinearIsotropicHardening);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
index bd330ea7c..8d339c2b1 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
@@ -1,116 +1,116 @@
 /**
  * @file   material_linear_isotropic_hardening.hh
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Specialization of the material class for isotropic finite deformation
  * linear hardening plasticity
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_voigthelper.hh"
 #include "material_plastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_LINEAR_ISOTROPIC_HARDENING_HH_
 #define AKANTU_MATERIAL_LINEAR_ISOTROPIC_HARDENING_HH_
 
 namespace akantu {
 
 /**
  * Material plastic with a linear evolution of the yielding stress
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialLinearIsotropicHardening
     : public MaterialPlastic<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialLinearIsotropicHardening(SolidMechanicsModel & model,
                                    const ID & id = "");
   MaterialLinearIsotropicHardening(SolidMechanicsModel & model, UInt dim,
                                    const Mesh & mesh, FEEngine & fe_engine,
                                    const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(ElementType el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
 protected:
   /// Infinitesimal deformations
   inline void
   computeStressOnQuad(const Matrix<Real> & grad_u,
                       const Matrix<Real> & previous_grad_u,
                       Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
                       Matrix<Real> & inelastic_strain,
                       const Matrix<Real> & previous_inelastic_strain,
                       Real & iso_hardening, const Real & previous_iso_hardening,
                       const Real & sigma_th, const Real & previous_sigma_th);
   /// Finite deformations
   inline void computeStressOnQuad(
       const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
       Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
       Matrix<Real> & inelastic_strain,
       const Matrix<Real> & previous_inelastic_strain, Real & iso_hardening,
       const Real & previous_iso_hardening, const Real & sigma_th,
       const Real & previous_sigma_th, const Matrix<Real> & F_tensor);
 
   inline void computeTangentModuliOnQuad(
       Matrix<Real> & tangent, const Matrix<Real> & grad_u,
       const Matrix<Real> & previous_grad_u, const Matrix<Real> & sigma_tensor,
       const Matrix<Real> & previous_sigma_tensor,
       const Real & iso_hardening) const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #include "material_linear_isotropic_hardening_inline_impl.hh"
 
 #endif /* AKANTU_MATERIAL_LINEAR_ISOTROPIC_HARDENING_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.hh b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.hh
index d5ae4a2a9..a17b2dc12 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.hh
@@ -1,302 +1,302 @@
 /**
  * @file   material_linear_isotropic_hardening_inline_impl.hh
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Benjamin Paccaud <benjamin.paccaud@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Apr 07 2014
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Implementation of the inline functions of the material plasticity
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_linear_isotropic_hardening.hh"
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 /// Infinitesimal deformations
-template <UInt dim>
+template <Int dim>
 inline void MaterialLinearIsotropicHardening<dim>::computeStressOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
     Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
     Matrix<Real> & inelastic_strain,
     const Matrix<Real> & previous_inelastic_strain, Real & iso_hardening,
     const Real & previous_iso_hardening, const Real & sigma_th,
     const Real & previous_sigma_th) {
 
   Real delta_sigma_th = sigma_th - previous_sigma_th;
 
   Matrix<Real> grad_delta_u(grad_u);
   grad_delta_u -= previous_grad_u;
 
   // Compute trial stress, sigma_tr
   Matrix<Real> sigma_tr(dim, dim);
   MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr,
                                             delta_sigma_th);
   sigma_tr += previous_sigma;
 
   // We need a full stress tensor, otherwise the VM stress is messed up
   Matrix<Real> sigma_tr_dev(3, 3, 0);
   for (UInt i = 0; i < dim; ++i) {
     for (UInt j = 0; j < dim; ++j) {
       sigma_tr_dev(i, j) = sigma_tr(i, j);
     }
   }
 
   sigma_tr_dev -= Matrix<Real>::eye(3, sigma_tr.trace() / 3.0);
 
   // Compute effective deviatoric trial stress
   Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
   Real sigma_tr_dev_eff = std::sqrt(3. / 2. * s);
 
   bool initial_yielding =
       ((sigma_tr_dev_eff - iso_hardening - this->sigma_y) > 0);
 
   Real dp = (initial_yielding)
                 ? (sigma_tr_dev_eff - this->sigma_y - previous_iso_hardening) /
                       (3 * this->mu + this->h)
                 : 0;
 
   iso_hardening = previous_iso_hardening + this->h * dp;
 
   // Compute inelastic strain (ignore last components in 1-2D)
   Matrix<Real> delta_inelastic_strain(dim, dim, 0.);
   if (std::abs(sigma_tr_dev_eff) >
       sigma_tr_dev.norm<L_inf>() * Math::getTolerance()) {
     for (UInt i = 0; i < dim; ++i) {
       for (UInt j = 0; j < dim; ++j) {
         delta_inelastic_strain(i, j) = sigma_tr_dev(i, j);
       }
     }
     delta_inelastic_strain *= 3. / 2. * dp / sigma_tr_dev_eff;
   }
 
   MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
       grad_delta_u, sigma, previous_sigma, inelastic_strain,
       previous_inelastic_strain, delta_inelastic_strain);
 }
 
 /* -------------------------------------------------------------------------- */
 /// Finite deformations
-template <UInt dim>
+template <Int dim>
 inline void MaterialLinearIsotropicHardening<dim>::computeStressOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
     Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
     Matrix<Real> & inelastic_strain,
     const Matrix<Real> & previous_inelastic_strain, Real & iso_hardening,
     const Real & previous_iso_hardening, const Real & sigma_th,
     const Real & previous_sigma_th, const Matrix<Real> & F_tensor) {
   // Finite plasticity
   Real dp = 0.0;
   Real d_dp = 0.0;
   UInt n = 0;
 
   Real delta_sigma_th = sigma_th - previous_sigma_th;
 
   Matrix<Real> grad_delta_u(grad_u);
   grad_delta_u -= previous_grad_u;
 
   // Compute trial stress, sigma_tr
   Matrix<Real> sigma_tr(dim, dim);
   MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr,
                                             delta_sigma_th);
   sigma_tr += previous_sigma;
 
   // Compute deviatoric trial stress,  sigma_tr_dev
   Matrix<Real> sigma_tr_dev(sigma_tr);
   sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
 
   // Compute effective deviatoric trial stress
   Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
   Real sigma_tr_dev_eff = std::sqrt(3. / 2. * s);
 
   // compute the cauchy stress to apply the Von-Mises criterion
   Matrix<Real> cauchy_stress(dim, dim);
   Material::StoCauchy<dim>(F_tensor, sigma_tr, cauchy_stress);
   Matrix<Real> cauchy_stress_dev(cauchy_stress);
   cauchy_stress_dev -= Matrix<Real>::eye(dim, cauchy_stress.trace() / 3.0);
   Real c = cauchy_stress_dev.doubleDot(cauchy_stress_dev);
   Real cauchy_stress_dev_eff = std::sqrt(3. / 2. * c);
 
   const Real iso_hardening_t = previous_iso_hardening;
   iso_hardening = iso_hardening_t;
   // Loop for correcting stress based on yield function
 
   // F is written in terms of S
   // bool initial_yielding = ( (sigma_tr_dev_eff - iso_hardening -
   // this->sigma_y) > 0) ;
   // while ( initial_yielding && std::abs(sigma_tr_dev_eff - iso_hardening -
   // this->sigma_y) > Math::getTolerance() ) {
 
   //   d_dp = (sigma_tr_dev_eff - 3. * this->mu *dp -  iso_hardening -
   //   this->sigma_y)
   //     / (3. * this->mu + this->h);
 
   //   //r = r +  h * dp;
   //   dp = dp + d_dp;
   //   iso_hardening = iso_hardening_t + this->h * dp;
 
   //   ++n;
 
   //   /// TODO : explicit this criterion with an error message
   //   if ((std::abs(d_dp) < 1e-9) || (n>50)){
   //     AKANTU_DEBUG_INFO("convergence of increment of plastic strain. d_dp:"
   //     << d_dp << "\tNumber of iteration:"<<n);
   //     break;
   //   }
   // }
 
   // F is written in terms of cauchy stress
   bool initial_yielding =
       ((cauchy_stress_dev_eff - iso_hardening - this->sigma_y) > 0);
   while (initial_yielding && std::abs(cauchy_stress_dev_eff - iso_hardening -
                                       this->sigma_y) > Math::getTolerance()) {
 
     d_dp = (cauchy_stress_dev_eff - 3. * this->mu * dp - iso_hardening -
             this->sigma_y) /
            (3. * this->mu + this->h);
 
     // r = r +  h * dp;
     dp = dp + d_dp;
     iso_hardening = iso_hardening_t + this->h * dp;
 
     ++n;
     /// TODO : explicit this criterion with an error message
     if ((d_dp < 1e-5) || (n > 50)) {
       AKANTU_DEBUG_INFO("convergence of increment of plastic strain. d_dp:"
                         << d_dp << "\tNumber of iteration:" << n);
       break;
     }
   }
 
   // Update internal variable
   Matrix<Real> delta_inelastic_strain(dim, dim, 0.);
   if (std::abs(sigma_tr_dev_eff) >
       sigma_tr_dev.norm<L_inf>() * Math::getTolerance()) {
 
     // /// compute the direction of the plastic strain as \frac{\partial
     // F}{\partial S} = \frac{3}{2J\sigma_{effective}}} Ft \sigma_{dev} F
     Matrix<Real> cauchy_dev_F(dim, dim);
     cauchy_dev_F.mul<false, false>(F_tensor, cauchy_stress_dev);
     Real J = F_tensor.det();
     Real constant = not Math::are_float_equal(J, 0.) ? 1. / J : 0;
     constant *= 3. * dp / (2. * cauchy_stress_dev_eff);
     delta_inelastic_strain.mul<true, false>(F_tensor, cauchy_dev_F, constant);
 
     // Direction given by the piola kirchhoff deviatoric tensor \frac{\partial
     // F}{\partial S} = \frac{3}{2\sigma_{effective}}}S_{dev}
     // delta_inelastic_strain.copy(sigma_tr_dev);
     // delta_inelastic_strain *= 3./2. * dp / sigma_tr_dev_eff;
   }
 
   MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
       grad_delta_u, sigma, previous_sigma, inelastic_strain,
       previous_inelastic_strain, delta_inelastic_strain);
 }
 
 /* -------------------------------------------------------------------------- */
 
-template <UInt dim>
+template <Int dim>
 inline void MaterialLinearIsotropicHardening<dim>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent, __attribute__((unused)) const Matrix<Real> & grad_u,
     __attribute__((unused)) const Matrix<Real> & previous_grad_u,
     __attribute__((unused)) const Matrix<Real> & sigma_tensor,
     __attribute__((unused)) const Matrix<Real> & previous_sigma_tensor,
     __attribute__((unused)) const Real & iso_hardening) const {
   // Real r=iso_hardening;
 
   // Matrix<Real> grad_delta_u(grad_u);
   // grad_delta_u -= previous_grad_u;
 
   // //Compute trial stress, sigma_tr
   // Matrix<Real> sigma_tr(dim, dim);
   // MaterialElastic<dim>::computeStressOnQuad(grad_delta_u, sigma_tr);
   // sigma_tr += previous_sigma_tensor;
 
   // // Compute deviatoric trial stress,  sigma_tr_dev
   // Matrix<Real> sigma_tr_dev(sigma_tr);
   // sigma_tr_dev -= Matrix<Real>::eye(dim, sigma_tr.trace() / 3.0);
 
   // // Compute effective deviatoric trial stress
   // Real s = sigma_tr_dev.doubleDot(sigma_tr_dev);
   // Real sigma_tr_dev_eff=std::sqrt(3./2. * s);
 
   // // Compute deviatoric stress,  sigma_dev
   // Matrix<Real> sigma_dev(sigma_tensor);
   // sigma_dev -= Matrix<Real>::eye(dim, sigma_tensor.trace() / 3.0);
 
   // // Compute effective deviatoric stress
   // s =  sigma_dev.doubleDot(sigma_dev);
   // Real sigma_dev_eff = std::sqrt(3./2. * s);
 
   // Real xr = 0.0;
   // if(sigma_tr_dev_eff > sigma_dev_eff * Math::getTolerance())
   //   xr = sigma_dev_eff / sigma_tr_dev_eff;
 
   // Real __attribute__((unused)) q = 1.5 * (1. / (1. +  3. * this->mu  /
   // this->h) - xr);
 
   /*
   UInt cols = tangent.cols();
   UInt rows = tangent.rows();
 
   for (UInt m = 0; m < rows; ++m) {
     UInt i = VoigtHelper<dim>::vec[m][0];
     UInt j = VoigtHelper<dim>::vec[m][1];
 
     for (UInt n = 0; n < cols; ++n) {
       UInt k = VoigtHelper<dim>::vec[n][0];
       UInt l = VoigtHelper<dim>::vec[n][1];
       */
 
   // This section of the code is commented
   // There were some problems with the convergence of plastic-coupled
   // simulations with thermal expansion
   // XXX: DO NOT REMOVE
   /*if (((sigma_tr_dev_eff-iso_hardening-sigmay) > 0) && (xr > 0)) {
     tangent(m,n) =
     2. * this->mu * q * (sigma_tr_dev (i,j) / sigma_tr_dev_eff) * (sigma_tr_dev
     (k,l) / sigma_tr_dev_eff) +
     (i==k) * (j==l) * 2. * this->mu * xr +
     (i==j) * (k==l) * (this->kpa - 2./3. * this->mu * xr);
     if ((m == n) && (m>=dim))
     tangent(m, n) = tangent(m, n) - this->mu * xr;
     } else {*/
   /*
   tangent(m,n) =  (i==k) * (j==l) * 2. * this->mu +
     (i==j) * (k==l) * this->lambda;
   tangent(m,n) -= (m==n) * (m>=dim) * this->mu;
   */
   //}
   // correct tangent stiffness for shear component
   //}
   //}
   MaterialElastic<dim>::computeTangentModuliOnQuad(tangent);
 }
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc b/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
index 73bf43b23..7eaa01794 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic.cc
@@ -1,202 +1,202 @@
 /**
  * @file   material_plastic.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Apr 07 2014
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Implemantation of the akantu::MaterialPlastic class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_plastic.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialPlastic<spatial_dimension>::MaterialPlastic(SolidMechanicsModel & model,
                                                     const ID & id)
     : MaterialElastic<spatial_dimension>(model, id),
       iso_hardening("iso_hardening", *this),
       inelastic_strain("inelastic_strain", *this),
       plastic_energy("plastic_energy", *this),
       d_plastic_energy("d_plastic_energy", *this) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialPlastic<spatial_dimension>::MaterialPlastic(SolidMechanicsModel & model,
                                                     UInt dim, const Mesh & mesh,
                                                     FEEngine & fe_engine,
                                                     const ID & id)
     : MaterialElastic<spatial_dimension>(model, dim, mesh, fe_engine, id),
       iso_hardening("iso_hardening", *this, dim, fe_engine,
                     this->element_filter),
       inelastic_strain("inelastic_strain", *this, dim, fe_engine,
                        this->element_filter),
       plastic_energy("plastic_energy", *this, dim, fe_engine,
                      this->element_filter),
       d_plastic_energy("d_plastic_energy", *this, dim, fe_engine,
                        this->element_filter) {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialPlastic<spatial_dimension>::initialize() {
   this->registerParam("h", h, Real(0.), _pat_parsable | _pat_modifiable,
                       "Hardening  modulus");
   this->registerParam("sigma_y", sigma_y, Real(0.),
                       _pat_parsable | _pat_modifiable, "Yield stress");
 
   this->iso_hardening.initialize(1);
   this->iso_hardening.initializeHistory();
 
   this->plastic_energy.initialize(1);
   this->d_plastic_energy.initialize(1);
 
   this->use_previous_stress = true;
   this->use_previous_gradu = true;
   this->use_previous_stress_thermal = true;
 
   this->inelastic_strain.initialize(spatial_dimension * spatial_dimension);
   this->inelastic_strain.initializeHistory();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialPlastic<spatial_dimension>::getEnergy(const std::string & type) {
   if (type == "plastic") {
     return getPlasticEnergy();
   }
   return MaterialElastic<spatial_dimension>::getEnergy(type);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialPlastic<spatial_dimension>::getPlasticEnergy() {
   AKANTU_DEBUG_IN();
 
   Real penergy = 0.;
 
   for (auto & type :
        this->element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     penergy +=
         this->fem.integrate(plastic_energy(type, _not_ghost), type, _not_ghost,
                             this->element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return penergy;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialPlastic<spatial_dimension>::computePotentialEnergy(
     ElementType el_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real>::scalar_iterator epot = this->potential_energy(el_type).begin();
 
   Array<Real>::const_iterator<Matrix<Real>> inelastic_strain_it =
       this->inelastic_strain(el_type).begin(spatial_dimension,
                                             spatial_dimension);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
 
   Matrix<Real> elastic_strain(spatial_dimension, spatial_dimension);
   elastic_strain.copy(grad_u);
   elastic_strain -= *inelastic_strain_it;
 
   MaterialElastic<spatial_dimension>::computePotentialEnergyOnQuad(
       elastic_strain, sigma, *epot);
 
   ++epot;
   ++inelastic_strain_it;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialPlastic<spatial_dimension>::updateEnergies(ElementType el_type) {
   AKANTU_DEBUG_IN();
 
   MaterialElastic<spatial_dimension>::updateEnergies(el_type);
 
   Array<Real>::iterator<> pe_it = this->plastic_energy(el_type).begin();
 
   Array<Real>::iterator<> wp_it = this->d_plastic_energy(el_type).begin();
 
   Array<Real>::iterator<Matrix<Real>> inelastic_strain_it =
       this->inelastic_strain(el_type).begin(spatial_dimension,
                                             spatial_dimension);
 
   Array<Real>::iterator<Matrix<Real>> previous_inelastic_strain_it =
       this->inelastic_strain.previous(el_type).begin(spatial_dimension,
                                                      spatial_dimension);
 
   Array<Real>::matrix_iterator previous_sigma =
       this->stress.previous(el_type).begin(spatial_dimension,
                                            spatial_dimension);
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
 
   Matrix<Real> delta_strain_it(*inelastic_strain_it);
   delta_strain_it -= *previous_inelastic_strain_it;
 
   Matrix<Real> sigma_h(sigma);
   sigma_h += *previous_sigma;
 
   *wp_it = .5 * sigma_h.doubleDot(delta_strain_it);
 
   *pe_it += *wp_it;
 
   ++pe_it;
   ++wp_it;
   ++inelastic_strain_it;
   ++previous_inelastic_strain_it;
   ++previous_sigma;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL_ONLY(MaterialPlastic);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh b/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
index 5e908bc97..e470629fc 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic.hh
@@ -1,134 +1,134 @@
 /**
  * @file   material_plastic.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Common interface for plastic materials
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_PLASTIC_HH_
 #define AKANTU_MATERIAL_PLASTIC_HH_
 
 namespace akantu {
 
 /**
  * Parent class for the plastic constitutive laws
  * parameters in the material files :
  *   - h : Hardening parameter (default: 0)
  *   - sigmay : Yield stress
  */
-template <UInt dim> class MaterialPlastic : public MaterialElastic<dim> {
+template <Int dim> class MaterialPlastic : public MaterialElastic<dim> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialPlastic(SolidMechanicsModel & model, const ID & id = "");
   MaterialPlastic(SolidMechanicsModel & model, UInt a_dim, const Mesh & mesh,
                   FEEngine & fe_engine, const ID & id = "");
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /**
    * @brief Return potential or plastic energy
    *
    * Plastic dissipated energy is integrated over time.
    */
   Real getEnergy(const std::string & type) override;
 
   /// Update the plastic energy for the current timestep
   void updateEnergies(ElementType el_type) override;
 
   /// Compute the true potential energy (w/ elastic strain)
   void computePotentialEnergy(ElementType el_type) override;
 
 protected:
   /// compute the stress and inelastic strain for the quadrature point
   inline void computeStressAndInelasticStrainOnQuad(
       const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
       Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
       Matrix<Real> & inelastic_strain,
       const Matrix<Real> & previous_inelastic_strain,
       const Matrix<Real> & delta_inelastic_strain) const;
 
   inline void computeStressAndInelasticStrainOnQuad(
       const Matrix<Real> & delta_grad_u, Matrix<Real> & sigma,
       const Matrix<Real> & previous_sigma, Matrix<Real> & inelastic_strain,
       const Matrix<Real> & previous_inelastic_strain,
       const Matrix<Real> & delta_inelastic_strain) const;
 
   /// Get the integrated plastic energy for the time step
   Real getPlasticEnergy();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Yield stresss
   Real sigma_y;
 
   /// hardening modulus
   Real h;
 
   /// isotropic hardening, r
   InternalField<Real> iso_hardening;
 
   /// inelastic strain arrays ordered by element types (inelastic deformation)
   InternalField<Real> inelastic_strain;
 
   /// Plastic energy
   InternalField<Real> plastic_energy;
 
   /// @todo : add a coefficient beta that will multiply the plastic energy
   /// increment
   /// to compute the energy converted to heat
 
   /// Plastic energy increment
   InternalField<Real> d_plastic_energy;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #include "material_plastic_inline_impl.hh"
 #endif /* AKANTU_MATERIAL_PLASTIC_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.hh b/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.hh
index e1361c09b..43ecd23e5 100644
--- a/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.hh
+++ b/src/model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.hh
@@ -1,77 +1,77 @@
 /**
  * @file   material_plastic_inline_impl.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: Mon Apr 07 2014
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Implementation of the inline functions of akantu::MaterialPlastic
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 MATERIAL_PLASTIC_INLINE_IMPL_H
 #define MATERIAL_PLASTIC_INLINE_IMPL_H
 
 #include "material_plastic.hh"
 
 namespace akantu {
 
-template <UInt dim>
+template <Int dim>
 inline void MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
     const Matrix<Real> & delta_grad_u, Matrix<Real> & sigma,
     const Matrix<Real> & previous_sigma, Matrix<Real> & inelastic_strain,
     const Matrix<Real> & previous_inelastic_strain,
     const Matrix<Real> & delta_inelastic_strain) const {
   Matrix<Real> grad_u_elastic(dim, dim);
   grad_u_elastic.copy(delta_grad_u);
   grad_u_elastic -= delta_inelastic_strain;
   Matrix<Real> sigma_elastic(dim, dim);
   MaterialElastic<dim>::computeStressOnQuad(grad_u_elastic, sigma_elastic);
   sigma.copy(previous_sigma);
   sigma += sigma_elastic;
   inelastic_strain.copy(previous_inelastic_strain);
   inelastic_strain += delta_inelastic_strain;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 inline void MaterialPlastic<dim>::computeStressAndInelasticStrainOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
     Matrix<Real> & sigma, const Matrix<Real> & previous_sigma,
     Matrix<Real> & inelastic_strain,
     const Matrix<Real> & previous_inelastic_strain,
     const Matrix<Real> & delta_inelastic_strain) const {
   Matrix<Real> delta_grad_u(grad_u);
   delta_grad_u -= previous_grad_u;
 
   computeStressAndInelasticStrainOnQuad(
       delta_grad_u, sigma, previous_sigma, inelastic_strain,
       previous_inelastic_strain, delta_inelastic_strain);
 }
 
 } // namespace akantu
 
 #endif /* MATERIAL_PLASTIC_INLINE_IMPL_H */
diff --git a/src/model/solid_mechanics/materials/material_thermal.cc b/src/model/solid_mechanics/materials/material_thermal.cc
index 4de1e3844..685bca36c 100644
--- a/src/model/solid_mechanics/materials/material_thermal.cc
+++ b/src/model/solid_mechanics/materials/material_thermal.cc
@@ -1,97 +1,97 @@
 /**
  * @file   material_thermal.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Specialization of the material class for the thermal material
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_thermal.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
-MaterialThermal<dim>::MaterialThermal(SolidMechanicsModel & model,
-                                      const ID & id)
+template <Int spatial_dimension>
+MaterialThermal<spatial_dimension>::MaterialThermal(SolidMechanicsModel & model,
+                                                    const ID & id)
     : Material(model, id), delta_T("delta_T", *this),
       sigma_th("sigma_th", *this), use_previous_stress_thermal(false) {
   this->initialize();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialThermal<dim>::MaterialThermal(SolidMechanicsModel & model,
-                                      UInt spatial_dimension, const Mesh & mesh,
+                                      Int spatial_dimension, const Mesh & mesh,
                                       FEEngine & fe_engine, const ID & id)
     : Material(model, spatial_dimension, mesh, fe_engine, id),
       delta_T("delta_T", *this, dim, fe_engine, this->element_filter),
       sigma_th("sigma_th", *this, dim, fe_engine, this->element_filter),
       use_previous_stress_thermal(false) {
   this->initialize();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialThermal<dim>::initialize() {
+template <Int dim> void MaterialThermal<dim>::initialize() {
   this->registerParam("E", E, Real(0.), _pat_parsable | _pat_modifiable,
                       "Young's modulus");
   this->registerParam("nu", nu, Real(0.5), _pat_parsable | _pat_modifiable,
                       "Poisson's ratio");
   this->registerParam("alpha", alpha, Real(0.), _pat_parsable | _pat_modifiable,
                       "Thermal expansion coefficient");
   this->registerParam("delta_T", delta_T, _pat_parsable | _pat_modifiable,
                       "Uniform temperature field");
 
   delta_T.initialize(1);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialThermal<dim>::initMaterial() {
+template <Int dim> void MaterialThermal<dim>::initMaterial() {
   sigma_th.initialize(1);
 
   if (use_previous_stress_thermal) {
     sigma_th.initializeHistory();
   }
 
   Material::initMaterial();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialThermal<dim>::computeStress(ElementType el_type,
                                          GhostType ghost_type) {
   for (auto && tuple : zip(this->delta_T(el_type, ghost_type),
                            this->sigma_th(el_type, ghost_type))) {
     computeStressOnQuad(std::get<1>(tuple), std::get<0>(tuple));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 INSTANTIATE_MATERIAL_ONLY(MaterialThermal);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_thermal.hh b/src/model/solid_mechanics/materials/material_thermal.hh
index f6a303e42..20db635e2 100644
--- a/src/model/solid_mechanics/materials/material_thermal.hh
+++ b/src/model/solid_mechanics/materials/material_thermal.hh
@@ -1,110 +1,110 @@
 /**
  * @file   material_thermal.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Material isotropic thermo-elastic
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 {
+template <Int spatial_dimension> class MaterialThermal : public Material {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialThermal(SolidMechanicsModel & model, const ID & id = "");
   MaterialThermal(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
                   FEEngine & fe_engine, const ID & id = "");
 
   ~MaterialThermal() override = default;
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type, GhostType ghost_type) override;
 
   /// local computation of thermal stress
   inline void computeStressOnQuad(Real & sigma, const Real & deltaT);
 
   /* ------------------------------------------------------------------------ */
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Young modulus
   Real E;
 
   /// Poisson ratio
   Real nu;
 
   /// Thermal expansion coefficient
   /// TODO : implement alpha as a matrix
   Real alpha;
 
   /// Temperature field
   InternalField<Real> delta_T;
 
   /// Current thermal stress
   InternalField<Real> sigma_th;
 
   /// Tell if we need to use the previous thermal stress
   bool use_previous_stress_thermal;
 };
 
 /* ------------------------------------------------------------------------ */
 /* Inline impl                                                              */
 /* ------------------------------------------------------------------------ */
-template <UInt dim>
+template <Int dim>
 inline void MaterialThermal<dim>::computeStressOnQuad(Real & sigma,
                                                       const Real & deltaT) {
   sigma = -this->E / (1. - 2. * this->nu) * this->alpha * deltaT;
 }
 
 template <>
 inline void MaterialThermal<1>::computeStressOnQuad(Real & sigma,
                                                     const Real & deltaT) {
   sigma = -this->E * this->alpha * deltaT;
 }
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_THERMAL_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
index 2e2284c1d..c51325c3e 100644
--- a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
+++ b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
@@ -1,318 +1,318 @@
 /**
  * @file   material_standard_linear_solid_deviatoric.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
  *
  * @date creation: Wed May 04 2011
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Material Visco-elastic
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_standard_linear_solid_deviatoric.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialStandardLinearSolidDeviatoric<
     dim>::MaterialStandardLinearSolidDeviatoric(SolidMechanicsModel & model,
                                                 const ID & id)
     : MaterialElastic<dim>(model, id), stress_dev("stress_dev", *this),
       history_integral("history_integral", *this),
       dissipated_energy("dissipated_energy", *this) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam("Eta", eta, Real(1.), _pat_parsable | _pat_modifiable,
                       "Viscosity");
   this->registerParam("Ev", Ev, Real(1.), _pat_parsable | _pat_modifiable,
                       "Stiffness of the viscous element");
   this->registerParam("Einf", E_inf, Real(1.), _pat_readable,
                       "Stiffness of the elastic element");
 
   UInt stress_size = dim * dim;
 
   this->stress_dev.initialize(stress_size);
   this->history_integral.initialize(stress_size);
   this->dissipated_energy.initialize(1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialStandardLinearSolidDeviatoric<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   updateInternalParameters();
   MaterialElastic<dim>::initMaterial();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialStandardLinearSolidDeviatoric<dim>::updateInternalParameters() {
   MaterialElastic<dim>::updateInternalParameters();
   E_inf = this->E - this->Ev;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialStandardLinearSolidDeviatoric<dim>::setToSteadyState(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
   Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
 
   Array<Real>::matrix_iterator stress_d = stress_dev_vect.begin(dim, dim);
   Array<Real>::matrix_iterator history_int = history_int_vect.begin(dim, dim);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & dev_s = *stress_d;
   Matrix<Real> & h = *history_int;
 
   /// Compute the first invariant of strain
   Real Theta = grad_u.trace();
 
   for (UInt i = 0; i < dim; ++i) {
     for (UInt j = 0; j < dim; ++j) {
       dev_s(i, j) = 2 * this->mu *
                     (.5 * (grad_u(i, j) + grad_u(j, i)) -
                      1. / 3. * Theta * Math::kronecker(i, j));
       h(i, j) = 0.;
     }
   }
 
   /// Save the deviator of stress
   ++stress_d;
   ++history_int;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialStandardLinearSolidDeviatoric<dim>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real tau = 0.;
   // if(std::abs(Ev) > std::numeric_limits<Real>::epsilon())
   tau = eta / Ev;
 
   Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
   Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
 
   Array<Real>::matrix_iterator stress_d = stress_dev_vect.begin(dim, dim);
   Array<Real>::matrix_iterator history_int = history_int_vect.begin(dim, dim);
 
   Matrix<Real> s(dim, dim);
 
   Real dt = this->model.getTimeStep();
   Real exp_dt_tau = exp(-dt / tau);
   Real exp_dt_tau_2 = exp(-.5 * dt / tau);
 
   Matrix<Real> epsilon_v(dim, dim);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & dev_s = *stress_d;
   Matrix<Real> & h = *history_int;
 
   s.zero();
   sigma.zero();
 
   /// Compute the first invariant of strain
   Real gamma_inf = E_inf / this->E;
   Real gamma_v = Ev / this->E;
 
   auto epsilon_d = this->template gradUToEpsilon<dim>(grad_u);
   Real Theta = epsilon_d.trace();
   epsilon_v.eye(Theta / Real(3.));
   epsilon_d -= epsilon_v;
 
   Matrix<Real> U_rond_prim(dim, dim);
 
   U_rond_prim.eye(gamma_inf * this->kpa * Theta);
 
   for (UInt i = 0; i < dim; ++i) {
     for (UInt j = 0; j < dim; ++j) {
       s(i, j) = 2 * this->mu * epsilon_d(i, j);
       h(i, j) = exp_dt_tau * h(i, j) + exp_dt_tau_2 * (s(i, j) - dev_s(i, j));
       dev_s(i, j) = s(i, j);
       sigma(i, j) = U_rond_prim(i, j) + gamma_inf * s(i, j) + gamma_v * h(i, j);
     }
   }
 
   /// Save the deviator of stress
   ++stress_d;
   ++history_int;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   this->updateDissipatedEnergy(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialStandardLinearSolidDeviatoric<dim>::updateDissipatedEnergy(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   // if(ghost_type == _ghost) return 0.;
 
   Real tau = 0.;
   tau = eta / Ev;
   Real * dis_energy = dissipated_energy(el_type, ghost_type).data();
 
   Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
   Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
 
   Array<Real>::matrix_iterator stress_d = stress_dev_vect.begin(dim, dim);
   Array<Real>::matrix_iterator history_int = history_int_vect.begin(dim, dim);
 
   Matrix<Real> q(dim, dim);
   Matrix<Real> q_rate(dim, dim);
   Matrix<Real> epsilon_d(dim, dim);
   Matrix<Real> epsilon_v(dim, dim);
 
   Real dt = this->model.getTimeStep();
 
   Real gamma_v = Ev / this->E;
   Real alpha = 1. / (2. * this->mu * gamma_v);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & dev_s = *stress_d;
   Matrix<Real> & h = *history_int;
 
   /// Compute the first invariant of strain
   this->template gradUToEpsilon<dim>(grad_u, epsilon_d);
 
   Real Theta = epsilon_d.trace();
   epsilon_v.eye(Theta / Real(3.));
   epsilon_d -= epsilon_v;
 
   q.copy(dev_s);
   q -= h;
   q *= gamma_v;
 
   q_rate.copy(dev_s);
   q_rate *= gamma_v;
   q_rate -= q;
   q_rate /= tau;
 
   for (UInt i = 0; i < dim; ++i) {
     for (UInt j = 0; j < dim; ++j) {
       *dis_energy += (epsilon_d(i, j) - alpha * q(i, j)) * q_rate(i, j) * dt;
     }
   }
 
   /// Save the deviator of stress
   ++stress_d;
   ++history_int;
   ++dis_energy;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 Real MaterialStandardLinearSolidDeviatoric<dim>::getDissipatedEnergy() const {
   AKANTU_DEBUG_IN();
 
   Real de = 0.;
 
   /// integrate the dissipated energy for each type of elements
   for (auto & type : this->element_filter.elementTypes(dim, _not_ghost)) {
     de +=
         this->fem.integrate(dissipated_energy(type, _not_ghost), type,
                             _not_ghost, this->element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return de;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 Real MaterialStandardLinearSolidDeviatoric<dim>::getDissipatedEnergy(
     ElementType type, UInt index) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
   auto it =
       this->dissipated_energy(type, _not_ghost).begin(nb_quadrature_points);
   UInt gindex = (this->element_filter(type, _not_ghost))(index);
 
   AKANTU_DEBUG_OUT();
   return this->fem.integrate(it[index], type, gindex);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 Real MaterialStandardLinearSolidDeviatoric<dim>::getEnergy(
     const std::string & type) {
   if (type == "dissipated") {
     return getDissipatedEnergy();
   }
   if (type == "dissipated_sls_deviatoric") {
     return getDissipatedEnergy();
   }
   return MaterialElastic<dim>::getEnergy(type);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 Real MaterialStandardLinearSolidDeviatoric<dim>::getEnergy(
     const std::string & energy_id, ElementType type, UInt index) {
   if (energy_id == "dissipated") {
     return getDissipatedEnergy(type, index);
   }
   if (energy_id == "dissipated_sls_deviatoric") {
     return getDissipatedEnergy(type, index);
   }
   return MaterialElastic<dim>::getEnergy(energy_id, type, index);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(sls_deviatoric, MaterialStandardLinearSolidDeviatoric);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
index 2a6df1f97..2e7e15e51 100644
--- a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
+++ b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
@@ -1,138 +1,138 @@
 /**
  * @file   material_standard_linear_solid_deviatoric.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Material Visco-elastic, based on Standard Solid rheological model,
  * see
  * [] J.C.  Simo, T.J.R. Hughes, "Computational  Inelasticity", Springer (1998),
  * see Sections 10.2 and 10.3
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_STANDARD_LINEAR_SOLID_DEVIATORIC_HH_
 #define AKANTU_MATERIAL_STANDARD_LINEAR_SOLID_DEVIATORIC_HH_
 
 namespace akantu {
 
 /**
  * Material standard linear solid deviatoric
  *
  *
  * @verbatim
 
              E_\inf
       ------|\/\/\|------
       |                 |
    ---|                 |---
       |                 |
       ----|\/\/\|--[|----
             E_v   \eta
 
  @endverbatim
  *
  * keyword : sls_deviatoric
  *
  * parameters in the material files :
  *   - E   : Initial Young's modulus @f$ E = E_i + E_v @f$
  *   - eta : viscosity
  *   - Ev  : stiffness of the viscous element
  */
 
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialStandardLinearSolidDeviatoric
     : public MaterialElastic<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialStandardLinearSolidDeviatoric(SolidMechanicsModel & model,
                                         const ID & id = "");
   ~MaterialStandardLinearSolidDeviatoric() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
   void initMaterial() override;
 
   /// update the internal parameters (for modifiable parameters)
   void updateInternalParameters() override;
 
   /// set material to steady state
   void setToSteadyState(ElementType el_type,
                         GhostType ghost_type = _not_ghost) override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
 protected:
   /// update the dissipated energy, is called after the stress have been
   /// computed
   void updateDissipatedEnergy(ElementType el_type, GhostType ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// give the dissipated energy for the time step
   Real getDissipatedEnergy() const;
   Real getDissipatedEnergy(ElementType type, UInt index) const;
 
   /// get the energy using an energy type string for the time step
   Real getEnergy(const std::string & type) override;
   Real getEnergy(const std::string & energy_id, ElementType type,
                  UInt index) override;
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// viscosity, viscous elastic modulus
   Real eta, Ev, E_inf;
 
   Vector<Real> etas;
 
   /// history of deviatoric stress
   InternalField<Real> stress_dev;
 
   /// Internal variable: history integral
   InternalField<Real> history_integral;
 
   /// Dissipated energy
   InternalField<Real> dissipated_energy;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_STANDARD_LINEAR_SOLID_DEVIATORIC_HH_ */
diff --git a/src/model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.cc b/src/model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.cc
index f0aac9836..610a68a73 100644
--- a/src/model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.cc
+++ b/src/model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.cc
@@ -1,736 +1,735 @@
 /**
  * @file   material_viscoelastic_maxwell.cc
  *
  * @author Emil Gallyamov <emil.gallyamov@epfl.ch>
  *
  * @date creation: Mon Jun 04 2018
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Material Visco-elastic, based on Maxwell chain,
  * see
  * [] R. de Borst and A.H. van den Boogaard "Finite-element modeling of
  * deformation and cracking in early-age concrete", J.Eng.Mech., 1994
  * as well as
  * [] Manual of DIANA FEA Theory manual v.10.2 Section 37.6
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_viscoelastic_maxwell.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialViscoelasticMaxwell<spatial_dimension>::MaterialViscoelasticMaxwell(
     SolidMechanicsModel & model, const ID & id)
     : MaterialElastic<spatial_dimension>(model, id),
       C(voigt_h::size, voigt_h::size), D(voigt_h::size, voigt_h::size),
       sigma_v("sigma_v", *this), epsilon_v("epsilon_v", *this),
       dissipated_energy("dissipated_energy", *this),
       mechanical_work("mechanical_work", *this) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam("Einf", Einf, Real(1.), _pat_parsable | _pat_modifiable,
                       "Stiffness of the elastic element");
   this->registerParam("previous_dt", previous_dt, Real(0.), _pat_readable,
                       "Time step of previous solveStep");
   this->registerParam("Eta", Eta, _pat_parsable | _pat_modifiable,
                       "Viscosity of a Maxwell element");
   this->registerParam("Ev", Ev, _pat_parsable | _pat_modifiable,
                       "Stiffness of a Maxwell element");
   this->update_variable_flag = true;
   this->use_previous_stress = true;
   this->use_previous_gradu = true;
   this->use_previous_stress_thermal = true;
 
   this->dissipated_energy.initialize(1);
   this->mechanical_work.initialize(1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   this->E = Einf + Ev.norm<L_1>();
   //  this->E = std::min(this->Einf, this->Ev(0));
   MaterialElastic<spatial_dimension>::initMaterial();
   AKANTU_DEBUG_ASSERT(this->Eta.size() == this->Ev.size(),
                       "Eta and Ev have different dimensions! Please correct.");
   AKANTU_DEBUG_ASSERT(
       !this->finite_deformation,
       "Current material works only in infinitesimal deformations.");
 
   UInt stress_size = spatial_dimension * spatial_dimension;
   this->sigma_v.initialize(stress_size * this->Ev.size());
   this->epsilon_v.initialize(stress_size * this->Ev.size());
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<
     spatial_dimension>::updateInternalParameters() {
   MaterialElastic<spatial_dimension>::updateInternalParameters();
 
   Real pre_mult = 1 / (1 + this->nu) / (1 - 2 * this->nu);
   UInt n = voigt_h::size;
   Real Miiii = pre_mult * (1 - this->nu);
   Real Miijj = pre_mult * this->nu;
   Real Mijij = pre_mult * 0.5 * (1 - 2 * this->nu);
 
   Real Diiii = 1;
   Real Diijj = -this->nu;
   Real Dijij = (2 + 2 * this->nu);
 
   if (spatial_dimension == 1) {
     C(0, 0) = 1;
     D(0, 0) = 1;
   } else {
     C(0, 0) = Miiii;
     D(0, 0) = Diiii;
   }
   if (spatial_dimension >= 2) {
     C(1, 1) = Miiii;
     C(0, 1) = Miijj;
     C(1, 0) = Miijj;
     C(n - 1, n - 1) = Mijij;
 
     D(1, 1) = Diiii;
     D(0, 1) = Diijj;
     D(1, 0) = Diijj;
     D(n - 1, n - 1) = Dijij;
   }
 
   if (spatial_dimension == 3) {
     C(2, 2) = Miiii;
     C(0, 2) = Miijj;
     C(1, 2) = Miijj;
     C(2, 0) = Miijj;
     C(2, 1) = Miijj;
     C(3, 3) = Mijij;
     C(4, 4) = Mijij;
 
     D(2, 2) = Diiii;
     D(0, 2) = Diijj;
     D(1, 2) = Diijj;
     D(2, 0) = Diijj;
     D(2, 1) = Diijj;
     D(3, 3) = Dijij;
     D(4, 4) = Dijij;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <> void MaterialViscoelasticMaxwell<2>::updateInternalParameters() {
   MaterialElastic<2>::updateInternalParameters();
 
   Real pre_mult = 1 / (1 + this->nu) / (1 - 2 * this->nu);
   UInt n = voigt_h::size;
   Real Miiii = pre_mult * (1 - this->nu);
   Real Miijj = pre_mult * this->nu;
   Real Mijij = pre_mult * 0.5 * (1 - 2 * this->nu);
 
   Real Diiii = 1;
   Real Diijj = -this->nu;
   Real Dijij = (2 + 2 * this->nu);
 
   C(0, 0) = Miiii;
   C(1, 1) = Miiii;
   C(0, 1) = Miijj;
   C(1, 0) = Miijj;
   C(n - 1, n - 1) = Mijij;
 
   D(0, 0) = Diiii;
   D(1, 1) = Diiii;
   D(0, 1) = Diijj;
   D(1, 0) = Diijj;
   D(n - 1, n - 1) = Dijij;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   // NOLINTNEXTLINE(bugprone-parent-virtual-call)
   MaterialThermal<spatial_dimension>::computeStress(el_type, ghost_type);
 
   auto sigma_th_it = this->sigma_th(el_type, ghost_type).begin();
 
   auto previous_gradu_it = this->gradu.previous(el_type, ghost_type)
                                .begin(spatial_dimension, spatial_dimension);
 
   auto previous_stress_it = this->stress.previous(el_type, ghost_type)
                                 .begin(spatial_dimension, spatial_dimension);
 
   auto sigma_v_it =
       this->sigma_v(el_type, ghost_type)
           .begin(spatial_dimension, spatial_dimension, this->Eta.size());
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   computeStressOnQuad(grad_u, *previous_gradu_it, sigma, *sigma_v_it,
                       *sigma_th_it);
   ++sigma_th_it;
   ++previous_gradu_it;
   ++sigma_v_it;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::computeStressOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
     Matrix<Real> & sigma, Tensor3<Real> & sigma_v, const Real & sigma_th) {
 
   // Wikipedia convention:
   // 2*eps_ij (i!=j) = voigt_eps_I
   // http://en.wikipedia.org/wiki/Voigt_notation
   Vector<Real> voigt_current_strain(voigt_h::size);
   Vector<Real> voigt_previous_strain(voigt_h::size);
   Vector<Real> voigt_stress(voigt_h::size);
   Vector<Real> voigt_sigma_v(voigt_h::size);
 
   for (UInt I = 0; I < voigt_h::size; ++I) {
     Real voigt_factor = voigt_h::factors[I];
     UInt i = voigt_h::vec[I][0];
     UInt j = voigt_h::vec[I][1];
 
     voigt_current_strain(I) = voigt_factor * (grad_u(i, j) + grad_u(j, i)) / 2.;
     voigt_previous_strain(I) =
         voigt_factor * (previous_grad_u(i, j) + previous_grad_u(j, i)) / 2.;
   }
 
   voigt_stress = this->Einf * this->C * voigt_current_strain;
   Real dt = this->model.getTimeStep();
 
   for (UInt k = 0; k < Eta.size(); ++k) {
     Real lambda = this->Eta(k) / this->Ev(k);
     Real exp_dt_lambda = exp(-dt / lambda);
     Real E_additional;
 
     if (exp_dt_lambda == 1) {
       E_additional = this->Ev(k);
     } else {
       E_additional = (1 - exp_dt_lambda) * this->Ev(k) * lambda / dt;
     }
 
     for (UInt I = 0; I < voigt_h::size; ++I) {
       UInt i = voigt_h::vec[I][0];
       UInt j = voigt_h::vec[I][1];
 
       voigt_sigma_v(I) = sigma_v(i, j, k);
     }
 
     voigt_stress += E_additional * this->C *
                         (voigt_current_strain - voigt_previous_strain) +
                     exp_dt_lambda * voigt_sigma_v;
   }
 
   for (UInt I = 0; I < voigt_h::size; ++I) {
     UInt i = voigt_h::vec[I][0];
     UInt j = voigt_h::vec[I][1];
 
     sigma(i, j) = sigma(j, i) =
         voigt_stress(I) + Math::kronecker(i, j) * sigma_th;
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::computePotentialEnergy(
     ElementType el_type) {
   AKANTU_DEBUG_IN();
 
   auto epot = this->potential_energy(el_type).begin();
   auto sigma_v_it = this->sigma_v(el_type).begin(
       spatial_dimension, spatial_dimension, this->Eta.size());
   auto epsilon_v_it = this->epsilon_v(el_type).begin(
       spatial_dimension, spatial_dimension, this->Eta.size());
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
 
   this->computePotentialEnergyOnQuad(grad_u, *epot, *sigma_v_it, *epsilon_v_it);
   ++epot;
   ++sigma_v_it;
   ++epsilon_v_it;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::
     computePotentialEnergyOnQuad(const Matrix<Real> & grad_u, Real & epot,
                                  Tensor3<Real> & sigma_v,
                                  Tensor3<Real> & epsilon_v) {
 
   Vector<Real> voigt_strain(voigt_h::size);
   Vector<Real> voigt_stress(voigt_h::size);
   Vector<Real> voigt_sigma_v(voigt_h::size);
 
   for (UInt I = 0; I < voigt_h::size; ++I) {
     Real voigt_factor = voigt_h::factors[I];
     UInt i = voigt_h::vec[I][0];
     UInt j = voigt_h::vec[I][1];
 
     voigt_strain(I) = voigt_factor * (grad_u(i, j) + grad_u(j, i)) / 2.;
   }
 
   voigt_stress = this->Einf * this->C * voigt_strain;
   epot = 0.5 * voigt_stress.dot(voigt_strain);
 
   for (UInt k = 0; k < this->Eta.size(); ++k) {
     Matrix<Real> stress_v = sigma_v(k);
     Matrix<Real> strain_v = epsilon_v(k);
     epot += 0.5 * stress_v.doubleDot(strain_v);
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
-void MaterialViscoelasticMaxwell<spatial_dimension>::afterSolveStep(
-    bool converged) {
+template <Int spatial_dimension>
+void MaterialViscoelasticMaxwell<spatial_dimension>::afterSolveStep(bool converged) {
 
   Material::afterSolveStep(converged);
 
   if (not converged) {
     return;
   }
 
   for (auto & el_type : this->element_filter.elementTypes(
            _all_dimensions, _not_ghost, _ek_not_defined)) {
     if (this->update_variable_flag) {
       auto previous_gradu_it = this->gradu.previous(el_type, _not_ghost)
                                    .begin(spatial_dimension, spatial_dimension);
 
       auto sigma_v_it =
           this->sigma_v(el_type, _not_ghost)
               .begin(spatial_dimension, spatial_dimension, this->Eta.size());
 
       auto epsilon_v_it =
           this->epsilon_v(el_type, _not_ghost)
               .begin(spatial_dimension, spatial_dimension, this->Eta.size());
 
       MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
 
       updateIntVarOnQuad(grad_u, *previous_gradu_it, *sigma_v_it,
                          *epsilon_v_it);
 
       ++previous_gradu_it;
       ++sigma_v_it;
       ++epsilon_v_it;
 
       MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
     }
     this->updateDissipatedEnergy(el_type);
   }
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::updateIntVarOnQuad(
     const Matrix<Real> & grad_u, const Matrix<Real> & previous_grad_u,
     Tensor3<Real> & sigma_v, Tensor3<Real> & epsilon_v) {
 
   Matrix<Real> grad_delta_u(grad_u);
   grad_delta_u -= previous_grad_u;
 
   Real dt = this->model.getTimeStep();
   Vector<Real> voigt_delta_strain(voigt_h::size);
   for (UInt I = 0; I < voigt_h::size; ++I) {
     Real voigt_factor = voigt_h::factors[I];
     UInt i = voigt_h::vec[I][0];
     UInt j = voigt_h::vec[I][1];
 
     voigt_delta_strain(I) =
         voigt_factor * (grad_delta_u(i, j) + grad_delta_u(j, i)) / 2.;
   }
 
   for (UInt k = 0; k < this->Eta.size(); ++k) {
     Real lambda = this->Eta(k) / this->Ev(k);
     Real exp_dt_lambda = exp(-dt / lambda);
     Real E_ef_v;
 
     if (exp_dt_lambda == 1) {
       E_ef_v = this->Ev(k);
     } else {
       E_ef_v = (1 - exp_dt_lambda) * this->Ev(k) * lambda / dt;
     }
 
     Vector<Real> voigt_sigma_v(voigt_h::size);
     Vector<Real> voigt_epsilon_v(voigt_h::size);
 
     for (UInt I = 0; I < voigt_h::size; ++I) {
       UInt i = voigt_h::vec[I][0];
       UInt j = voigt_h::vec[I][1];
 
       voigt_sigma_v(I) = sigma_v(i, j, k);
     }
 
     voigt_sigma_v =
         exp_dt_lambda * voigt_sigma_v + E_ef_v * this->C * voigt_delta_strain;
     voigt_epsilon_v = 1 / Ev(k) * this->D * voigt_sigma_v;
 
     for (UInt I = 0; I < voigt_h::size; ++I) {
       UInt i = voigt_h::vec[I][0];
       UInt j = voigt_h::vec[I][1];
 
       sigma_v(i, j, k) = sigma_v(j, i, k) = voigt_sigma_v(I);
       epsilon_v(i, j, k) = epsilon_v(j, i, k) = voigt_epsilon_v(I);
     }
   }
 }
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::computeTangentModuli(
     ElementType el_type, Array<Real> & tangent_matrix, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real dt = this->model.getTimeStep();
   Real E_ef = this->Einf;
 
   for (UInt k = 0; k < Eta.size(); ++k) {
     Real lambda = this->Eta(k) / this->Ev(k);
     Real exp_dt_lambda = exp(-dt / lambda);
     if (exp_dt_lambda == 1) {
       E_ef += this->Ev(k);
     } else {
       E_ef += (1 - exp_dt_lambda) * this->Ev(k) * lambda / dt;
     }
   }
 
   this->previous_dt = dt;
 
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_matrix);
   this->computeTangentModuliOnQuad(tangent);
   MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END;
 
   tangent_matrix *= E_ef;
 
   this->was_stiffness_assembled = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::computeTangentModuliOnQuad(
     Matrix<Real> & tangent) {
 
   tangent.copy(C);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::savePreviousState() {
 
   for (auto & el_type : this->element_filter.elementTypes(
            _all_dimensions, _not_ghost, _ek_not_defined)) {
 
     auto sigma_th_it = this->sigma_th(el_type, _not_ghost).begin();
 
     auto previous_sigma_th_it =
         this->sigma_th.previous(el_type, _not_ghost).begin();
 
     auto previous_gradu_it = this->gradu.previous(el_type, _not_ghost)
                                  .begin(spatial_dimension, spatial_dimension);
 
     auto previous_sigma_it = this->stress.previous(el_type, _not_ghost)
                                  .begin(spatial_dimension, spatial_dimension);
 
     auto sigma_v_it =
         this->sigma_v(el_type, _not_ghost)
             .begin(spatial_dimension, spatial_dimension, this->Eta.size());
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
     auto & previous_grad_u = *previous_gradu_it;
     auto & previous_sigma = *previous_sigma_it;
 
     previous_grad_u.copy(grad_u);
     previous_sigma.copy(sigma);
     *previous_sigma_th_it = *sigma_th_it;
 
     ++previous_gradu_it, ++previous_sigma_it, ++previous_sigma_th_it,
         ++sigma_v_it, ++sigma_th_it;
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::updateIntVariables() {
 
   for (auto & el_type : this->element_filter.elementTypes(
            _all_dimensions, _not_ghost, _ek_not_defined)) {
 
     auto previous_gradu_it = this->gradu.previous(el_type, _not_ghost)
                                  .begin(spatial_dimension, spatial_dimension);
     auto previous_sigma_it = this->stress.previous(el_type, _not_ghost)
                                  .begin(spatial_dimension, spatial_dimension);
 
     auto sigma_v_it =
         this->sigma_v(el_type, _not_ghost)
             .begin(spatial_dimension, spatial_dimension, this->Eta.size());
 
     auto epsilon_v_it =
         this->epsilon_v(el_type, _not_ghost)
             .begin(spatial_dimension, spatial_dimension, this->Eta.size());
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
 
     updateIntVarOnQuad(grad_u, *previous_gradu_it, *sigma_v_it, *epsilon_v_it);
 
     ++previous_gradu_it;
     ++sigma_v_it;
     ++epsilon_v_it;
 
     MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::updateDissipatedEnergy(
     ElementType el_type) {
   AKANTU_DEBUG_IN();
 
   this->computePotentialEnergy(el_type);
 
   auto epot = this->potential_energy(el_type).begin();
   auto dis_energy = this->dissipated_energy(el_type).begin();
   auto mech_work = this->mechanical_work(el_type).begin();
   auto sigma_v_it = this->sigma_v(el_type).begin(
       spatial_dimension, spatial_dimension, this->Eta.size());
   auto epsilon_v_it = this->epsilon_v(el_type).begin(
       spatial_dimension, spatial_dimension, this->Eta.size());
   auto previous_gradu_it =
       this->gradu.previous(el_type).begin(spatial_dimension, spatial_dimension);
   auto previous_sigma_it = this->stress.previous(el_type).begin(
       spatial_dimension, spatial_dimension);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, _not_ghost);
 
   updateDissipatedEnergyOnQuad(grad_u, *previous_gradu_it, sigma,
                                *previous_sigma_it, *dis_energy, *mech_work,
                                *epot);
   ++previous_gradu_it;
   ++previous_sigma_it;
   ++dis_energy;
   ++mech_work;
   ++epot;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::
     updateDissipatedEnergyOnQuad(const Matrix<Real> & grad_u,
                                  const Matrix<Real> & previous_grad_u,
                                  const Matrix<Real> & sigma,
                                  const Matrix<Real> & previous_sigma,
                                  Real & dis_energy, Real & mech_work,
                                  const Real & pot_energy) {
 
   Real dt = this->model.getTimeStep();
 
   Matrix<Real> strain_rate = grad_u;
   strain_rate -= previous_grad_u;
   strain_rate /= dt;
 
   Matrix<Real> av_stress = sigma;
   av_stress += previous_sigma;
   av_stress /= 2;
 
   mech_work += av_stress.doubleDot(strain_rate) * dt;
 
   dis_energy = mech_work - pot_energy;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialViscoelasticMaxwell<spatial_dimension>::getDissipatedEnergy()
     const {
   AKANTU_DEBUG_IN();
 
   Real de = 0.;
 
   /// integrate the dissipated energy for each type of elements
   for (auto & type :
        this->element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     de +=
         this->fem.integrate(this->dissipated_energy(type, _not_ghost), type,
                             _not_ghost, this->element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return de;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialViscoelasticMaxwell<spatial_dimension>::getDissipatedEnergy(
     ElementType type, UInt index) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
   auto it =
       this->dissipated_energy(type, _not_ghost).begin(nb_quadrature_points);
   UInt gindex = (this->element_filter(type, _not_ghost))(index);
 
   AKANTU_DEBUG_OUT();
   return this->fem.integrate(it[index], type, gindex);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialViscoelasticMaxwell<spatial_dimension>::getMechanicalWork() const {
   AKANTU_DEBUG_IN();
 
   Real mw = 0.;
 
   /// integrate the dissipated energy for each type of elements
   for (auto & type :
        this->element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     mw +=
         this->fem.integrate(this->mechanical_work(type, _not_ghost), type,
                             _not_ghost, this->element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return mw;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialViscoelasticMaxwell<spatial_dimension>::getMechanicalWork(
     ElementType type, UInt index) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
   auto it = this->mechanical_work(type, _not_ghost).begin(nb_quadrature_points);
   UInt gindex = (this->element_filter(type, _not_ghost))(index);
 
   AKANTU_DEBUG_OUT();
   return this->fem.integrate(it[index], type, gindex);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialViscoelasticMaxwell<spatial_dimension>::getPotentialEnergy()
     const {
   AKANTU_DEBUG_IN();
 
   Real epot = 0.;
 
   /// integrate the dissipated energy for each type of elements
   for (auto & type :
        this->element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     epot +=
         this->fem.integrate(this->potential_energy(type, _not_ghost), type,
                             _not_ghost, this->element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return epot;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialViscoelasticMaxwell<spatial_dimension>::getPotentialEnergy(
     ElementType type, UInt index) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
   auto it =
       this->potential_energy(type, _not_ghost).begin(nb_quadrature_points);
   UInt gindex = (this->element_filter(type, _not_ghost))(index);
 
   AKANTU_DEBUG_OUT();
   return this->fem.integrate(it[index], type, gindex);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialViscoelasticMaxwell<spatial_dimension>::getEnergy(
     const std::string & type) {
   if (type == "dissipated") {
     return getDissipatedEnergy();
   }
   if (type == "potential") {
     return getPotentialEnergy();
   }
   if (type == "work") {
     return getMechanicalWork();
   }
   return MaterialElastic<spatial_dimension>::getEnergy(type);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 Real MaterialViscoelasticMaxwell<spatial_dimension>::getEnergy(
     const std::string & energy_id, ElementType type, UInt index) {
   if (energy_id == "dissipated") {
     return getDissipatedEnergy(type, index);
   }
   if (energy_id == "potential") {
     return getPotentialEnergy(type, index);
   }
   if (energy_id == "work") {
     return getMechanicalWork(type, index);
   }
   return MaterialElastic<spatial_dimension>::getEnergy(energy_id, type, index);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::forceUpdateVariable() {
   update_variable_flag = true;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialViscoelasticMaxwell<spatial_dimension>::forceNotUpdateVariable() {
   update_variable_flag = false;
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(viscoelastic_maxwell, MaterialViscoelasticMaxwell);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.hh b/src/model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.hh
index d8ef5fb17..71801b7e2 100644
--- a/src/model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.hh
+++ b/src/model/solid_mechanics/materials/material_viscoelastic/material_viscoelastic_maxwell.hh
@@ -1,231 +1,231 @@
 /**
  * @file   material_viscoelastic_maxwell.hh
  *
  * @author Emil Gallyamov <emil.gallyamov@epfl.ch>
  *
  * @date creation: Mon Jun 04 2018
  * @date last modification: Wed Dec 09 2020
  *
  * @brief  Material Visco-elastic, based on Maxwell chain,
  * see
  * [] R. de Borst and A.H. van den Boogaard "Finite-element modeling of
  * deformation and cracking in early-age concrete", J.Eng.Mech., 1994
  * as well as
  * [] Manual of DIANA FEA Theory manual v.10.2 Section 37.6
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_voigthelper.hh"
 #include "material_elastic.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_VISCOELASTIC_MAXWELL_HH_
 #define AKANTU_MATERIAL_VISCOELASTIC_MAXWELL_HH_
 
 namespace akantu {
 
 /**
  * Material Viscoelastic based on Maxwell chain
  *
  *
  * @verbatim
 
               E_0
       ------|\/\/\|-------
       |                  |
    ---|                  |---
       |                  |
       ----|\/\/\|--[|-----
       |   E_v1  \Eta_1|
    ---|                  |---
       |                  |
       ----|\/\/\|--[|-----
       |   E_v2 \Eta_2 |
    ---|                  |---
       |                  |
       ----|\/\/\|--[|----
           E_vN \Eta_N
 
  @endverbatim
  *
  * keyword : viscoelastic_maxwell
  *
  * parameters in the material files :
  *   - N   : number of Maxwell elements
  *   - Einf  : one spring element stiffness
  *   - Ev1 : stiffness of the 1st viscous element
  *   - Eta1: viscosity of the 1st Maxwell element
  *   ...
  *   - Ev<N> : stiffness of the Nst viscous element
  *   - Eta<N>: viscosity of the Nst Maxwell element
  */
 
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialViscoelasticMaxwell : public MaterialElastic<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialViscoelasticMaxwell(SolidMechanicsModel & model, const ID & id = "");
   ~MaterialViscoelasticMaxwell() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
   void initMaterial() override;
 
   /// recompute the lame coefficient and effective tangent moduli
   void updateInternalParameters() override;
 
   /// update internal variable on a converged Newton
   void afterSolveStep(bool converged) override;
 
   /// update internal variable based on previous and current strain values
   void updateIntVariables();
 
   /// update the internal variable sigma_v on quadrature point
   void updateIntVarOnQuad(const Matrix<Real> & grad_u,
                           const Matrix<Real> & previous_grad_u,
                           Tensor3<Real> & sigma_v, Tensor3<Real> & epsilon_v);
 
   /// 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(ElementType el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
   /// save previous stress and strain values into "previous" arrays
   void savePreviousState() override;
 
   /// change flag of updateIntVar to true
   void forceUpdateVariable();
 
   /// change flag of updateIntVar to false
   void forceNotUpdateVariable();
 
   /// compute the elastic potential energy
   void computePotentialEnergy(ElementType el_type) override;
 
 protected:
   void computePotentialEnergyOnQuad(const Matrix<Real> & grad_u, Real & epot,
                                     Tensor3<Real> & sigma_v,
                                     Tensor3<Real> & epsilon_v);
 
   /// update the dissipated energy, is called after the stress have been
   /// computed
   void updateDissipatedEnergy(ElementType el_type);
 
   void updateDissipatedEnergyOnQuad(const Matrix<Real> & grad_u,
                                     const Matrix<Real> & previous_grad_u,
                                     const Matrix<Real> & sigma,
                                     const Matrix<Real> & previous_sigma,
                                     Real & dis_energy, Real & mech_work,
                                     const Real & pot_energy);
 
   /// compute stresses on a quadrature point
   void computeStressOnQuad(const Matrix<Real> & grad_u,
                            const Matrix<Real> & previous_grad_u,
                            Matrix<Real> & sigma, Tensor3<Real> & sigma_v,
                            const Real & sigma_th);
 
   /// compute tangent moduli on a quadrature point
   void computeTangentModuliOnQuad(Matrix<Real> & tangent);
 
   bool hasStiffnessMatrixChanged() override {
     Real dt = this->model.getTimeStep();
 
     return ((this->previous_dt == dt)
                 ? (!(this->previous_dt == dt)) * (this->was_stiffness_assembled)
                 : (!(this->previous_dt == dt)));
     //  return (!(this->previous_dt == dt));
   }
 
   MatrixType getTangentType() override {
     return _symmetric;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// give the dissipated energy
   Real getDissipatedEnergy() const;
   Real getDissipatedEnergy(ElementType type, UInt index) const;
 
   /// get the potential energy
   Real getPotentialEnergy() const;
   Real getPotentialEnergy(ElementType type, UInt index) const;
 
   /// get the potential energy
   Real getMechanicalWork() const;
   Real getMechanicalWork(ElementType type, UInt index) const;
 
   /// get the energy using an energy type string for the time step
   Real getEnergy(const std::string & type) override;
   Real getEnergy(const std::string & energy_id, ElementType type,
                  UInt index) override;
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   using voigt_h = VoigtHelper<spatial_dimension>;
 
   /// Vectors of viscosity, viscous elastic modulus, one spring element elastic
   /// modulus
   Vector<Real> Eta;
   Vector<Real> Ev;
   Real Einf;
 
   /// time step from previous solveStep
   Real previous_dt;
 
   /// Stiffness matrix template
   Matrix<Real> C;
   /// Compliance matrix template
   Matrix<Real> D;
 
   /// Internal variable: viscous_stress
   InternalField<Real> sigma_v;
 
   /// Internal variable: spring strain in Maxwell element
   InternalField<Real> epsilon_v;
 
   /// Dissipated energy
   InternalField<Real> dissipated_energy;
 
   /// Mechanical work
   InternalField<Real> mechanical_work;
 
   /// Update internal variable after solve step or not
   bool update_variable_flag;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_VISCOELASTIC_MAXWELL_HH_ */
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
index 536ee7095..f8018e9a2 100644
--- a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
+++ b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
@@ -1,125 +1,124 @@
 /**
  * @file   stress_based_weight_function.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Aug 24 2015
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  implementation of the stres based weight function classes
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "stress_based_weight_function.hh"
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 StressBasedWeightFunction::StressBasedWeightFunction(NonLocalManager & manager)
     : BaseWeightFunction(manager, "stress_based")
 // stress_diag("stress_diag", material), selected_stress_diag(NULL),
 // stress_base("stress_base", material), selected_stress_base(NULL),
 // characteristic_size("lc", material),  selected_characteristic_size(NULL)
 {
-
   // this->registerParam("ft", this->ft, 0., _pat_parsable, "Tensile strength");
   // stress_diag.initialize(spatial_dimension);
   // stress_base.initialize(spatial_dimension * spatial_dimension);
   // characteristic_size.initialize(1);
 }
 
 /* -------------------------------------------------------------------------- */
 /// During intialization the characteristic sizes for all quadrature
 /// points are computed
 void StressBasedWeightFunction::init() {
   // const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
   // for (UInt g = _not_ghost; g <= _ghost; ++g) {
   //   GhostType gt = GhostType(g);
   //   Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt);
   //   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt);
   //   for(; it != last_type; ++it) {
   //     UInt nb_quadrature_points =
   // 	this->material.getModel().getFEEngine().getNbQuadraturePoints(*it, gt);
-  //     const Array<UInt> & element_filter =
+  //     const Array<Int> & element_filter =
   //     this->material.getElementFilter(*it, gt);
   //     UInt nb_element = element_filter.size();
 
   //     Array<Real> ones(nb_element*nb_quadrature_points, 1, 1.);
   //     Array<Real> & lc = characteristic_size(*it, gt);
   //     this->material.getModel().getFEEngine().integrateOnQuadraturePoints(ones,
   // 								     lc,
   // 								     1,
   // 								     *it,
   // 								     gt,
   // 								     element_filter);
 
   //     for (UInt q = 0;  q < nb_quadrature_points * nb_element; q++) {
   // 	lc(q) = pow(lc(q), 1./ Real(spatial_dimension));
   //     }
   //   }
   // }
 }
 
 /* -------------------------------------------------------------------------- */
 /// computation of principals stresses and principal directions
 void StressBasedWeightFunction::updatePrincipalStress(__attribute__((unused))
                                                       GhostType ghost_type) {
   //   AKANTU_DEBUG_IN();
 
   //   const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
 
   //   Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
   //   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension,
   //   ghost_type);
   //   for(; it != last_type; ++it) {
   //     Array<Real>::const_matrix_iterator sigma =
   //       this->material.getStress(*it, ghost_type).begin(spatial_dimension,
   //       spatial_dimension);
   //     auto eigenvalues =
   //       stress_diag(*it, ghost_type).begin(spatial_dimension);
   //     auto eigenvalues_end =
   //       stress_diag(*it, ghost_type).end(spatial_dimension);
   //     Array<Real>::matrix_iterator eigenvector =
   //       stress_base(*it, ghost_type).begin(spatial_dimension,
   //       spatial_dimension);
 
   // #ifndef __trick__
   //     auto cl = characteristic_size(*it, ghost_type).begin();
   // #endif
   //     UInt q = 0;
   //     for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues,
   //     ++eigenvector, ++cl, ++q) {
   //       sigma->eig(*eigenvalues, *eigenvector);
   //       *eigenvalues /= ft;
   // #ifndef __trick__
   //       // specify a lower bound for principal stress based on the size of
   //       the element
   //       for (UInt i = 0; i < spatial_dimension; ++i) {
   //         (*eigenvalues)(i) = std::max(*cl / this->R, (*eigenvalues)(i));
   //       }
   // #endif
   //     }
   //   }
   //   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model.hh b/src/model/solid_mechanics/solid_mechanics_model.hh
index 7aa62cbed..d7af3f830 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,594 +1,593 @@
 /**
  * @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: Fri Apr 09 2021
  *
  * @brief  Model of Solid Mechanics
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_callback.hh"
 #include "solid_mechanics_model_event_handler.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SOLID_MECHANICS_MODEL_HH_
 #define AKANTU_SOLID_MECHANICS_MODEL_HH_
 
 namespace akantu {
 class Material;
 class MaterialSelector;
 class DumperIOHelper;
 class NonLocalManager;
 template <ElementKind kind, class IntegrationOrderFunctor>
 class IntegratorGauss;
 template <ElementKind kind> class ShapeLagrange;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class SolidMechanicsModel
     : public Model,
       public DataAccessor<Element>,
-      public DataAccessor<UInt>,
+      public DataAccessor<Idx>,
       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> &);
+    AKANTU_GET_MACRO_NOT_CONST(MaterialList, material, Array<Int> &);
+    AKANTU_GET_MACRO(MaterialList, material, const Array<Int> &);
 
   protected:
-    Array<UInt> material;
+    Array<Int> material;
   };
 
   using MyFEEngineType = FEEngineTemplate<IntegratorGauss, ShapeLagrange>;
 
 protected:
   using EventManager = EventHandlerManager<SolidMechanicsModelEventHandler>;
 
 public:
-  SolidMechanicsModel(Mesh & mesh, UInt dim = _all_dimensions,
+  SolidMechanicsModel(Mesh & mesh, Int dim = _all_dimensions,
                       const ID & id = "solid_mechanics_model",
                       std::shared_ptr<DOFManager> dof_manager = nullptr,
                       ModelType model_type = ModelType::_solid_mechanics_model);
 
   ~SolidMechanicsModel() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// initialize completely the model
   void initFullImpl(
       const ModelOptions & options = SolidMechanicsModelOptions()) override;
 
 public:
   /// initialize all internal arrays for materials
   virtual void initMaterials();
 
 protected:
   /// 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(bool need_to_reassemble = false);
   /// assembles the internal forces in the array internal_forces
   virtual void assembleInternalForces();
 
 protected:
   /// callback for the solver, this adds f_{ext} - f_{int} to the residual
   void assembleResidual() override;
 
   /// callback for the solver, this adds f_{ext} or  f_{int} to the residual
   void assembleResidual(const ID & residual_part) override;
   bool canSplitResidual() override { return true; }
 
   /// get the type of matrix needed
   MatrixType getMatrixType(const ID & matrix_id) override;
 
   /// callback for the solver, this assembles different matrices
   void assembleMatrix(const ID & matrix_id) override;
 
   /// callback for the solver, this assembles the stiffness matrix
   void assembleLumpedMatrix(const ID & matrix_id) override;
 
   /// callback for the solver, this is called at beginning of solve
   void predictor() override;
   /// callback for the solver, this is called at end of solve
   void corrector() override;
 
   /// callback for the solver, this is called at beginning of solve
   void beforeSolveStep() override;
   /// callback for the solver, this is called at end of solve
   void afterSolveStep(bool converged = true) 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,
                                GhostType ghost_type = _not_ghost);
 
 protected:
   /// register a material in the dynamic database
   Material & registerNewMaterial(const ParserSection & mat_section);
 
   /// read the material files to instantiate all the materials
   void instantiateMaterials();
 
   /// set the element_id_by_material and add the elements to the good materials
   virtual void
-  assignMaterialToElements(const ElementTypeMapArray<UInt> * filter = nullptr);
+  assignMaterialToElements(const ElementTypeMapArray<Idx> * 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();
 
 public:
   /// 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);
 
   
 protected:
   /// fill a vector of rho
   void computeRho(Array<Real> & rho, ElementType type, GhostType ghost_type);
 
   /// compute the kinetic energy
   Real getKineticEnergy();
-  Real getKineticEnergy(ElementType type, UInt index);
+  Real getKineticEnergy(const ElementType & type, Idx 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(GhostType ghost_type) override;
 
   void insertIntegrationPointsInNeighborhoods(GhostType ghost_type) override;
 
   /// update the values of the non local internal
   void updateLocalInternal(ElementTypeMapReal & internal_flat,
                            GhostType ghost_type, ElementKind kind) override;
 
   /// copy the results of the averaging in the materials
   void updateNonLocalInternal(ElementTypeMapReal & internal_flat,
                               GhostType ghost_type, ElementKind kind) override;
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
-  UInt getNbData(const Array<Element> & elements,
-                 const SynchronizationTag & tag) const override;
+  Int getNbData(const Array<Element> & elements,
+                const SynchronizationTag & tag) const override;
 
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const SynchronizationTag & tag) const override;
 
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const SynchronizationTag & tag) override;
 
-  UInt getNbData(const Array<UInt> & dofs,
-                 const SynchronizationTag & tag) const override;
+  Int getNbData(const Array<Idx> & dofs,
+                const SynchronizationTag & tag) const override;
 
-  void packData(CommunicationBuffer & buffer, const Array<UInt> & dofs,
+  void packData(CommunicationBuffer & buffer, const Array<Idx> & dofs,
                 const SynchronizationTag & tag) const override;
 
-  void unpackData(CommunicationBuffer & buffer, const Array<UInt> & dofs,
+  void unpackData(CommunicationBuffer & buffer, const Array<Idx> & 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,
+  void onNodesAdded(const Array<Idx> & nodes_list,
                     const NewNodesEvent & event) override;
-  void onNodesRemoved(const Array<UInt> & element_list,
-                      const Array<UInt> & new_numbering,
+  void onNodesRemoved(const Array<Idx> & element_list,
+                      const Array<Idx> & new_numbering,
                       const RemovedNodesEvent & event) override;
   void onElementsAdded(const Array<Element> & element_list,
                        const NewElementsEvent & event) override;
   void onElementsRemoved(const Array<Element> & element_list,
-                         const ElementTypeMapArray<UInt> & new_numbering,
+                         const ElementTypeMapArray<Idx> & new_numbering,
                          const RemovedElementsEvent & event) override;
-  void onElementsChanged(const Array<Element> & /*unused*/,
-                         const Array<Element> & /*unused*/,
-                         const ElementTypeMapArray<UInt> & /*unused*/,
-                         const ChangedElementsEvent & /*unused*/) override{};
+  void onElementsChanged(const Array<Element> &, const Array<Element> &,
+                         const ElementTypeMapArray<Idx> &,
+                         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, ElementKind element_kind);
   //! give the amount of data per element
-  virtual ElementTypeMap<UInt>
-  getInternalDataPerElem(const std::string & field_name, ElementKind kind);
+  virtual ElementTypeMap<Int>
+  getInternalDataPerElem(const std::string & field_name,
+                         const ElementKind & kind);
 
   //! flatten a given material internal field
   ElementTypeMapArray<Real> &
   flattenInternal(const std::string & field_name, ElementKind kind,
                   GhostType ghost_type = _not_ghost);
   //! flatten all the registered material internals
   void flattenAllRegisteredInternals(ElementKind kind);
 
   std::shared_ptr<dumpers::Field>
   createNodalFieldReal(const std::string & field_name,
                        const std::string & group_name,
                        bool padding_flag) override;
 
   std::shared_ptr<dumpers::Field>
   createNodalFieldBool(const std::string & field_name,
                        const std::string & group_name,
                        bool padding_flag) override;
 
   std::shared_ptr<dumpers::Field>
   createElementalField(const std::string & field_name,
                        const std::string & group_name, bool padding_flag,
-                       UInt spatial_dimension, ElementKind kind) override;
+                       const Int & spatial_dimension,
+                       const ElementKind & kind) override;
 
   void dump(const std::string & dumper_name) override;
-  void dump(const std::string & dumper_name, UInt step) override;
-  void dump(const std::string & dumper_name, Real time, UInt step) override;
+  void dump(const std::string & dumper_name, Int step) override;
+  void dump(const std::string & dumper_name, Real time, Int step) override;
 
   void dump() override;
-  void dump(UInt step) override;
-  void dump(Real time, UInt step) override;
+  void dump(Int step) override;
+  void dump(Real time, Int step) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// 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 array
   AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(Displacement, displacement);
   /// get the SolidMechanicsModel::displacement array
   AKANTU_GET_MACRO_DEREF_PTR(Displacement, displacement);
 
   /// get the SolidMechanicsModel::previous_displacement array
   AKANTU_GET_MACRO_DEREF_PTR(PreviousDisplacement, previous_displacement);
 
   /// get the SolidMechanicsModel::current_position array
   const Array<Real> & getCurrentPosition();
 
   /// get  the SolidMechanicsModel::displacement_increment  array
   AKANTU_GET_MACRO_DEREF_PTR(Increment, displacement_increment);
   /// get  the SolidMechanicsModel::displacement_increment  array
   AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(Increment, displacement_increment);
 
   /// get the lumped SolidMechanicsModel::mass array
   AKANTU_GET_MACRO_DEREF_PTR(Mass, mass);
 
   /// get the SolidMechanicsModel::velocity array
   AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(Velocity, velocity);
   /// get the SolidMechanicsModel::velocity array
   AKANTU_GET_MACRO_DEREF_PTR(Velocity, velocity);
 
   /// get    the    SolidMechanicsModel::acceleration   array
   AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(Acceleration, acceleration);
   /// get    the    SolidMechanicsModel::acceleration   array
   AKANTU_GET_MACRO_DEREF_PTR(Acceleration, acceleration);
 
   /// get the SolidMechanicsModel::external_force array
   AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(ExternalForce, external_force);
   /// get the SolidMechanicsModel::external_force array
   AKANTU_GET_MACRO_DEREF_PTR(ExternalForce, external_force);
 
   /// get the SolidMechanicsModel::force array (external forces)
   [[deprecated("Use getExternalForce instead of this function")]] Array<Real> &
   getForce() {
     return getExternalForce();
   }
 
   /// get the SolidMechanicsModel::internal_force array (internal forces)
   AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(InternalForce, internal_force);
   /// get the SolidMechanicsModel::internal_force array (internal forces)
   AKANTU_GET_MACRO_DEREF_PTR(InternalForce, internal_force);
 
   /// get the SolidMechanicsModel::blocked_dofs array
   AKANTU_GET_MACRO_DEREF_PTR_NOT_CONST(BlockedDOFs, blocked_dofs);
   /// get the SolidMechanicsModel::blocked_dofs array
   AKANTU_GET_MACRO_DEREF_PTR(BlockedDOFs, blocked_dofs);
 
   /// get an iterable on the materials
   inline decltype(auto) getMaterials();
 
   /// get an iterable on the materials
   inline decltype(auto) getMaterials() const;
 
   /// get a particular material (by numerical material index)
   inline Material & getMaterial(UInt mat_index);
 
   /// get a particular material (by numerical 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;
+  inline Int getMaterialIndex(const std::string & name) const;
 
   /// give the number of materials
   inline UInt getNbMaterials() const { return materials.size(); }
 
   /// give the material internal index from its id
   Int getInternalIndexFromID(const ID & id) const;
 
   /// compute the stable time step
   Real getStableTimeStep();
 
   /**
    * @brief Returns the total energy for a given energy type
    *
    * Energy types of SolidMechanicsModel expected as argument are:
    *   - `kinetic`
    *   - `external work`
    *
    * Other energy types are passed on to the materials. All materials should
    * define a `potential` energy type. For additional energy types, see material
    * documentation.
    */
   Real getEnergy(const std::string & energy_id);
 
   /// Compute energy for an element type and material index
-  Real getEnergy(const std::string & energy_id, ElementType type, UInt index);
+  Real getEnergy(const std::string & energy_id, ElementType type, Idx index);
 
   /// Compute energy for an individual element
   Real getEnergy(const std::string & energy_id, const Element & element) {
     return getEnergy(energy_id, element.type, element.element);
   }
 
   /// Compute energy for an element group
   Real getEnergy(const ID & energy_id, const ID & group_id);
 
-  AKANTU_GET_MACRO(MaterialByElement, material_index,
-                   const ElementTypeMapArray<UInt> &);
-  AKANTU_GET_MACRO(MaterialLocalNumbering, material_local_numbering,
-                   const ElementTypeMapArray<UInt> &);
+  AKANTU_GET_MACRO_AUTO(MaterialByElement, material_index);
+  AKANTU_GET_MACRO_AUTO(MaterialLocalNumbering, material_local_numbering);
 
   /// 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);
+                                         Int);
+  // AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialByElement, material_index, Int);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialLocalNumbering,
-                                         material_local_numbering, UInt);
+                                         material_local_numbering, Int);
   // AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialLocalNumbering,
   //                                  material_local_numbering, UInt);
 
   AKANTU_GET_MACRO_NOT_CONST(MaterialSelector, material_selector,
                              std::shared_ptr<MaterialSelector>);
   void
   setMaterialSelector(std::shared_ptr<MaterialSelector> material_selector) {
     this->material_selector = std::move(material_selector);
   }
 
   /// Access the non_local_manager interface
   AKANTU_GET_MACRO(NonLocalManager, *non_local_manager, NonLocalManager &);
 
   /// get the FEEngine object to integrate or interpolate on the boundary
   FEEngine & getFEEngineBoundary(const ID & name = "") override;
 
 protected:
   /// compute the stable time step
   Real getStableTimeStep(GhostType ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// release version of the displacement array
-  UInt displacement_release{0};
+  Int displacement_release{0};
 
   /// release version of the current_position array
-  UInt current_position_release{0};
+  Int current_position_release{0};
 
   /// 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};
 
   /// mapping between material name and material internal id
-  std::map<std::string, UInt> materials_names_to_id;
+  std::map<std::string, Int> materials_names_to_id;
 
 protected:
   /// conversion coefficient form force/mass to acceleration
   Real f_m2a{1.0};
 
   /// displacements array
   std::unique_ptr<Array<Real>> displacement;
 
   /// displacements array at the previous time step (used in finite deformation)
   std::unique_ptr<Array<Real>> previous_displacement;
 
   /// increment of displacement
   std::unique_ptr<Array<Real>> displacement_increment;
 
   /// lumped mass array
   std::unique_ptr<Array<Real>> mass;
 
   /// velocities array
   std::unique_ptr<Array<Real>> velocity;
 
   /// accelerations array
   std::unique_ptr<Array<Real>> acceleration;
 
   /// external forces array
   std::unique_ptr<Array<Real>> external_force;
 
   /// internal forces array
   std::unique_ptr<Array<Real>> internal_force;
 
   /// array specifing if a degree of freedom is blocked or not
   std::unique_ptr<Array<bool>> blocked_dofs;
 
   /// array of current position used during update residual
   std::unique_ptr<Array<Real>> current_position;
 
   /// Arrays containing the material index for each element
-  ElementTypeMapArray<UInt> material_index;
+  ElementTypeMapArray<Int> material_index;
 
   /// Arrays containing the position in the element filter of the material
   /// (material's local numbering)
-  ElementTypeMapArray<UInt> material_local_numbering;
+  ElementTypeMapArray<Int> material_local_numbering;
 
   /// list of used materials
   std::vector<std::unique_ptr<Material>> materials;
 
   /// class defining of to choose a material
   std::shared_ptr<MaterialSelector> material_selector;
 
   using flatten_internal_map =
       std::map<std::pair<std::string, ElementKind>,
                std::unique_ptr<ElementTypeMapArray<Real>>>;
 
   /// tells if the material are instantiated
   flatten_internal_map registered_internals;
 
   /// non local manager
   std::unique_ptr<NonLocalManager> non_local_manager;
 
   /// tells if the material are instantiated
   bool are_materials_instantiated{false};
 
   friend class Material;
 
     template <class Model_> friend class CouplerSolidContactTemplate;
 };
 
 /* -------------------------------------------------------------------------- */
 namespace BC {
   namespace Neumann {
     using FromStress = FromHigherDim;
     using FromTraction = FromSameDim;
   } // namespace Neumann
 } // namespace BC
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 #include "parser.hh"
 
 #include "solid_mechanics_model_inline_impl.hh"
 #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 4f7daf317..b2e9867bf 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,547 +1,547 @@
 /**
  * @file   fragment_manager.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Thu Jan 23 2014
  * @date last modification: Mon Mar 29 2021
  *
  * @brief  Group manager to handle fragments
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "communicator.hh"
 #include "element_synchronizer.hh"
 #include "material_cohesive.hh"
 #include "mesh_iterators.hh"
 #include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <functional>
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 FragmentManager::FragmentManager(SolidMechanicsModelCohesive & model,
                                  bool dump_data, const ID & id)
     : GroupManager(model.getMesh(), id), model(model),
       mass_center(0, model.getSpatialDimension(), "mass_center"),
       mass(0, model.getSpatialDimension(), "mass"),
       velocity(0, model.getSpatialDimension(), "velocity"),
       inertia_moments(0, model.getSpatialDimension(), "inertia_moments"),
       principal_directions(
           0, model.getSpatialDimension() * model.getSpatialDimension(),
           "principal_directions"),
       quad_coordinates("quad_coordinates", id),
       mass_density("mass_density", id),
       nb_elements_per_fragment(0, 1, "nb_elements_per_fragment"),
       dump_data(dump_data) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   /// compute quadrature points' coordinates
   quad_coordinates.initialize(mesh, _nb_component = spatial_dimension,
                               _spatial_dimension = spatial_dimension,
                               _ghost_type = _not_ghost);
   // mesh.initElementTypeMapArray(quad_coordinates, spatial_dimension,
   //                              spatial_dimension, _not_ghost);
 
   model.getFEEngine().interpolateOnIntegrationPoints(model.getMesh().getNodes(),
                                                      quad_coordinates);
 
   /// store mass density per quadrature point
   mass_density.initialize(mesh, _spatial_dimension = spatial_dimension,
                           _ghost_type = _not_ghost);
   // mesh.initElementTypeMapArray(mass_density, 1, spatial_dimension,
   // _not_ghost);
 
   storeMassDensityPerIntegrationPoint();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 class CohesiveElementFilter : public GroupManager::ClusteringFilter {
 public:
   CohesiveElementFilter(const SolidMechanicsModelCohesive & model,
                         const Real max_damage = 1.)
       : model(model), is_unbroken(max_damage) {}
 
   bool operator()(const Element & el) const override {
     if (Mesh::getKind(el.type) == _ek_regular) {
       return true;
     }
 
-    const Array<UInt> & mat_indexes =
+    const auto & mat_indexes =
         model.getMaterialByElement(el.type, el.ghost_type);
-    const Array<UInt> & mat_loc_num =
+    const auto & mat_loc_num =
         model.getMaterialLocalNumbering(el.type, el.ghost_type);
 
     const auto & mat = static_cast<const MaterialCohesive &>(
         model.getMaterial(mat_indexes(el.element)));
 
-    UInt el_index = mat_loc_num(el.element);
-    UInt nb_quad_per_element =
+    auto el_index = mat_loc_num(el.element);
+    auto 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);
+    const auto & damage_array = mat.getDamage(el.type, el.ghost_type);
 
-    AKANTU_DEBUG_ASSERT(nb_quad_per_element * el_index < damage_array.size(),
+    AKANTU_DEBUG_ASSERT(Int(nb_quad_per_element * el_index) <
+                            damage_array.size(),
                         "This quadrature point is out of range");
 
-    const Real * element_damage =
+    const auto * element_damage =
         damage_array.data() + nb_quad_per_element * el_index;
 
-    UInt unbroken_quads = std::count_if(
+    auto unbroken_quads = std::count_if(
         element_damage, element_damage + nb_quad_per_element, is_unbroken);
 
     return (unbroken_quads > 0);
   }
 
 private:
   struct IsUnbrokenFunctor {
     IsUnbrokenFunctor(const Real & max_damage) : max_damage(max_damage) {}
     bool operator()(const Real & x) const { 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 (mesh.isDistributed()) {
     auto & cohesive_synchronizer = model.getCohesiveSynchronizer();
     cohesive_synchronizer.synchronize(model, SynchronizationTag::_smmc_damage);
   }
 
   auto & mesh_facets = 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);
 
   /// loop over fragments
   for (auto && data : zip(iterateElementGroups(), fragment_index)) {
     auto name = std::get<0>(data).getName();
     /// get fragment index
     std::string fragment_index_string = name.substr(fragment_prefix.size() + 1);
     std::get<1>(data) = std::stoul(fragment_index_string);
   }
 
   /// 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.);
 
   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.data();
   Real * mass_center_storage = mass_center.data();
 
   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);
 
   model.getFEEngine().interpolateOnIntegrationPoints(model.getVelocity(),
                                                      velocity_field);
 
   /// integrate on fragments
   integrateFieldOnFragments(velocity_field, velocity);
 
   /// divide it by the fragments' mass
   Real * mass_storage = mass.data();
   Real * velocity_storage = velocity.data();
 
   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.);
 
   /// loop over fragments
   for (auto && data :
        zip(iterateElementGroups(), make_view(mass_center, spatial_dimension))) {
     const auto & el_list = std::get<0>(data).getElements();
     auto & mass_center = std::get<1>(data);
 
     /// loop over elements of the fragment
     for (auto type :
          el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
       auto nb_quad_per_element =
           model.getFEEngine().getNbIntegrationPoints(type);
 
       auto & moments_coords_array = moments_coords(type);
       const auto & quad_coordinates_array = quad_coordinates(type);
       const auto & el_list_array = el_list(type);
 
       auto moments_begin =
           moments_coords_array.begin(spatial_dimension, spatial_dimension);
       auto quad_coordinates_begin =
           quad_coordinates_array.begin(spatial_dimension);
 
       Vector<Real> relative_coords(spatial_dimension);
 
-      for (UInt el = 0; el < el_list_array.size(); ++el) {
-        UInt global_el = el_list_array(el);
+      for (Int el = 0; el < el_list_array.size(); ++el) {
+        auto 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;
+        for (Int q = 0; q < nb_quad_per_element; ++q) {
+          auto global_q = global_el * nb_quad_per_element + q;
           auto && moments_matrix = moments_begin[global_q];
           const auto & 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;
 
           moments_matrix = relative_coords * relative_coords.transpose();
           Real trace = moments_matrix.trace();
-          moments_matrix *= -1.;
-          moments_matrix += trace * Matrix<Real>::Identity(spatial_dimension,
-                                                           spatial_dimension);
+          moments_matrix = -1. * moments_matrix +
+                           trace * Matrix<Real>::Identity(spatial_dimension,
+                                                          spatial_dimension);
         }
       }
     }
   }
 
   /// 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);
 
   auto integrated_moments_it =
       integrated_moments.begin(spatial_dimension, spatial_dimension);
   auto inertia_moments_it = inertia_moments.begin(spatial_dimension);
   auto 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->eigh(*inertia_moments_it, *principal_directions_it);
   }
 
   if (dump_data) {
     createDumpDataArray(inertia_moments, "moments of inertia");
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeAllData(Real damage_limit) {
   AKANTU_DEBUG_IN();
 
   buildFragments(damage_limit);
   computeVelocity();
   computeInertiaMoments();
   computeNbElementsPerFragment();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::storeMassDensityPerIntegrationPoint() {
   AKANTU_DEBUG_IN();
 
-  UInt spatial_dimension = model.getSpatialDimension();
+  auto spatial_dimension = model.getSpatialDimension();
 
   for (auto type : mesh.elementTypes(_spatial_dimension = spatial_dimension,
                    _element_kind = _ek_regular)) {
-    Array<Real> & mass_density_array = mass_density(type);
+    auto & mass_density_array = mass_density(type);
 
-    UInt nb_element = mesh.getNbElement(type);
-    UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
+    auto nb_element = mesh.getNbElement(type);
+    auto 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);
+    const auto & mat_indexes = model.getMaterialByElement(type);
 
-    Real * mass_density_it = mass_density_array.data();
+    auto * mass_density_it = mass_density_array.data();
 
     /// 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 (Int el = 0; el < nb_element; ++el) {
+      auto & mat = model.getMaterial(mat_indexes(el));
 
-      for (UInt q = 0; q < nb_quad_per_element; ++q, ++mass_density_it) {
+      for (Int 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();
+  auto spatial_dimension = model.getSpatialDimension();
+  auto nb_component = output.getNbComponent();
 
   /// integration part
   output.resize(global_nb_fragment);
   output.zero();
 
   auto output_begin = output.begin(nb_component);
 
   /// loop over fragments
   for (auto && data : zip(iterateElementGroups(), fragment_index)) {
     const auto & el_list = std::get<0>(data).getElements();
     auto fragment_index = std::get<1>(data);
 
     /// loop over elements of the fragment
     for (auto type :
          el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
 
-      UInt nb_quad_per_element =
+      auto 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);
+      const auto & density_array = mass_density(type);
+      auto & field_array = field(type);
+      const auto & elements = el_list(type);
 
       /// generate array to be integrated by filtering fragment's elements
       Array<Real> integration_array(elements.size() * nb_quad_per_element,
                                     nb_component);
 
-      auto field_array_begin = field_array.begin_reinterpret(
-          nb_quad_per_element, nb_component,
-          field_array.size() / nb_quad_per_element);
-      auto density_array_begin = density_array.begin_reinterpret(
-          nb_quad_per_element, density_array.size() / nb_quad_per_element);
+      auto field_array_begin =
+          make_view(field_array, nb_quad_per_element, nb_component).begin();
+      auto density_array_begin =
+          make_view(density_array, nb_quad_per_element).begin();
 
       for (auto && data : enumerate(make_view(
                integration_array, nb_quad_per_element, nb_component))) {
-        UInt global_el = elements(std::get<0>(data));
+        auto global_el = elements(std::get<0>(data));
         auto & int_array = std::get<1>(data);
         int_array = field_array_begin[global_el];
 
         /// multiply field by density
-        const Vector<Real> & density_vector = density_array_begin[global_el];
+        const auto & 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) {
+        for (Int i = 0; i < nb_quad_per_element; ++i) {
+          for (Int j = 0; j < nb_component; ++j) {
             int_array(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]);
       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();
+  const auto & 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.zero();
 
   /// loop over fragments
   for (auto && data : zip(iterateElementGroups(), fragment_index)) {
     const auto & el_list = std::get<0>(data).getElements();
     auto fragment_index = std::get<1>(data);
 
     /// 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) += 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.empty()) {
     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);
 
   /// loop over fragments
   for (auto && data : zip(iterateElementGroups(), fragment_index)) {
     const auto & fragment = std::get<0>(data);
     auto fragment_idx = std::get<1>(data);
 
     /// 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.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
index 9da4bd348..3f5f34a91 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.cc
@@ -1,169 +1,169 @@
 /**
  * @file   material_selector_cohesive.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Dec 11 2015
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Material selector for cohesive elements
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_cohesive.hh"
 #include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 DefaultMaterialCohesiveSelector::DefaultMaterialCohesiveSelector(
     const SolidMechanicsModelCohesive & model)
     : facet_material(model.getFacetMaterial()), mesh(model.getMesh()) {
   // backward compatibility v3: to get the former behavior back when the user
   // creates its own selector
   this->fallback_selector =
       std::make_shared<DefaultMaterialSelector>(model.getMaterialByElement());
 }
 
 /* -------------------------------------------------------------------------- */
-UInt DefaultMaterialCohesiveSelector::operator()(const Element & element) {
+Int DefaultMaterialCohesiveSelector::operator()(const Element & element) {
   if (Mesh::getKind(element.type) == _ek_cohesive) {
     try {
       const Array<Element> & cohesive_el_to_facet =
           mesh.getMeshFacets().getSubelementToElement(element.type,
                                                       element.ghost_type);
       bool third_dimension = (mesh.getSpatialDimension() == 3);
       const Element & facet =
           cohesive_el_to_facet(element.element, UInt(third_dimension));
       if (facet_material.exists(facet.type, facet.ghost_type)) {
         return facet_material(facet.type, facet.ghost_type)(facet.element);
       }
       return fallback_value;
 
     } catch (...) {
       return fallback_value;
     }
   } else if (Mesh::getSpatialDimension(element.type) ==
              mesh.getSpatialDimension() - 1) {
     return facet_material(element.type, element.ghost_type)(element.element);
   } else {
     return MaterialSelector::operator()(element);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 MeshDataMaterialCohesiveSelector::MeshDataMaterialCohesiveSelector(
     const SolidMechanicsModelCohesive & model)
     : model(model), mesh_facets(model.getMeshFacets()),
       material_index(mesh_facets.getData<std::string>("physical_names")) {
   third_dimension = (model.getSpatialDimension() == 3);
   // backward compatibility v3: to get the former behavior back when the user
   // creates its own selector
   this->fallback_selector =
       std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names",
                                                               model);
 }
 
 /* -------------------------------------------------------------------------- */
-UInt MeshDataMaterialCohesiveSelector::operator()(const Element & element) {
+Int MeshDataMaterialCohesiveSelector::operator()(const Element & element) {
   if (Mesh::getKind(element.type) == _ek_cohesive or
       Mesh::getSpatialDimension(element.type) ==
           mesh_facets.getSpatialDimension() - 1) {
     Element facet;
     if (Mesh::getKind(element.type) == _ek_cohesive) {
       facet =
           mesh_facets.getSubelementToElement(element.type, element.ghost_type)(
               element.element, UInt(third_dimension));
     } else {
       facet = element;
     }
 
     try {
       std::string material_name = this->material_index(facet);
       return this->model.getMaterialIndex(material_name);
     } catch (...) {
       return fallback_value;
     }
   }
   return MaterialSelector::operator()(element);
 }
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 MaterialCohesiveRulesSelector::MaterialCohesiveRulesSelector(
     const SolidMechanicsModelCohesive & model,
     const MaterialCohesiveRules & rules,
     ID mesh_data_id) // what we have here is the name of model and also
                      // the name of different materials
     : model(model), mesh_data_id(std::move(mesh_data_id)),
       mesh(model.getMesh()), mesh_facets(model.getMeshFacets()),
       spatial_dimension(model.getSpatialDimension()), rules(rules) {
 
   // cohesive fallback
   this->fallback_selector =
       std::make_shared<DefaultMaterialCohesiveSelector>(model);
 
   // non cohesive fallback
   this->fallback_selector->setFallback(
       std::make_shared<MeshDataMaterialSelector<std::string>>(mesh_data_id,
                                                               model));
 }
 
 /* -------------------------------------------------------------------------- */
-UInt MaterialCohesiveRulesSelector::operator()(const Element & element) {
+Int MaterialCohesiveRulesSelector::operator()(const Element & element) {
   if (mesh_facets.getSpatialDimension(element.type) ==
       (spatial_dimension - 1)) {
-    const std::vector<Element> & element_to_subelement =
+    const auto & element_to_subelement =
         mesh_facets.getElementToSubelement(element.type,
                                            element.ghost_type)(element.element);
     // Array<bool> & facets_check = model.getFacetsCheck();
 
-    const Element & el1 = element_to_subelement[0];
-    const Element & el2 = element_to_subelement[1];
+    const auto & el1 = element_to_subelement[0];
+    const auto & el2 = element_to_subelement[1];
 
-    ID id1 = mesh.getData<std::string>(mesh_data_id, el1.type,
+    auto id1 = mesh.getData<std::string>(mesh_data_id, el1.type,
                                        el1.ghost_type)(el1.element);
 
-    ID id2 = id1;
+    auto id2 = id1;
     if (el2 != ElementNull) {
       id2 = mesh.getData<std::string>(mesh_data_id, el2.type,
                                       el2.ghost_type)(el2.element);
     }
 
     auto rit = rules.find(std::make_pair(id1, id2));
     if (rit == rules.end()) {
       rit = rules.find(std::make_pair(id2, id1));
     }
 
     if (rit != rules.end()) {
       return model.getMaterialIndex(rit->second);
     }
   }
 
   return MaterialSelector::operator()(element);
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/material_selector_cohesive.hh
index e4108e199..9e8f274b9 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,100 +1,100 @@
 /**
  * @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: Fri Apr 09 2021
  *
  * @brief  Material selectors for cohesive elements
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class SolidMechanicsModelCohesive;
 }
 
 namespace akantu {
 
 #ifndef AKANTU_MATERIAL_SELECTOR_COHESIVE_HH_
 #define AKANTU_MATERIAL_SELECTOR_COHESIVE_HH_
 
 /* -------------------------------------------------------------------------- */
 /**
  * class that assigns the first cohesive material by default to the
  * cohesive elements
  */
 class DefaultMaterialCohesiveSelector : public MaterialSelector {
 public:
   DefaultMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model);
-  UInt operator()(const Element & element) override;
+  Int operator()(const Element & element) override;
 
 private:
-  const ElementTypeMapArray<UInt> & facet_material;
+  const ElementTypeMapArray<Idx> & facet_material;
   const Mesh & mesh;
 };
 
 /* -------------------------------------------------------------------------- */
 /// To be used with intrinsic elements inserted along mesh physical surfaces
 class MeshDataMaterialCohesiveSelector : public MaterialSelector {
 public:
   MeshDataMaterialCohesiveSelector(const SolidMechanicsModelCohesive & model);
-  UInt operator()(const Element & element) override;
+  Int operator()(const Element & element) override;
 
 protected:
   const SolidMechanicsModelCohesive & model;
   const Mesh & mesh_facets;
   const ElementTypeMapArray<std::string> & material_index;
   bool third_dimension;
 };
 
 /// bulk1, bulk2 -> cohesive
 using MaterialCohesiveRules = std::map<std::pair<ID, ID>, ID>;
 
 /* -------------------------------------------------------------------------- */
 class MaterialCohesiveRulesSelector : public MaterialSelector {
 public:
   MaterialCohesiveRulesSelector(const SolidMechanicsModelCohesive & model,
                                 const MaterialCohesiveRules & rules,
                                 ID mesh_data_id = "physical_names");
-  UInt operator()(const Element & element) override;
+  Int operator()(const Element & element) override;
 
 private:
   const SolidMechanicsModelCohesive & model;
   ID mesh_data_id;
   const Mesh & mesh;
   const Mesh & mesh_facets;
-  UInt spatial_dimension;
+  Int spatial_dimension;
   MaterialCohesiveRules rules;
 };
 
 #endif /* AKANTU_MATERIAL_SELECTOR_COHESIVE_HH_ */
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
index b69ab1cdc..956662dce 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
@@ -1,215 +1,205 @@
 /**
  * @file   material_cohesive_bilinear.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Feb 22 2012
  * @date last modification: Sat Dec 19 2020
  *
  * @brief  Bilinear cohesive constitutive law
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_bilinear.hh"
 //#include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialCohesiveBilinear<spatial_dimension>::MaterialCohesiveBilinear(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesiveLinear<spatial_dimension>(model, id) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("delta_0", delta_0, Real(0.),
                       _pat_parsable | _pat_readable,
                       "Elastic limit displacement");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   this->sigma_c_eff.setRandomDistribution(this->sigma_c.getRandomParameter());
   MaterialCohesiveLinear<spatial_dimension>::initMaterial();
 
   this->delta_max.setDefaultValue(delta_0);
   this->insertion_stress.setDefaultValue(0);
 
   this->delta_max.reset();
   this->insertion_stress.reset();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::onElementsAdded(
     const Array<Element> & element_list, const NewElementsEvent & event) {
   AKANTU_DEBUG_IN();
 
   MaterialCohesiveLinear<spatial_dimension>::onElementsAdded(element_list,
                                                              event);
 
   bool scale_traction = false;
 
   // don't scale sigma_c if volume_s hasn't been specified by the user
   if (!Math::are_float_equal(this->volume_s, 0.)) {
     scale_traction = true;
   }
 
-  Array<Element>::const_scalar_iterator el_it = element_list.begin();
-  Array<Element>::const_scalar_iterator el_end = element_list.end();
-
-  for (; el_it != el_end; ++el_it) {
+  for (auto && el : element_list) {
     // filter not ghost cohesive elements
-    if ((el_it->ghost_type != _not_ghost) or
-        (Mesh::getKind(el_it->type) != _ek_cohesive)) {
+    if ((el.ghost_type != _not_ghost) or (Mesh::getKind(el.type) != _ek_cohesive))
       continue;
     }
 
-    UInt index = el_it->element;
-    ElementType type = el_it->type;
-    UInt nb_element = this->model->getMesh().getNbElement(type);
-    UInt nb_quad_per_element = this->fem_cohesive.getNbIntegrationPoints(type);
+    auto index = el.element;
+    auto type = el.type;
+    auto nb_quad_per_element = this->fem_cohesive.getNbIntegrationPoints(type);
 
-    auto sigma_c_begin = this->sigma_c_eff(type).begin_reinterpret(
-        nb_quad_per_element, nb_element);
-    Vector<Real> sigma_c_vec = sigma_c_begin[index];
+    auto sigma_c_begin =
+        make_view(this->sigma_c_eff(type), nb_quad_per_element).begin();
+    auto && sigma_c_vec = sigma_c_begin[index];
 
-    auto delta_c_begin = this->delta_c_eff(type).begin_reinterpret(
-        nb_quad_per_element, nb_element);
-    Vector<Real> delta_c_vec = delta_c_begin[index];
+    auto delta_c_begin =
+        make_view(this->delta_c_eff(type), nb_quad_per_element).begin();
+    auto && delta_c_vec = delta_c_begin[index];
 
     if (scale_traction) {
-      scaleTraction(*el_it, sigma_c_vec);
+      scaleTraction(el, sigma_c_vec);
     }
 
     /**
      * Recompute sigma_c as
      * @f$ {\sigma_c}_\textup{new} =
      * \frac{{\sigma_c}_\textup{old} \delta_c} {\delta_c - \delta_0} @f$
      */
 
-    for (UInt q = 0; q < nb_quad_per_element; ++q) {
+    for (Int q = 0; q < nb_quad_per_element; ++q) {
       delta_c_vec(q) = 2 * this->G_c / sigma_c_vec(q);
 
       if (delta_c_vec(q) - delta_0 < Math::getTolerance()) {
         AKANTU_ERROR("delta_0 = " << delta_0 << " must be lower than delta_c = "
                                   << delta_c_vec(q)
                                   << ", modify your material file");
       }
 
       sigma_c_vec(q) *= delta_c_vec(q) / (delta_c_vec(q) - delta_0);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
+template<typename D1>
 void MaterialCohesiveBilinear<spatial_dimension>::scaleTraction(
-    const Element & el, Vector<Real> & sigma_c_vec) {
+    const Element & el, Eigen::MatrixBase<D1> & sigma_c_vec) {
   AKANTU_DEBUG_IN();
 
-  Real base_sigma_c = this->sigma_c_eff;
+  auto base_sigma_c = Real(this->sigma_c_eff);
 
-  const Mesh & mesh_facets = this->model->getMeshFacets();
-  const FEEngine & fe_engine = this->model->getFEEngine();
+  const auto & mesh_facets = this->model->getMeshFacets();
+  const auto & fe_engine = this->model->getFEEngine();
 
   auto coh_element_to_facet_begin =
       mesh_facets.getSubelementToElement(el.type).begin(2);
-  const Vector<Element> & coh_element_to_facet =
-      coh_element_to_facet_begin[el.element];
+  const auto & coh_element_to_facet = coh_element_to_facet_begin[el.element];
 
   // compute bounding volume
-  Real volume = 0;
+  Real volume = 0.;
 
   // loop over facets
   for (UInt f = 0; f < 2; ++f) {
-    const Element & facet = coh_element_to_facet(f);
+    const auto & facet = coh_element_to_facet(f);
 
-    const Array<std::vector<Element>> & facet_to_element =
+    const auto & facet_to_element =
         mesh_facets.getElementToSubelement(facet.type, facet.ghost_type);
 
-    const std::vector<Element> & element_list = facet_to_element(facet.element);
-
-    auto elem = element_list.begin();
-    auto elem_end = element_list.end();
-
     // loop over elements connected to each facet
-    for (; elem != elem_end; ++elem) {
+    for (auto && elem : facet_to_element(facet.element)) {
       // skip cohesive elements and dummy elements
-      if (*elem == ElementNull || Mesh::getKind(elem->type) == _ek_cohesive) {
+      if (elem == ElementNull || Mesh::getKind(elem.type) == _ek_cohesive) {
         continue;
       }
 
       // unit vector for integration in order to obtain the volume
-      UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(elem->type);
-      Vector<Real> unit_vector(nb_quadrature_points, 1);
+      auto nb_quadrature_points = fe_engine.getNbIntegrationPoints(elem.type);
+      Vector<Real> unit_vector(nb_quadrature_points);
+      unit_vector.fill(1);
 
-      volume += fe_engine.integrate(unit_vector, elem->type, elem->element,
-                                    elem->ghost_type);
+      volume += fe_engine.integrate(unit_vector, elem);
     }
   }
 
   // scale sigma_c
   sigma_c_vec = (sigma_c_vec.array() - base_sigma_c) *
                     std::pow(this->volume_s / volume, 1. / this->m_s) +
                 base_sigma_c;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   MaterialCohesiveLinear<spatial_dimension>::computeTraction(normal, el_type,
                                                              ghost_type);
 
   // adjust damage
-  auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
-  auto delta_max_it = this->delta_max(el_type, ghost_type).begin();
-  auto damage_it = this->damage(el_type, ghost_type).begin();
-  auto damage_end = this->damage(el_type, ghost_type).end();
-
-  for (; damage_it != damage_end; ++damage_it, ++delta_max_it, ++delta_c_it) {
-    *damage_it =
-        std::max((*delta_max_it - delta_0) / (*delta_c_it - delta_0), Real(0.));
-    *damage_it = std::min(*damage_it, Real(1.));
+  for (auto && data : zip(this->damage(el_type, ghost_type),
+                          this->delta_max(el_type, ghost_type),
+                          this->delta_c_eff(el_type, ghost_type))) {
+    auto & dam = std::get<0>(data);
+    auto & delta_max = std::get<1>(data);
+    auto & delta_c = std::get<2>(data);
+
+    dam = std::max((delta_max - delta_0) / (delta_c - delta_0), Real(0.));
+    dam = std::min(dam, Real(1.));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_bilinear, MaterialCohesiveBilinear);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
index dd21d5211..acffb5871 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.hh
@@ -1,106 +1,107 @@
 /**
  * @file   material_cohesive_bilinear.hh
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Bilinear cohesive constitutive law
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "material_cohesive_linear.hh"
 
 #ifndef AKANTU_MATERIAL_COHESIVE_BILINEAR_HH_
 #define AKANTU_MATERIAL_COHESIVE_BILINEAR_HH_
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Cohesive material bilinear
  *
  * parameters in the material files :
  *   - delta_0   : elastic limit displacement (default: 0)
  *   - sigma_c   : critical stress sigma_c  (default: 0)
  *   - beta      : weighting parameter for sliding and normal opening (default:
  * 0)
  *   - G_cI      : fracture energy for mode I (default: 0)
  *   - G_cII     : fracture energy for mode II (default: 0)
  *   - penalty   : stiffness in compression to prevent penetration
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialCohesiveBilinear
     : public MaterialCohesiveLinear<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialCohesiveBilinear(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
   void initMaterial() override;
 
   /// set material parameters for new elements
   void onElementsAdded(const Array<Element> & element_list,
                        const NewElementsEvent & event) override;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /**
    * Scale traction sigma_c according to the volume of the
    * two elements surrounding an element
    */
-  void scaleTraction(const Element & el, Vector<Real> & sigma_c_vec);
+  template <typename D1>
+  void scaleTraction(const Element & el, Eigen::MatrixBase<D1> & sigma_c_vec);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// elastic limit displacement
   Real delta_0;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 //#include "material_cohesive_elastic_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_COHESIVE_BILINEAR_HH_ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
index 04dc18135..d2dc52e92 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
@@ -1,307 +1,307 @@
 /**
  * @file   material_cohesive_exponential.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Mon Jul 09 2012
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Exponential irreversible cohesive law of mixed mode loading
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_exponential.hh"
 #include "dof_synchronizer.hh"
 #include "solid_mechanics_model.hh"
 #include "sparse_matrix.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialCohesiveExponential<dim>::MaterialCohesiveExponential(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesive(model, id) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("beta", beta, Real(0.), _pat_parsable, "Beta parameter");
 
   this->registerParam("exponential_penalty", exp_penalty, true, _pat_parsable,
                       "Is contact penalty following the exponential law?");
 
   this->registerParam(
       "contact_tangent", contact_tangent, Real(1.0), _pat_parsable,
       "Ratio of contact tangent over the initial exponential tangent");
 
   // this->initInternalArray(delta_max, 1, _ek_cohesive);
 
   use_previous_delta_max = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialCohesiveExponential<dim>::initMaterial() {
+template <Int dim> void MaterialCohesiveExponential<dim>::initMaterial() {
 
   AKANTU_DEBUG_IN();
   MaterialCohesive::initMaterial();
 
   if ((exp_penalty) && (contact_tangent != 1)) {
 
     contact_tangent = 1;
     AKANTU_DEBUG_WARNING("The parsed paramter <contact_tangent> is forced to "
                          "1.0 when the contact penalty follows the exponential "
                          "law");
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialCohesiveExponential<dim>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// compute scalars
   Real beta2 = beta * beta;
 
   /// loop on each quadrature point
   for (auto && data :
        zip(make_view<dim>(tractions(el_type, ghost_type)),
            make_view<dim>(opening(el_type, ghost_type)), make_view<dim>(normal),
            delta_max(el_type, ghost_type),
            delta_max.previous(el_type, ghost_type))) {
     auto & traction = std::get<0>(data);
     auto & opening = std::get<1>(data);
     auto & normal = std::get<2>(data);
     auto & delta_max = std::get<3>(data);
     auto & delta_max_prev = std::get<4>(data);
 
     /// compute normal and tangential opening vectors
     Real normal_opening_norm = opening.dot(normal);
     auto && normal_opening = normal * normal_opening_norm;
     auto && tangential_opening = opening - normal_opening;
 
     Real tangential_opening_norm = tangential_opening.norm();
 
     /**
      * compute effective opening displacement
      * @f$ \delta = \sqrt{
      * \beta^2 \Delta_t^2 + \Delta_n^2 } @f$
      */
     Real delta = tangential_opening_norm * delta * beta2 +
                  normal_opening_norm * normal_opening_norm;
 
     delta = sqrt(delta);
 
     if ((normal_opening_norm < 0) &&
         (std::abs(normal_opening_norm) > Math::getTolerance())) {
 
       auto && delta_s = opening - normal_opening;
       delta = tangential_opening_norm * beta;
 
       computeCoupledTraction(traction, normal, delta, delta_s, delta_max,
                              delta_max_prev);
 
       computeCompressiveTraction(traction, normal, normal_opening_norm,
                                  opening);
 
     } else
       computeCoupledTraction(traction, normal, delta, opening, delta_max,
                              delta_max_prev);
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class D1, class D2, class D3>
 void MaterialCohesiveExponential<dim>::computeCoupledTraction(
     Eigen::MatrixBase<D1> & tract, const Eigen::MatrixBase<D2> & normal,
     Real delta, const Eigen::MatrixBase<D3> & opening, Real & delta_max_new,
     Real delta_max) {
   /// full damage case
   if (std::abs(delta) < Math::getTolerance()) {
     /// set traction to zero
     tract.zero();
     return;
   }
 
   /// element not fully damaged
   /**
    * Compute traction loading @f$ \mathbf{T} =
    * e \sigma_c \frac{\delta}{\delta_c} e^{-\delta/ \delta_c}@f$
    */
   /**
    * Compute traction unloading @f$ \mathbf{T} =
    *  \frac{t_{max}}{\delta_{max}} \delta @f$
    */
   Real beta2 = beta * beta;
   Real normal_open_norm = opening.dot(normal);
 
   delta_max_new = std::max(delta_max, delta);
   auto && op_n_n = normal * (1 - beta2) * normal_open_norm;
   tract = (beta2 * opening + op_n_n) * std::exp(1.) * sigma_c *
           std::exp(-delta_max_new / delta_c) / delta_c;
 }
 
 /* ------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class D1, class D2, class D3>
 void MaterialCohesiveExponential<dim>::computeCompressiveTraction(
     Eigen::MatrixBase<D1> & tract, const Eigen::MatrixBase<D2> & normal,
     Real delta_n, const Eigen::MatrixBase<D3> & /*opening*/) {
   Vector<Real> temp_tract(normal);
 
   if (exp_penalty) {
     temp_tract *= delta_n * std::exp(1) * sigma_c *
                   std::exp(-delta_n / delta_c) / delta_c;
   } else {
     Real initial_tg =
         contact_tangent * std::exp(1.) * sigma_c * delta_n / delta_c;
     temp_tract *= initial_tg;
   }
 
   tract += temp_tract;
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialCohesiveExponential<dim>::computeTangentTraction(
     ElementType el_type, Array<Real> & tangent_matrix,
     const Array<Real> & normal, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real beta2 = beta * beta;
 
   /**
    * compute tangent matrix  @f$ \frac{\partial \mathbf{t}}
    * {\partial \delta} = \hat{\mathbf{t}} \otimes
    * \frac{\partial (t/\delta)}{\partial \delta}
    * \frac{\hat{\mathbf{t}}}{\delta}+ \frac{t}{\delta}  [ \beta^2 \mathbf{I} +
    * (1-\beta^2) (\mathbf{n} \otimes \mathbf{n})] @f$
    **/
 
   /**
    * In which @f$
    *  \frac{\partial(t/ \delta)}{\partial \delta} =
    * \left\{\begin{array} {l l}
    *  -e  \frac{\sigma_c}{\delta_c^2  }e^{-\delta  /  \delta_c} &  \quad  if
    *  \delta \geq \delta_{max} \\
    *  0 & \quad if \delta < \delta_{max}, \delta_n > 0
    *  \end{array}\right. @f$
    **/
 
   for (auto && data :
        zip(make_view<dim, dim>(tangent_matrix),
            make_view<dim>(opening(el_type, ghost_type)), make_view<dim>(normal),
            delta_max.previous(el_type, ghost_type))) {
     auto && tangent = std::get<0>(data);
     auto && opening = std::get<1>(data);
     auto && normal = std::get<2>(data);
     auto && delta_max_prev = std::get<3>(data);
 
     Real normal_opening_norm = opening.dot(normal);
 
     auto && normal_opening = normal * normal_opening_norm;
     auto && tangential_opening = opening - normal_opening;
 
     Real tangential_opening_norm = tangential_opening.norm();
 
     auto delta =
         std::sqrt(tangential_opening_norm * tangential_opening_norm * beta2 +
                   normal_opening_norm * normal_opening_norm);
 
     if ((normal_opening_norm < 0) &&
         (std::abs(normal_opening_norm) > Math::getTolerance())) {
 
       auto && delta_s = opening - normal_opening;
       delta = tangential_opening_norm * beta;
 
       computeCoupledTangent(tangent, normal, delta, delta_s, delta_max_prev);
 
       computeCompressivePenalty(tangent, normal, normal_opening_norm);
     } else
       computeCoupledTangent(tangent, normal, delta, opening, delta_max_prev);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class D1, class D2, class D3>
 void MaterialCohesiveExponential<dim>::computeCoupledTangent(
     Eigen::MatrixBase<D1> & tangent, const Eigen::MatrixBase<D2> & normal,
     Real delta, const Eigen::MatrixBase<D3> & opening,
     Real /* delta_max_new */) {
   AKANTU_DEBUG_IN();
 
   auto beta2 = beta * beta;
   auto J = Matrix<Real, dim, dim>::Identity() * beta2;
 
   if (std::abs(delta) < Math::getTolerance()) {
     delta = Math::getTolerance();
   }
 
   auto opening_normal = opening.dot(normal);
 
   auto && delta_e = normal * opening_normal * (1. - beta2) + beta2 * opening;
 
   auto exponent = std::exp(1. - delta / delta_c) * sigma_c / delta_c;
 
   auto && first_term = normal * normal.transpose() * (1. - beta2) + J;
 
   auto && second_term = delta_e * delta_e.transpose() / delta / delta_c;
 
   tangent = (first_term - second_term) * exponent;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class D1, class D2>
 void MaterialCohesiveExponential<dim>::computeCompressivePenalty(
     Eigen::MatrixBase<D1> & tangent, const Eigen::MatrixBase<D2> & normal,
     Real delta_n) {
 
   if (not exp_penalty)
     delta_n = 0.;
   }
 
   auto && n_outer_n = normal * normal.transpose();
 
   auto normal_tg = contact_tangent * std::exp(1.) * sigma_c *
                    std::exp(-delta_n / delta_c) * (1. - delta_n / delta_c) /
                    delta_c;
 
   tangent = tangent + n_outer_n * normal_tg;
 }
 
 INSTANTIATE_MATERIAL(cohesive_exponential, MaterialCohesiveExponential);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
index 077160d59..0d5671eee 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.hh
@@ -1,131 +1,131 @@
 /**
  * @file   material_cohesive_exponential.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Exponential irreversible cohesive law of mixed mode loading
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_cohesive.hh"
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH_
 #define AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH_
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Cohesive material Exponential damage
  *
  * parameters in the material files :
  *   - sigma_c   : critical stress sigma_c  (default: 0)
  *   - beta      : weighting parameter for sliding and normal opening (default:
  * 0)
  *   - delta_c   : critical opening (default: 0)
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialCohesiveExponential : public MaterialCohesive {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialCohesiveExponential(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// Initialization
   void initMaterial() override;
 
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentTraction(ElementType el_type,
                               Array<Real> & tangent_matrix,
                               const Array<Real> & normal,
                               GhostType ghost_type = _not_ghost) override;
 
 private:
   template <class D1, class D2, class D3>
   void computeCoupledTraction(Eigen::MatrixBase<D1> & tract,
                               const Eigen::MatrixBase<D2> & normal, Real delta,
                               const Eigen::MatrixBase<D3> & opening,
                               Real & delta_max_new, Real delta_max);
 
   template <class D1, class D2, class D3>
   void computeCompressiveTraction(Eigen::MatrixBase<D1> & tract,
                                   const Eigen::MatrixBase<D2> & normal,
                                   Real delta_n,
                                   const Eigen::MatrixBase<D3> & opening);
 
   template <class D1, class D2, class D3>
   void computeCoupledTangent(Eigen::MatrixBase<D1> & tangent,
                              const Eigen::MatrixBase<D2> & normal, Real delta,
                              const Eigen::MatrixBase<D3> & opening,
                              Real delta_max_new);
 
   template <class D1, class D2>
   void computeCompressivePenalty(Eigen::MatrixBase<D1> & tangent,
                                  const Eigen::MatrixBase<D2> & normal,
                                  Real delta_n);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// beta parameter
   Real beta;
 
   /// contact penalty = initial slope ?
   bool exp_penalty;
 
   /// Ratio of contact tangent over the initial exponential tangent
   Real contact_tangent;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 // #include "material_cohesive_exponential_inline_impl.hh"
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_COHESIVE_EXPONENTIAL_HH_ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc
index aa859a33e..e71579c96 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc
@@ -1,421 +1,412 @@
 /**
  * @file   material_cohesive_linear.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Feb 22 2012
  * @date last modification: Thu Jan 14 2021
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear.hh"
 #include "dof_synchronizer.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialCohesiveLinear<dim>::MaterialCohesiveLinear(SolidMechanicsModel & model,
                                                     const ID & id)
     : MaterialCohesive(model, id), sigma_c_eff("sigma_c_eff", *this),
       delta_c_eff("delta_c_eff", *this),
       insertion_stress("insertion_stress", *this) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("beta", beta, Real(0.), _pat_parsable | _pat_readable,
                       "Beta parameter");
 
   this->registerParam("G_c", G_c, Real(0.), _pat_parsable | _pat_readable,
                       "Mode I fracture energy");
 
   this->registerParam("penalty", penalty, Real(0.),
                       _pat_parsable | _pat_readable, "Penalty coefficient");
 
   this->registerParam("volume_s", volume_s, Real(0.),
                       _pat_parsable | _pat_readable,
                       "Reference volume for sigma_c scaling");
 
   this->registerParam("m_s", m_s, Real(1.), _pat_parsable | _pat_readable,
                       "Weibull exponent for sigma_c scaling");
 
   this->registerParam("kappa", kappa, Real(1.), _pat_parsable | _pat_readable,
                       "Kappa parameter");
 
   this->registerParam(
       "contact_after_breaking", contact_after_breaking, false,
       _pat_parsable | _pat_readable,
       "Activation of contact when the elements are fully damaged");
 
   this->registerParam("max_quad_stress_insertion", max_quad_stress_insertion,
                       false, _pat_parsable | _pat_readable,
                       "Insertion of cohesive element when stress is high "
                       "enough just on one quadrature point");
 
   this->registerParam("recompute", recompute, false,
                       _pat_parsable | _pat_modifiable, "recompute solution");
 
   this->use_previous_delta_max = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialCohesiveLinear<dim>::initMaterial() {
+template <Int dim> void MaterialCohesiveLinear<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   MaterialCohesive::initMaterial();
 
   sigma_c_eff.initialize(1);
   delta_c_eff.initialize(1);
   insertion_stress.initialize(dim);
 
   if (not Math::are_float_equal(delta_c, 0.)) {
     delta_c_eff.setDefaultValue(delta_c);
   } else {
     delta_c_eff.setDefaultValue(2 * G_c / sigma_c);
   }
 
   if (model->getIsExtrinsic()) {
     scaleInsertionTraction();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialCohesiveLinear<dim>::updateInternalParameters() {
   /// compute scalars
   beta2_kappa2 = beta * beta / kappa / kappa;
   beta2_kappa = beta * beta / kappa;
 
   if (Math::are_float_equal(beta, 0)) {
     beta2_inv = 0;
   } else {
     beta2_inv = 1. / beta / beta;
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void MaterialCohesiveLinear<dim>::scaleInsertionTraction() {
+template <Int dim> void MaterialCohesiveLinear<dim>::scaleInsertionTraction() {
   AKANTU_DEBUG_IN();
 
   // do nothing if volume_s hasn't been specified by the user
   if (Math::are_float_equal(volume_s, 0.)) {
     return;
   }
 
-  const Mesh & mesh_facets = model->getMeshFacets();
+  const auto & mesh_facets = model->getMeshFacets();
   const auto & fe_engine = model->getFEEngine();
   const auto & fe_engine_facet = model->getFEEngine("FacetsFEEngine");
 
   for (auto && type_facet : mesh_facets.elementTypes(dim - 1)) {
-    const Array<std::vector<Element>> & facet_to_element =
+    const auto & facet_to_element =
         mesh_facets.getElementToSubelement(type_facet);
 
-    UInt nb_facet = facet_to_element.size();
-    UInt nb_quad_per_facet = fe_engine_facet.getNbIntegrationPoints(type_facet);
+    auto nb_quad_per_facet = fe_engine_facet.getNbIntegrationPoints(type_facet);
 
-    // iterator to modify sigma_c for all the quadrature points of a facet
-    auto sigma_c_iterator =
-        sigma_c(type_facet).begin_reinterpret(nb_quad_per_facet, nb_facet);
-
-    for (UInt f = 0; f < nb_facet; ++f, ++sigma_c_iterator) {
-      auto && sigma_c = *sigma_c_iterator;
-
-      const std::vector<Element> & element_list = facet_to_element(f);
+    for(auto && data : enumerate(make_view(sigma_c(type_facet), nb_quad_per_facet))) {
+      auto f = std::get<0>(data);
+      auto && sigma_c = std::get<1>(data);
 
       // compute bounding volume
       Real volume = 0;
 
-      auto elem = element_list.begin();
-      auto elem_end = element_list.end();
-
-      for (; elem != elem_end; ++elem) {
-        if (*elem == ElementNull) {
+      for(auto && elem : facet_to_element(f)) {
+          if (elem == ElementNull) {
           continue;
         }
 
         // unit vector for integration in order to obtain the volume
-        UInt nb_quadrature_points =
-            fe_engine.getNbIntegrationPoints(elem->type);
-        Vector<Real> unit_vector(nb_quadrature_points, 1);
+        auto nb_quadrature_points =
+            fe_engine.getNbIntegrationPoints(elem.type);
+        Vector<Real> unit_vector(nb_quadrature_points);
+        unit_vector.fill(1);
 
-        volume += fe_engine.integrate(unit_vector, elem->type, elem->element,
-                                      elem->ghost_type);
+        volume += fe_engine.integrate(unit_vector, elem);
       }
 
       // scale sigma_c
       Vector<Real> base_sigma_c_v(sigma_c.rows());
       sigma_c = (sigma_c.colwise() - base_sigma_c_v) *
                     std::pow(volume_s / volume, 1. / m_s) +
                 base_sigma_c_v;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialCohesiveLinear<dim>::checkInsertion(bool check_only) {
   AKANTU_DEBUG_IN();
 
-  const Mesh & mesh_facets = model->getMeshFacets();
-  CohesiveElementInserter & inserter = model->getElementInserter();
+  const auto & mesh_facets = model->getMeshFacets();
+  auto & inserter = model->getElementInserter();
 
   for (auto && type_facet : mesh_facets.elementTypes(dim - 1)) {
-    ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
+    auto type_cohesive = FEEngine::getCohesiveElementType(type_facet);
 
     const auto & facets_check = inserter.getCheckFacets(type_facet);
     auto & f_insertion = inserter.getInsertionFacets(type_facet);
     auto & f_filter = facet_filter(type_facet);
     auto & sig_c_eff = sigma_c_eff(type_cohesive);
     auto & del_c = delta_c_eff(type_cohesive);
     auto & ins_stress = insertion_stress(type_cohesive);
     auto & trac_old = tractions.previous(type_cohesive);
     const auto & f_stress = model->getStressOnFacets(type_facet);
     const auto & sigma_lim = sigma_c(type_facet);
 
-    UInt nb_quad_facet =
+    auto nb_quad_facet =
         model->getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
 
 #ifndef AKANTU_NDEBUG
-    UInt nb_quad_cohesive = model->getFEEngine("CohesiveFEEngine")
+    auto nb_quad_cohesive = model->getFEEngine("CohesiveFEEngine")
                                 .getNbIntegrationPoints(type_cohesive);
 
     AKANTU_DEBUG_ASSERT(nb_quad_cohesive == nb_quad_facet,
                         "The cohesive element and the corresponding facet do "
                         "not have the same numbers of integration points");
 #endif
 
-    UInt nb_facet = f_filter.size();
+    auto nb_facet = f_filter.size();
     //  if (nb_facet == 0) continue;
 
     auto sigma_lim_it = sigma_lim.begin();
 
-    Matrix<Real> stress_tmp(dim, dim);
+    Matrix<Real, dim, dim> stress_tmp;
     Matrix<Real> normal_traction(dim, nb_quad_facet);
     Vector<Real> stress_check(nb_quad_facet);
-    UInt sp2 = dim * dim;
+    auto sp2 = dim * dim;
 
     const auto & tangents = model->getTangents(type_facet);
     const auto & normals = model->getFEEngine("FacetsFEEngine")
                                .getNormalsOnIntegrationPoints(type_facet);
     auto normal_begin = make_view<dim>(normals).begin();
-    auto tangent_begin = tangents.begin(tangents.getNbComponent());
-    auto facet_stress_begin = f_stress.begin(dim, dim * 2);
+    auto tangent_begin = make_view<dim, dim == 3 ? 2 : 1>(tangents).begin();
+    auto facet_stress_begin = make_view<dim, dim * 2>(f_stress).begin();
 
     std::vector<Real> new_sigmas;
     std::vector<Vector<Real>> new_normal_traction;
     std::vector<Real> new_delta_c;
 
     // loop over each facet belonging to this material
-    for (UInt f = 0; f < nb_facet; ++f, ++sigma_lim_it) {
-      UInt facet = f_filter(f);
+    for (Int f = 0; f < nb_facet; ++f, ++sigma_lim_it) {
+      auto facet = f_filter(f);
       // skip facets where check shouldn't be realized
       if (!facets_check(facet)) {
         continue;
       }
 
       // compute the effective norm on each quadrature point of the facet
-      for (UInt q = 0; q < nb_quad_facet; ++q) {
-        UInt current_quad = facet * nb_quad_facet + q;
+      for (Int q = 0; q < nb_quad_facet; ++q) {
+        auto current_quad = facet * nb_quad_facet + q;
         auto && normal = normal_begin[current_quad];
         auto && tangent = tangent_begin[current_quad];
         auto && facet_stress_it = facet_stress_begin[current_quad];
 
         // compute average stress on the current quadrature point
         MatrixProxy<const Real, dim, dim> stress_1(facet_stress_it.data());
         MatrixProxy<const Real, dim, dim> stress_2(facet_stress_it.data() +
                                                    sp2);
 
         auto && stress_avg = (stress_1 + stress_2) / 2.;
 
         // compute normal and effective stress
         stress_check(q) = computeEffectiveNorm(stress_avg, normal, tangent,
                                                normal_traction(q));
       }
 
       // verify if the effective stress overcomes the threshold
-      Real final_stress = stress_check.mean();
+      auto final_stress = stress_check.mean();
       if (max_quad_stress_insertion) {
         final_stress = *std::max_element(
             stress_check.data(), stress_check.data() + nb_quad_facet);
       }
 
       if (final_stress > *sigma_lim_it) {
         f_insertion(facet) = true;
 
         if (check_only) {
           continue;
         }
 
         // store the new cohesive material parameters for each quadrature
         // point
-        for (UInt q = 0; q < nb_quad_facet; ++q) {
-          Real new_sigma = stress_check(q);
-          Vector<Real> normal_traction_vec(normal_traction(q));
+        for (Int q = 0; q < nb_quad_facet; ++q) {
+          auto new_sigma = stress_check(q);
+          auto && normal_traction_vec = normal_traction(q);
 
           if (dim != 3) {
             normal_traction_vec *= -1.;
           }
 
           new_sigmas.push_back(new_sigma);
           new_normal_traction.push_back(normal_traction_vec);
 
           Real new_delta;
 
           // set delta_c in function of G_c or a given delta_c value
           if (Math::are_float_equal(delta_c, 0.)) {
             new_delta = 2 * G_c / new_sigma;
           } else {
             new_delta = (*sigma_lim_it) / new_sigma * delta_c;
           }
 
           new_delta_c.push_back(new_delta);
         }
       }
     }
 
     // update material data for the new elements
-    UInt old_nb_quad_points = sig_c_eff.size();
-    UInt new_nb_quad_points = new_sigmas.size();
+    auto old_nb_quad_points = sig_c_eff.size();
+    auto new_nb_quad_points = new_sigmas.size();
     sig_c_eff.resize(old_nb_quad_points + new_nb_quad_points);
     ins_stress.resize(old_nb_quad_points + new_nb_quad_points);
     trac_old.resize(old_nb_quad_points + new_nb_quad_points);
     del_c.resize(old_nb_quad_points + new_nb_quad_points);
 
     for (UInt q = 0; q < new_nb_quad_points; ++q) {
       sig_c_eff(old_nb_quad_points + q) = new_sigmas[q];
       del_c(old_nb_quad_points + q) = new_delta_c[q];
-      for (UInt d = 0; d < dim; ++d) {
+      for (Int d = 0; d < dim; ++d) {
         ins_stress(old_nb_quad_points + q, d) = new_normal_traction[q](d);
         trac_old(old_nb_quad_points + q, d) = new_normal_traction[q](d);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialCohesiveLinear<dim>::computeTraction(const Array<Real> & normal,
                                                   ElementType el_type,
                                                   GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto traction_it = tractions(el_type, ghost_type).begin(dim);
   auto opening_it = opening(el_type, ghost_type).begin(dim);
   auto contact_traction_it = contact_tractions(el_type, ghost_type).begin(dim);
   auto contact_opening_it = contact_opening(el_type, ghost_type).begin(dim);
 
   auto normal_it = normal.begin(dim);
   auto traction_end = tractions(el_type, ghost_type).end(dim);
   auto sigma_c_it = sigma_c_eff(el_type, ghost_type).begin();
   auto delta_max_it = delta_max(el_type, ghost_type).begin();
   auto delta_c_it = delta_c_eff(el_type, ghost_type).begin();
   auto damage_it = damage(el_type, ghost_type).begin();
   auto insertion_stress_it = insertion_stress(el_type, ghost_type).begin(dim);
 
   Vector<Real> normal_opening(dim);
   Vector<Real> tangential_opening(dim);
 
   /// loop on each quadrature point
   for (; traction_it != traction_end;
        ++traction_it, ++opening_it, ++normal_it, ++sigma_c_it, ++delta_max_it,
        ++delta_c_it, ++damage_it, ++contact_traction_it, ++insertion_stress_it,
        ++contact_opening_it) {
     Real normal_opening_norm{0};
     Real tangential_opening_norm{0};
     bool penetration{false};
     this->computeTractionOnQuad(
         *traction_it, *opening_it, *normal_it, *delta_max_it, *delta_c_it,
         *insertion_stress_it, *sigma_c_it, normal_opening, tangential_opening,
         normal_opening_norm, tangential_opening_norm, *damage_it, penetration,
         *contact_traction_it, *contact_opening_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialCohesiveLinear<dim>::computeTangentTraction(
     ElementType el_type, Array<Real> & tangent_matrix,
     const Array<Real> & normal, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto tangent_it = tangent_matrix.begin(dim, dim);
 
   auto tangent_end = tangent_matrix.end(dim, dim);
 
   auto normal_it = normal.begin(dim);
 
   auto opening_it = opening(el_type, ghost_type).begin(dim);
 
   /// NB: delta_max_it points on delta_max_previous, i.e. the
   /// delta_max related to the solution of the previous incremental
   /// step
   auto delta_max_it = delta_max.previous(el_type, ghost_type).begin();
   auto sigma_c_it = sigma_c_eff(el_type, ghost_type).begin();
   auto delta_c_it = delta_c_eff(el_type, ghost_type).begin();
   auto damage_it = damage(el_type, ghost_type).begin();
   auto contact_opening_it = contact_opening(el_type, ghost_type).begin(dim);
 
   Vector<Real> normal_opening(dim);
   Vector<Real> tangential_opening(dim);
 
   for (; tangent_it != tangent_end; ++tangent_it, ++normal_it, ++opening_it,
                                     ++delta_max_it, ++sigma_c_it, ++delta_c_it,
                                     ++damage_it, ++contact_opening_it) {
     Real normal_opening_norm{0};
     Real tangential_opening_norm{0};
     bool penetration{false};
     this->computeTangentTractionOnQuad(
         *tangent_it, *delta_max_it, *delta_c_it, *sigma_c_it, *opening_it,
         *normal_it, normal_opening, tangential_opening, normal_opening_norm,
         tangential_opening_norm, *damage_it, penetration, *contact_opening_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear, MaterialCohesiveLinear);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh
index 22f2e2a80..b24e6da9e 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh
@@ -1,196 +1,196 @@
 /**
  * @file   material_cohesive_linear.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Mon Sep 14 2020
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_MATERIAL_COHESIVE_LINEAR_HH_
 #define AKANTU_MATERIAL_COHESIVE_LINEAR_HH_
 
 namespace akantu {
 
 /**
  * Cohesive material linear damage for extrinsic case
  *
  * parameters in the material files :
  *   - sigma_c   : critical stress sigma_c  (default: 0)
  *   - beta      : weighting parameter for sliding and normal opening (default:
  * 0)
  *   - G_cI      : fracture energy for mode I (default: 0)
  *   - G_cII     : fracture energy for mode II (default: 0)
  *   - penalty   : stiffness in compression to prevent penetration
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialCohesiveLinear : public MaterialCohesive {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialCohesiveLinear(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material parameters
   void initMaterial() override;
 
   void updateInternalParameters() override;
 
   /// check stress for cohesive elements' insertion
   void checkInsertion(bool check_only = false) override;
 
   /// compute effective stress norm for insertion check
   template <class D1, class D2, class D3, class D4>
   Real computeEffectiveNorm(const Eigen::MatrixBase<D1> & stress,
                             const Eigen::MatrixBase<D2> & normal,
                             const Eigen::MatrixBase<D3> & tangent,
                             const Eigen::MatrixBase<D4> & normal_stress) const;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /// compute tangent stiffness matrix
   void computeTangentTraction(ElementType el_type,
                               Array<Real> & tangent_matrix,
                               const Array<Real> & normal,
                               GhostType ghost_type) override;
 
   /**
    * Scale insertion traction sigma_c according to the volume of the
    * two elements surrounding a facet
    *
    * see the article: F. Zhou and J. F. Molinari "Dynamic crack
    * propagation with cohesive elements: a methodology to address mesh
    * dependency" International Journal for Numerical Methods in
    * Engineering (2004)
    */
   void scaleInsertionTraction();
 
   /// compute the traction for a given quadrature point
   template <class D1, class D2, class D3, class D4, class D5, class D6,
             class D7, class D8>
   inline void computeTractionOnQuad(
       Eigen::MatrixBase<D1> & traction, Eigen::MatrixBase<D2> & opening,
       const Eigen::MatrixBase<D3> & normal, Real & delta_max,
       const Real & delta_c, const Eigen::MatrixBase<D4> & insertion_stress,
       const Real & sigma_c, Eigen::MatrixBase<D5> & normal_opening,
       Eigen::MatrixBase<D6> & tangential_opening, Real & normal_opening_norm,
       Real & tangential_opening_norm, Real & damage, bool & penetration,
       Eigen::MatrixBase<D7> & contact_traction,
       Eigen::MatrixBase<D8> & contact_opening) const;
 
   template <class D1, class D2, class D3, class D4, class D5, class D6>
   inline void computeTangentTractionOnQuad(
       Eigen::MatrixBase<D1> & tangent, Real & delta_max, const Real & delta_c,
       const Real & sigma_c, Eigen::MatrixBase<D2> & opening,
       const Eigen::MatrixBase<D3> & normal,
       Eigen::MatrixBase<D4> & normal_opening,
       Eigen::MatrixBase<D5> & tangential_opening, Real & normal_opening_norm,
       Real & tangential_opening_norm, Real & damage, bool & penetration,
       Eigen::MatrixBase<D6> & contact_opening) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get sigma_c_eff
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(InsertionTraction, sigma_c_eff, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// beta parameter
   Real beta;
 
   /// beta square inverse to compute effective norm
   Real beta2_inv;
 
   /// mode I fracture energy
   Real G_c;
 
   /// kappa parameter
   Real kappa;
 
   /// constitutive law scalar to compute delta
   Real beta2_kappa2;
 
   /// constitutive law scalar to compute traction
   Real beta2_kappa;
 
   /// penalty coefficient
   Real penalty;
 
   /// reference volume used to scale sigma_c
   Real volume_s;
 
   /// weibull exponent used to scale sigma_c
   Real m_s;
 
   /// variable defining if we are recomputing the last loading step
   /// after load_reduction
   bool recompute;
 
   /// critical effective stress
   RandomInternalField<Real, CohesiveInternalField> sigma_c_eff;
 
   /// effective critical displacement (each element can have a
   /// different value)
   CohesiveInternalField<Real> delta_c_eff;
 
   /// stress at insertion
   CohesiveInternalField<Real> insertion_stress;
 
   /// variable saying if there should be penalty contact also after
   /// breaking the cohesive elements
   bool contact_after_breaking;
 
   /// insertion of cohesive element when stress is high enough just on
   /// one quadrature point
   bool max_quad_stress_insertion;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 #include "material_cohesive_linear_inline_impl.hh"
 
 #endif /* AKANTU_MATERIAL_COHESIVE_LINEAR_HH_ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
index df3b83375..40d3eea93 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
@@ -1,306 +1,304 @@
 /**
  * @file   material_cohesive_linear_fatigue.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Feb 20 2015
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  See material_cohesive_linear_fatigue.hh for information
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear_fatigue.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 MaterialCohesiveLinearFatigue<spatial_dimension>::MaterialCohesiveLinearFatigue(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesiveLinear<spatial_dimension>(model, id),
       delta_prec("delta_prec", *this), K_plus("K_plus", *this),
       K_minus("K_minus", *this), T_1d("T_1d", *this),
       switches("switches", *this), delta_dot_prec("delta_dot_prec", *this),
       normal_regime("normal_regime", *this) {
 
   this->registerParam("delta_f", delta_f, Real(-1.),
                       _pat_parsable | _pat_readable, "delta_f");
 
   this->registerParam("progressive_delta_f", progressive_delta_f, false,
                       _pat_parsable | _pat_readable,
                       "Whether or not delta_f is equal to delta_max");
 
   this->registerParam("count_switches", count_switches, false,
                       _pat_parsable | _pat_readable,
                       "Count the opening/closing switches per element");
 
   this->registerParam(
       "fatigue_ratio", fatigue_ratio, Real(1.), _pat_parsable | _pat_readable,
       "What portion of the cohesive law is subjected to fatigue");
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialCohesiveLinearFatigue<spatial_dimension>::initMaterial() {
   MaterialCohesiveLinear<spatial_dimension>::initMaterial();
 
   // check that delta_f has a proper value or assign a defaul value
   if (delta_f < 0) {
     delta_f = this->delta_c_eff;
   } else if (delta_f < this->delta_c_eff) {
     AKANTU_ERROR("Delta_f must be greater or equal to delta_c");
   }
 
   delta_prec.initialize(1);
   K_plus.initialize(1);
   K_minus.initialize(1);
   T_1d.initialize(1);
   normal_regime.initialize(1);
 
   if (count_switches) {
     switches.initialize(1);
     delta_dot_prec.initialize(1);
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 void MaterialCohesiveLinearFatigue<spatial_dimension>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto traction_it =
       this->tractions(el_type, ghost_type).begin(spatial_dimension);
 
   auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto contact_traction_it =
       this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
 
   auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto normal_it = normal.begin(spatial_dimension);
 
   auto traction_end =
       this->tractions(el_type, ghost_type).end(spatial_dimension);
 
   const Array<Real> & sigma_c_array = this->sigma_c_eff(el_type, ghost_type);
   Array<Real> & delta_max_array = this->delta_max(el_type, ghost_type);
   const Array<Real> & delta_c_array = this->delta_c_eff(el_type, ghost_type);
   Array<Real> & damage_array = this->damage(el_type, ghost_type);
 
   auto insertion_stress_it =
       this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
 
   Array<Real> & delta_prec_array = delta_prec(el_type, ghost_type);
   Array<Real> & K_plus_array = K_plus(el_type, ghost_type);
   Array<Real> & K_minus_array = K_minus(el_type, ghost_type);
   Array<Real> & T_1d_array = T_1d(el_type, ghost_type);
   Array<bool> & normal_regime_array = normal_regime(el_type, ghost_type);
 
   Array<UInt> * switches_array = nullptr;
   Array<Real> * delta_dot_prec_array = nullptr;
 
   if (count_switches) {
     switches_array = &switches(el_type, ghost_type);
     delta_dot_prec_array = &delta_dot_prec(el_type, ghost_type);
   }
 
-  auto * memory_space = new Real[2 * spatial_dimension];
-  Vector<Real> normal_opening(memory_space, spatial_dimension);
-  Vector<Real> tangential_opening(memory_space + spatial_dimension,
-                                  spatial_dimension);
+
+  Vector<Real, spatial_dimension> normal_opening;
+  Vector<Real, spatial_dimension> tangential_opening;
 
   Real tolerance = Math::getTolerance();
 
   /// loop on each quadrature point
   for (UInt q = 0; traction_it != traction_end; ++traction_it, ++opening_it,
             ++normal_it, ++contact_traction_it, ++insertion_stress_it,
             ++contact_opening_it, ++q) {
 
     /// compute normal and tangential opening vectors
     Real normal_opening_norm = opening_it->dot(*normal_it);
     normal_opening = (*normal_it);
     normal_opening *= normal_opening_norm;
 
     tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
 
     Real tangential_opening_norm = tangential_opening.norm();
 
     /**
      * compute effective opening displacement
      * @f$ \delta = \sqrt{
      * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
      */
     Real delta =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
     bool penetration = normal_opening_norm < -tolerance;
     if (not this->contact_after_breaking and
         Math::are_float_equal(damage_array(q), 1.)) {
       penetration = false;
     }
 
     if (penetration) {
       /// use penalty coefficient in case of penetration
       *contact_traction_it = normal_opening;
       *contact_traction_it *= this->penalty;
       *contact_opening_it = normal_opening;
       /// don't consider penetration contribution for delta
       *opening_it = tangential_opening;
       normal_opening.zero();
     } else {
       delta += normal_opening_norm * normal_opening_norm;
       contact_traction_it->zero();
       contact_opening_it->zero();
     }
 
     delta = std::sqrt(delta);
 
     /**
      * Compute traction @f$ \mathbf{T} = \left(
      * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
      * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
      * \frac{\delta}{\delta_c} \right)@f$
      */
 
     // update maximum displacement and damage
     delta_max_array(q) = std::max(delta, delta_max_array(q));
     damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
 
     Real delta_dot = delta - delta_prec_array(q);
 
     // count switches if asked
     if (count_switches) {
       if ((delta_dot > 0. && (*delta_dot_prec_array)(q) <= 0.) ||
           (delta_dot < 0. && (*delta_dot_prec_array)(q) >= 0.)) {
         ++((*switches_array)(q));
       }
 
       (*delta_dot_prec_array)(q) = delta_dot;
     }
 
     // set delta_f equal to delta_max if desired
     if (progressive_delta_f) {
       delta_f = delta_max_array(q);
     }
 
     // broken element case
     if (Math::are_float_equal(damage_array(q), 1.)) {
       traction_it->zero();
       // just inserted element case
     } else if (Math::are_float_equal(damage_array(q), 0.)) {
       if (penetration) {
         traction_it->zero();
       } else {
         *traction_it = *insertion_stress_it;
       }
       // initialize the 1d traction to sigma_c
       T_1d_array(q) = sigma_c_array(q);
     }
     // normal case
     else {
       // if element is closed then there are zero tractions
       if (delta <= tolerance) {
         traction_it->zero();
         // otherwise compute new tractions if the new delta is different
         // than the previous one
       } else if (std::abs(delta_dot) > tolerance) {
         // loading case
         if (delta_dot > 0.) {
           if (!normal_regime_array(q)) {
             // equation (4) of the article
             K_plus_array(q) *= 1. - delta_dot / delta_f;
             // equivalent to equation (2) of the article
             T_1d_array(q) += K_plus_array(q) * delta_dot;
 
             // in case of reloading, traction must not exceed that of the
             // envelop of the cohesive law
             Real max_traction =
                 sigma_c_array(q) * (1 - delta / delta_c_array(q));
             bool max_traction_exceeded = T_1d_array(q) > max_traction;
             if (max_traction_exceeded) {
               T_1d_array(q) = max_traction;
             }
 
             // switch to standard linear cohesive law
             if (delta_max_array(q) > fatigue_ratio * delta_c_array(q)) {
               // reset delta_max to avoid big jumps in the traction
               delta_max_array(q) =
                   sigma_c_array(q) /
                   (T_1d_array(q) / delta + sigma_c_array(q) / delta_c_array(q));
               damage_array(q) =
                   std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
               K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) *
                                  (1. - damage_array(q));
               normal_regime_array(q) = true;
             } else {
               // equation (3) of the article
               K_minus_array(q) = T_1d_array(q) / delta;
 
               // if the traction is following the cohesive envelop, then
               // K_plus has to be reset
               if (max_traction_exceeded) {
                 K_plus_array(q) = K_minus_array(q);
               }
             }
           } else {
             // compute stiffness according to the standard law
             K_minus_array(q) =
                 sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
           }
         }
         // unloading case
         else if (!normal_regime_array(q)) {
           // equation (4) of the article
           K_plus_array(q) +=
               (K_plus_array(q) - K_minus_array(q)) * delta_dot / delta_f;
           // equivalent to equation (2) of the article
           T_1d_array(q) = K_minus_array(q) * delta;
         }
 
         // applying the actual stiffness
         *traction_it = tangential_opening;
         *traction_it *= this->beta2_kappa;
         *traction_it += normal_opening;
         *traction_it *= K_minus_array(q);
       }
     }
 
     // update precendent delta
     delta_prec_array(q) = delta;
   }
 
-  delete[] memory_space;
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear_fatigue, MaterialCohesiveLinearFatigue);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
index da9255785..af25ca4d4 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.hh
@@ -1,133 +1,133 @@
 /**
  * @file   material_cohesive_linear_fatigue.hh
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Linear irreversible cohesive law with dissipative
  * unloading-reloading cycles
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "material_cohesive_linear.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH_
 #define AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH_
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Linear irreversible cohesive law with dissipative
  * unloading-reloading cycles
  *
  * This law uses two different stiffnesses during unloading and
  * reloading. The implementation is based on the article entitled "A
  * cohesive model for fatigue crack growth" by Nguyen, Repetto, Ortiz
  * and Radovitzky (2001). This law is identical to the
  * MaterialCohesiveLinear one except for the unloading-reloading
  * phase.
  *
  * input parameter:
  *
  * - delta_f : it must be greater than delta_c and it is inversely
  *      proportional to the dissipation in the unloading-reloading
  *      cycles (default: delta_c)
  */
 
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialCohesiveLinearFatigue
     : public MaterialCohesiveLinear<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialCohesiveLinearFatigue(SolidMechanicsModel & model,
                                 const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material parameters
   void initMaterial() override;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the switches
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Switches, switches, UInt);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// delta_f parameter
   Real delta_f;
 
   /// variable saying if delta_f is equal to delta_max for each
   /// element when the traction is computed
   bool progressive_delta_f;
 
   /// count the opening/closing switches per element
   bool count_switches;
 
   /// delta of the previous step
   CohesiveInternalField<Real> delta_prec;
 
   /// stiffness for reloading
   CohesiveInternalField<Real> K_plus;
 
   /// stiffness for unloading
   CohesiveInternalField<Real> K_minus;
 
   /// 1D traction in the cohesive law
   CohesiveInternalField<Real> T_1d;
 
   /// Number of opening/closing switches
   CohesiveInternalField<UInt> switches;
 
   /// delta increment of the previous time step
   CohesiveInternalField<Real> delta_dot_prec;
 
   /// has the element passed to normal regime (not in fatigue anymore)
   CohesiveInternalField<bool> normal_regime;
 
   /// ratio indicating until what point fatigue is applied in the cohesive law
   Real fatigue_ratio;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_COHESIVE_LINEAR_FATIGUE_HH_ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
index 9fba55f1b..9c388a7dc 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
@@ -1,277 +1,277 @@
 /**
  * @file   material_cohesive_linear_friction.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Tue Jan 12 2016
  * @date last modification: Fri Dec 11 2020
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear_friction.hh"
 #include "solid_mechanics_model_cohesive.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 MaterialCohesiveLinearFriction<dim>::
     MaterialCohesiveLinearFriction(SolidMechanicsModel & model, const ID & id)
     : MaterialParent(model, id), residual_sliding("residual_sliding", *this),
       friction_force("friction_force", *this) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("mu", mu_max, Real(0.), _pat_parsable | _pat_readable,
                       "Maximum value of the friction coefficient");
 
   this->registerParam("penalty_for_friction", friction_penalty, Real(0.),
                       _pat_parsable | _pat_readable,
                       "Penalty parameter for the friction behavior");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialCohesiveLinearFriction<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   MaterialParent::initMaterial();
 
   friction_force.initialize(dim);
   residual_sliding.initialize(1);
   residual_sliding.initializeHistory();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialCohesiveLinearFriction<dim>::computeTraction(
     __attribute__((unused)) const Array<Real> & normal, ElementType el_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   residual_sliding.resize();
   friction_force.resize();
 
   /// define iterators
   auto traction_it =
       this->tractions(el_type, ghost_type).begin(dim);
   auto traction_end =
       this->tractions(el_type, ghost_type).end(dim);
   auto opening_it = this->opening(el_type, ghost_type).begin(dim);
   auto previous_opening_it =
       this->opening.previous(el_type, ghost_type).begin(dim);
   auto contact_traction_it =
       this->contact_tractions(el_type, ghost_type).begin(dim);
   auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(dim);
   auto normal_it = this->normal.begin(dim);
   auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
   auto delta_max_it = this->delta_max(el_type, ghost_type).begin();
   auto delta_max_prev_it =
       this->delta_max.previous(el_type, ghost_type).begin();
   auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
   auto damage_it = this->damage(el_type, ghost_type).begin();
   auto insertion_stress_it =
       this->insertion_stress(el_type, ghost_type).begin(dim);
   auto res_sliding_it = this->residual_sliding(el_type, ghost_type).begin();
   auto res_sliding_prev_it =
       this->residual_sliding.previous(el_type, ghost_type).begin();
   auto friction_force_it =
       this->friction_force(el_type, ghost_type).begin(dim);
 
   Vector<Real> normal_opening(dim);
   Vector<Real> tangential_opening(dim);
 
   if (not this->model->isDefaultSolverExplicit()) {
     this->delta_max(el_type, ghost_type)
         .copy(this->delta_max.previous(el_type, ghost_type));
   }
 
   /// loop on each quadrature point
   for (; traction_it != traction_end;
        ++traction_it, ++opening_it, ++normal_it, ++sigma_c_it, ++delta_max_it,
        ++delta_c_it, ++damage_it, ++contact_traction_it, ++insertion_stress_it,
        ++contact_opening_it, ++delta_max_prev_it, ++res_sliding_it,
        ++res_sliding_prev_it, ++friction_force_it, ++previous_opening_it) {
 
     Real normal_opening_norm;
     Real tangential_opening_norm;
     bool penetration;
     this->computeTractionOnQuad(
         *traction_it, *opening_it, *normal_it, *delta_max_it, *delta_c_it,
         *insertion_stress_it, *sigma_c_it, normal_opening, tangential_opening,
         normal_opening_norm, tangential_opening_norm, *damage_it, penetration,
         *contact_traction_it, *contact_opening_it);
 
     if (penetration) {
       /// the friction coefficient mu increases with the damage. It
       /// equals the maximum value when damage = 1.
       //      Real damage = std::min(*delta_max_prev_it / *delta_c_it,
       //      Real(1.));
       Real mu = mu_max; // * damage;
 
       /// the definition of tau_max refers to the opening
       /// (penetration) of the previous incremental step
 
       Real tau_max = mu * this->penalty * (std::abs(normal_opening_norm));
       Real delta_sliding_norm =
           std::abs(tangential_opening_norm - *res_sliding_prev_it);
 
       /// tau is the norm of the friction force, acting tangentially to the
       /// surface
       Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
 
       if ((tangential_opening_norm - *res_sliding_prev_it) < 0.0) {
         tau = -tau;
       }
 
       /// from tau get the x and y components of friction, to be added in the
       /// force vector
       Vector<Real> tangent_unit_vector(dim);
       tangent_unit_vector = tangential_opening / tangential_opening_norm;
       *friction_force_it = tau * tangent_unit_vector;
 
       /// update residual_sliding
       if (friction_penalty == 0.) {
         *res_sliding_it =
             tangential_opening_norm;
       } else {
         *res_sliding_it =
             tangential_opening_norm - (std::abs(tau) / friction_penalty);
       }
     } else {
       friction_force_it->zero();
     }
 
     *traction_it += *friction_force_it;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void MaterialCohesiveLinearFriction<dim>::computeTangentTraction(
     ElementType el_type, Array<Real> & tangent_matrix,
     const Array<Real> & /*normal*/, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto tangent_it = tangent_matrix.begin(dim, dim);
   auto tangent_end = tangent_matrix.end(dim, dim);
 
   auto normal_it = this->normal.begin(dim);
 
   auto opening_it = this->opening(el_type, ghost_type).begin(dim);
   auto previous_opening_it =
       this->opening.previous(el_type, ghost_type).begin(dim);
 
   /**
    * NB: delta_max_it points on delta_max_previous, i.e. the
    * delta_max related to the solution of the previous incremental
    * step
    */
   auto delta_max_it = this->delta_max.previous(el_type, ghost_type).begin();
   auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
   auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
   auto damage_it = this->damage(el_type, ghost_type).begin();
 
   auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(dim);
 
   auto res_sliding_prev_it =
       this->residual_sliding.previous(el_type, ghost_type).begin();
 
   Vector<Real> normal_opening(dim);
   Vector<Real> tangential_opening(dim);
 
   for (; tangent_it != tangent_end;
        ++tangent_it, ++normal_it, ++opening_it, ++previous_opening_it,
        ++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
        ++contact_opening_it, ++res_sliding_prev_it) {
 
     Real normal_opening_norm;
     Real tangential_opening_norm;
     bool penetration;
     this->computeTangentTractionOnQuad(
         *tangent_it, *delta_max_it, *delta_c_it, *sigma_c_it, *opening_it,
         *normal_it, normal_opening, tangential_opening, normal_opening_norm,
         tangential_opening_norm, *damage_it, penetration, *contact_opening_it);
 
     if (penetration) {
       //      Real damage = std::min(*delta_max_it / *delta_c_it, Real(1.));
       Real mu = mu_max; // * damage;
 
       Real normal_opening_prev_norm =
           std::min(previous_opening_it->dot(*normal_it), Real(0.));
       //      Vector<Real> normal_opening_prev = (*normal_it);
       //      normal_opening_prev *= normal_opening_prev_norm;
 
       Real tau_max = mu * this->penalty * (std::abs(normal_opening_prev_norm));
       Real delta_sliding_norm =
           std::abs(tangential_opening_norm - *res_sliding_prev_it);
 
       // tau is the norm of the friction force, acting tangentially to the
       // surface
       Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
 
       if (tau < tau_max && tau_max > Math::getTolerance()) {
         auto && I = Matrix<Real, dim, dim>::Identity();
         auto && n =  *normal_it;
         *tangent_it += (I - n * n.transpose()) * friction_penalty;
       }
     }
 
     // check if the tangential stiffness matrix is symmetric
     //    for (UInt h = 0; h < dim; ++h){
     //      for (UInt l = h; l < dim; ++l){
     //        if (l > h){
     //          Real k_ls = (*tangent_it)[dim*h+l];
     //          Real k_us =  (*tangent_it)[dim*l+h];
     //          //          std::cout << "k_ls = " << k_ls << std::endl;
     //          //          std::cout << "k_us = " << k_us << std::endl;
     //          if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
     //            Real error = std::abs((k_ls - k_us) / k_us);
     //            if (error > 1e-10){
     //	      std::cout << "non symmetric cohesive matrix" << std::endl;
     //	      //  std::cout << "error " << error << std::endl;
     //            }
     //          }
     //        }
     //      }
     //    }
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear_friction, MaterialCohesiveLinearFriction);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
index fa6de4a8f..54aee23eb 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.hh
@@ -1,106 +1,106 @@
 /**
  * @file   material_cohesive_linear_friction.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Tue Apr 28 2020
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "material_cohesive_linear.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH_
 #define AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH_
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Cohesive material linear with friction force
  *
  * parameters in the material files :
  *   - mu   : friction coefficient
  *   - penalty_for_friction : Penalty parameter for the friction behavior
  */
-template <UInt spatial_dimension>
+template <Int spatial_dimension>
 class MaterialCohesiveLinearFriction
     : public MaterialCohesiveLinear<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   using MaterialParent = MaterialCohesiveLinear<spatial_dimension>;
 
 public:
   MaterialCohesiveLinearFriction(SolidMechanicsModel & model,
                                  const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material parameters
   void initMaterial() override;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /// compute tangent stiffness matrix
   void computeTangentTraction(ElementType el_type,
                               Array<Real> & tangent_matrix,
                               const Array<Real> & normal,
                               GhostType ghost_type) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// maximum value of the friction coefficient
   Real mu_max;
 
   /// penalty parameter for the friction law
   Real friction_penalty;
 
   /// history parameter for the friction law
   CohesiveInternalField<Real> residual_sliding;
 
   /// friction force
   CohesiveInternalField<Real> friction_force;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_COHESIVE_LINEAR_FRICTION_HH_ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.hh
index 725d35ff9..2fa46b04d 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.hh
@@ -1,255 +1,261 @@
 /**
  * @file   material_cohesive_linear_inline_impl.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Apr 22 2015
  * @date last modification: Thu Jan 14 2021
  *
  * @brief  Inline functions of the MaterialCohesiveLinear
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 //#include "material_cohesive_linear.hh"
 #include "solid_mechanics_model_cohesive.hh"
+#include "aka_static_if.hh"
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_HH_
 #define AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_HH_
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class D1, class D2, class D3, class D4>
 Real MaterialCohesiveLinear<dim>::computeEffectiveNorm(
     const Eigen::MatrixBase<D1> & stress, const Eigen::MatrixBase<D2> & normal,
     const Eigen::MatrixBase<D3> & tangent,
     const Eigen::MatrixBase<D4> & normal_traction_) const {
-  Eigen::MatrixBase<D4>& normal_traction = const_cast< Eigen::MatrixBase<D4>& >(normal_traction_);
+  Eigen::MatrixBase<D4> & normal_traction =
+      const_cast<Eigen::MatrixBase<D4> &>(normal_traction_);
   normal_traction = stress * normal;
 
   Real normal_contrib = normal_traction.dot(normal);
 
   /// in 3D tangential components must be summed
   Real tangent_contrib = 0;
 
-  if (dim == 2) {
-    Real tangent_contrib_tmp = normal_traction.dot(tangent);
-    tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
-  }
-  if (dim == 3) {
-    for (auto && tangent_v : tangent) {
-      Real tangent_contrib_tmp = normal_traction.dot(tangent_v);
-      tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
-    }
-  }
+  static_if(aka::bool_constant<dim == 2>{})
+      .then([&tangent_contrib, &normal_traction](auto && tangent) {
+        Real tangent_contrib_tmp = normal_traction.dot(tangent);
+        tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
+      })
+      .else_if(aka::bool_constant<dim == 3>{})
+      .then([&tangent_contrib, &normal_traction](auto && tangent) {
+        for (auto && tangent_v : tangent) {
+          Real tangent_contrib_tmp = normal_traction.dot(tangent_v);
+          tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
+        }
+      })(tangent);
 
   tangent_contrib = std::sqrt(tangent_contrib);
   normal_contrib = std::max(Real(0.), normal_contrib);
 
   return std::sqrt(normal_contrib * normal_contrib +
                    tangent_contrib * tangent_contrib * beta2_inv);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class D1, class D2, class D3, class D4, class D5, class D6, class D7,
           class D8>
 inline void MaterialCohesiveLinear<dim>::computeTractionOnQuad(
     Eigen::MatrixBase<D1> & traction, Eigen::MatrixBase<D2> & opening,
     const Eigen::MatrixBase<D3> & normal, Real & delta_max,
     const Real & delta_c, const Eigen::MatrixBase<D4> & insertion_stress,
     const Real & sigma_c, Eigen::MatrixBase<D5> & normal_opening,
     Eigen::MatrixBase<D6> & tangential_opening, Real & normal_opening_norm,
     Real & tangential_opening_norm, Real & damage, bool & penetration,
     Eigen::MatrixBase<D7> & contact_traction,
     Eigen::MatrixBase<D8> & contact_opening) const {
 
   /// compute normal and tangential opening vectors
   normal_opening_norm = opening.dot(normal);
   normal_opening = normal * normal_opening_norm;
 
   tangential_opening = opening - normal_opening;
   tangential_opening_norm = tangential_opening.norm();
 
   /**
    * compute effective opening displacement
    * @f$ \delta = \sqrt{
    * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
    */
   Real delta =
       tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
   penetration = normal_opening_norm / delta_c < -Math::getTolerance();
 
   // penetration = normal_opening_norm < 0.;
   if (not this->contact_after_breaking and
       Math::are_float_equal(damage, 1.)) {
     penetration = false;
   }
 
   if (penetration) {
     /// use penalty coefficient in case of penetration
     contact_traction = normal_opening * this->penalty;
     contact_opening = normal_opening;
 
     /// don't consider penetration contribution for delta
     opening = tangential_opening;
     normal_opening.zero();
   } else {
     delta += normal_opening_norm * normal_opening_norm;
     contact_traction.zero();
     contact_opening.zero();
   }
 
   delta = std::sqrt(delta);
 
   /// update maximum displacement and damage
   delta_max = std::max(delta_max, delta);
   damage = std::min(delta_max / delta_c, Real(1.));
 
   /**
    * Compute traction @f$ \mathbf{T} = \left(
    * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
    * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
    * \frac{\delta}{\delta_c} \right)@f$
    */
 
   if (Math::are_float_equal(damage, 1.)) {
     traction.zero();
   } else if (Math::are_float_equal(damage, 0.)) {
     if (penetration) {
       traction.zero();
     } else {
       traction = insertion_stress;
     }
   } else {
     AKANTU_DEBUG_ASSERT(delta_max != 0.,
                         "Division by zero, tolerance might be too low");
 
     traction = (tangential_opening * this->beta2_kappa + normal_opening) *
                sigma_c / delta_max * (1. - damage);
   }
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 template <class D1, class D2, class D3, class D4, class D5, class D6>
 inline void MaterialCohesiveLinear<dim>::computeTangentTractionOnQuad(
     Eigen::MatrixBase<D1> & tangent, Real & delta_max, const Real & delta_c,
     const Real & sigma_c, Eigen::MatrixBase<D2> & opening,
     const Eigen::MatrixBase<D3> & normal,
     Eigen::MatrixBase<D4> & normal_opening,
     Eigen::MatrixBase<D5> & tangential_opening, Real & normal_opening_norm,
     Real & tangential_opening_norm, Real & damage, bool & penetration,
     Eigen::MatrixBase<D6> & contact_opening) const {
 
   /**
    * During the update of the residual the interpenetrations are
    * stored in the array "contact_opening", therefore, in the case
    * of penetration, in the array "opening" there are only the
    * tangential components.
    */
   opening += contact_opening;
 
   /// compute normal and tangential opening vectors
   normal_opening_norm = opening.dot(normal);
   normal_opening = normal * normal_opening_norm;
 
   tangential_opening = opening - normal_opening;
   tangential_opening_norm = tangential_opening.norm();
 
   auto delta =
       tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
   penetration = normal_opening_norm < 0.0;
   if (not this->contact_after_breaking and
       Math::are_float_equal(damage, 1.)) {
     penetration = false;
   }
 
   Real derivative = 0; // derivative = d(t/delta)/ddelta
   Real t = 0;
 
   auto && n_outer_n = normal * normal.transpose();
 
   if (penetration) {
     /// stiffness in compression given by the penalty parameter
     tangent = penalty * (tangent + n_outer_n);
 
     opening = tangential_opening;
-    normal_opening_norm = normal * opening.dot(normal);
+
+    normal_opening_norm = opening.dot(normal);
+    normal_opening = normal * normal_opening_norm;
   } else {
     delta += normal_opening_norm * normal_opening_norm;
   }
 
   delta = std::sqrt(delta);
 
   /**
    * Delta has to be different from 0 to have finite values of
    * tangential stiffness.  At the element insertion, delta =
    * 0. Therefore, a fictictious value is defined, for the
    * evaluation of the first value of K.
    */
   if (delta < Math::getTolerance()) {
     delta = delta_c / 1000.;
   }
 
   if (delta >= delta_max) {
     if (delta <= delta_c) {
       derivative = -sigma_c / (delta * delta);
       t = sigma_c * (1 - delta / delta_c);
     } else {
       derivative = 0.;
       t = 0.;
     }
   } else if (delta < delta_max) {
     Real tmax = sigma_c * (1 - delta_max / delta_c);
     t = tmax / delta_max * delta;
   }
 
   /// computation of the derivative of the constitutive law (dT/ddelta)
   auto && I = Eigen::Matrix<Real, dim, dim>::Identity() * this->beta2_kappa;
 
-  auto &&  nn = (n_outer_n * (1. - this->beta2_kappa)  + I) * t / delta;
+  auto && nn = (n_outer_n * (1. - this->beta2_kappa) + I) * t / delta;
   auto && mm = opening * this->beta2_kappa2;
 
   auto && t_tilde = normal_opening * (1. - this->beta2_kappa2) + mm;
   auto && t_hat = normal_opening + this->beta2_kappa * tangential_opening;
 
   auto && prov = t_hat * t_tilde.transpose() * derivative / delta + nn;
 
   tangent += prov.transpose();
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 #endif //AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_HH_
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
index 36346d8ea..bb310dc32 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
@@ -1,420 +1,408 @@
 /**
  * @file   material_cohesive_linear_uncoupled.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Mon Jul 25 2016
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 <algorithm>
 #include <numeric>
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear_uncoupled.hh"
 #include "solid_mechanics_model_cohesive.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
-MaterialCohesiveLinearUncoupled<spatial_dimension>::
+template <Int dim>
+MaterialCohesiveLinearUncoupled<dim>::
     MaterialCohesiveLinearUncoupled(SolidMechanicsModel & model, const ID & id)
-    : MaterialCohesiveLinear<spatial_dimension>(model, id),
+    : MaterialCohesiveLinear<dim>(model, id),
       delta_n_max("delta_n_max", *this), delta_t_max("delta_t_max", *this),
       damage_n("damage_n", *this), damage_t("damage_t", *this) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam(
       "roughness", R, Real(1.), _pat_parsable | _pat_readable,
       "Roughness to define coupling between mode II and mode I");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
-void MaterialCohesiveLinearUncoupled<spatial_dimension>::initMaterial() {
+template <Int dim>
+void MaterialCohesiveLinearUncoupled<dim>::initMaterial() {
   AKANTU_DEBUG_IN();
 
-  MaterialCohesiveLinear<spatial_dimension>::initMaterial();
+  MaterialCohesiveLinear<dim>::initMaterial();
 
   delta_n_max.initialize(1);
   delta_t_max.initialize(1);
   damage_n.initialize(1);
   damage_t.initialize(1);
 
   delta_n_max.initializeHistory();
   delta_t_max.initializeHistory();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
-void MaterialCohesiveLinearUncoupled<spatial_dimension>::computeTraction(
-    const Array<Real> & /*unused*/, ElementType el_type, GhostType ghost_type) {
+template <Int dim>
+void MaterialCohesiveLinearUncoupled<dim>::computeTraction(
+    const Array<Real> &, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   delta_n_max.resize();
   delta_t_max.resize();
   damage_n.resize();
   damage_t.resize();
 
   /// define iterators
   auto traction_it =
-      this->tractions(el_type, ghost_type).begin(spatial_dimension);
+      this->tractions(el_type, ghost_type).begin(dim);
 
   auto traction_end =
-      this->tractions(el_type, ghost_type).end(spatial_dimension);
+      this->tractions(el_type, ghost_type).end(dim);
 
-  auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
+  auto opening_it = this->opening(el_type, ghost_type).begin(dim);
   auto contact_traction_it =
-      this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
+      this->contact_tractions(el_type, ghost_type).begin(dim);
   auto contact_opening_it =
-      this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
+      this->contact_opening(el_type, ghost_type).begin(dim);
 
-  auto normal_it = this->normal.begin(spatial_dimension);
+  auto normal_it = this->normal.begin(dim);
   auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
   auto delta_n_max_it = delta_n_max(el_type, ghost_type).begin();
   auto delta_t_max_it = delta_t_max(el_type, ghost_type).begin();
   auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
   auto damage_n_it = damage_n(el_type, ghost_type).begin();
   auto damage_t_it = damage_t(el_type, ghost_type).begin();
 
   auto insertion_stress_it =
-      this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
+      this->insertion_stress(el_type, ghost_type).begin(dim);
 
-  Vector<Real> normal_opening(spatial_dimension);
-  Vector<Real> tangential_opening(spatial_dimension);
+  Vector<Real> normal_opening(dim);
+  Vector<Real> tangential_opening(dim);
 
   /// loop on each quadrature point
   for (; traction_it != traction_end;
        ++traction_it, ++opening_it, ++contact_traction_it, ++contact_opening_it,
        ++normal_it, ++sigma_c_it, ++delta_n_max_it, ++delta_t_max_it,
        ++delta_c_it, ++damage_n_it, ++damage_t_it, ++insertion_stress_it) {
 
     Real normal_opening_norm;
     Real tangential_opening_norm;
     bool penetration;
 
     Real delta_c2_R2 = *delta_c_it * (*delta_c_it) / R / R;
 
     /// compute normal and tangential opening vectors
     normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening = *normal_it;
     normal_opening *= normal_opening_norm;
 
     //    std::cout<< "normal_opening_norm = " << normal_opening_norm
     //    <<std::endl;
 
     Vector<Real> tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
     tangential_opening_norm = tangential_opening.norm();
 
     /// compute effective opening displacement
     Real delta_n =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
     Real delta_t =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
     penetration = normal_opening_norm < 0.0;
     if (not this->contact_after_breaking and
         Math::are_float_equal(*damage_n_it, 1.)) {
       penetration = false;
     }
 
     if (penetration) {
       /// use penalty coefficient in case of penetration
       *contact_traction_it = normal_opening;
       *contact_traction_it *= this->penalty;
       *contact_opening_it = normal_opening;
 
       /// don't consider penetration contribution for delta
       //*opening_it = tangential_opening;
       normal_opening.zero();
 
     } else {
       delta_n += normal_opening_norm * normal_opening_norm;
       delta_t += normal_opening_norm * normal_opening_norm * delta_c2_R2;
       contact_traction_it->zero();
       contact_opening_it->zero();
     }
 
     delta_n = std::sqrt(delta_n);
     delta_t = std::sqrt(delta_t);
 
     /// update maximum displacement and damage
     *delta_n_max_it = std::max(*delta_n_max_it, delta_n);
     *damage_n_it = std::min(*delta_n_max_it / *delta_c_it, Real(1.));
 
     *delta_t_max_it = std::max(*delta_t_max_it, delta_t);
     *damage_t_it = std::min(*delta_t_max_it / *delta_c_it, Real(1.));
 
-    Vector<Real> normal_traction(spatial_dimension);
-    Vector<Real> shear_traction(spatial_dimension);
+    Vector<Real> normal_traction(dim);
+    Vector<Real> shear_traction(dim);
 
     /// NORMAL TRACTIONS
     if (Math::are_float_equal(*damage_n_it, 1.)) {
       normal_traction.zero();
     } else if (Math::are_float_equal(*damage_n_it, 0.)) {
       if (penetration) {
         normal_traction.zero();
       } else {
         normal_traction = *insertion_stress_it;
       }
     } else {
       // the following formulation holds both in loading and in
       // unloading-reloading
       normal_traction = normal_opening;
 
       AKANTU_DEBUG_ASSERT(*delta_n_max_it != 0.,
                           "Division by zero, tolerance might be too low");
 
       normal_traction *= *sigma_c_it / (*delta_n_max_it) * (1. - *damage_n_it);
     }
 
     /// SHEAR TRACTIONS
     if (Math::are_float_equal(*damage_t_it, 1.) or
         Math::are_float_equal(*damage_t_it, 0.)) {
       shear_traction.zero();
     } else {
       shear_traction = tangential_opening;
 
       AKANTU_DEBUG_ASSERT(*delta_t_max_it != 0.,
                           "Division by zero, tolerance might be too low");
 
       shear_traction *= this->beta2_kappa;
       shear_traction *= *sigma_c_it / (*delta_t_max_it) * (1. - *damage_t_it);
     }
 
     *traction_it = normal_traction;
     *traction_it += shear_traction;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt spatial_dimension>
-void MaterialCohesiveLinearUncoupled<spatial_dimension>::computeTangentTraction(
-    ElementType el_type, Array<Real> & tangent_matrix,
-    const Array<Real> & /*unused*/, GhostType ghost_type) {
+template <Int dim>
+void MaterialCohesiveLinearUncoupled<dim>::computeTangentTraction(
+    const ElementType & el_type, Array<Real> & tangent_matrix,
+    const Array<Real> &, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
-  auto tangent_it = tangent_matrix.begin(spatial_dimension, spatial_dimension);
-  auto tangent_end = tangent_matrix.end(spatial_dimension, spatial_dimension);
-  auto normal_it = this->normal.begin(spatial_dimension);
-  auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
+  auto tangent_it = tangent_matrix.begin(dim, dim);
+  auto tangent_end = tangent_matrix.end(dim, dim);
+  auto normal_it = this->normal.begin(dim);
+  auto opening_it = this->opening(el_type, ghost_type).begin(dim);
 
   /// NB: delta_max_it points on delta_max_previous, i.e. the
   /// delta_max related to the solution of the previous incremental
   /// step
   auto delta_n_max_it = delta_n_max.previous(el_type, ghost_type).begin();
   auto delta_t_max_it = delta_t_max.previous(el_type, ghost_type).begin();
   auto sigma_c_it = this->sigma_c_eff(el_type, ghost_type).begin();
   auto delta_c_it = this->delta_c_eff(el_type, ghost_type).begin();
   auto damage_n_it = damage_n(el_type, ghost_type).begin();
 
   auto contact_opening_it =
-      this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
+      this->contact_opening(el_type, ghost_type).begin(dim);
 
-  Vector<Real> normal_opening(spatial_dimension);
-  Vector<Real> tangential_opening(spatial_dimension);
+  Vector<Real> normal_opening(dim);
+  Vector<Real> tangential_opening(dim);
 
   for (; tangent_it != tangent_end; ++tangent_it, ++normal_it, ++opening_it,
                                     ++sigma_c_it, ++delta_c_it,
                                     ++delta_n_max_it, ++delta_t_max_it,
                                     ++damage_n_it, ++contact_opening_it) {
 
     Real normal_opening_norm;
     Real tangential_opening_norm;
     bool penetration;
     Real delta_c2_R2 = *delta_c_it * (*delta_c_it) / R / R;
 
     /**
      * During the update of the residual the interpenetrations are
      * stored in the array "contact_opening", therefore, in the case
      * of penetration, in the array "opening" there are only the
      * tangential components.
      */
     *opening_it += *contact_opening_it;
 
     /// compute normal and tangential opening vectors
     normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening = *normal_it;
     normal_opening *= normal_opening_norm;
 
     Vector<Real> tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
     tangential_opening_norm = tangential_opening.norm();
 
     Real delta_n =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
     Real delta_t =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
     penetration = normal_opening_norm < 0.0;
     if (not this->contact_after_breaking and
         Math::are_float_equal(*damage_n_it, 1.)) {
       penetration = false;
     }
 
     Real derivative = 0; // derivative = d(t/delta)/ddelta
     Real T = 0;
 
     /// TANGENT STIFFNESS FOR NORMAL TRACTIONS
-    Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
-    n_outer_n.outerProduct(*normal_it, *normal_it);
+    Matrix<Real> n_outer_n(dim, dim);
+    n_outer_n = *normal_it * (*normal_it).transpose();
 
     if (penetration) {
       /// stiffness in compression given by the penalty parameter
       *tangent_it = n_outer_n;
       *tangent_it *= this->penalty;
 
       //*opening_it = tangential_opening;
       normal_opening.zero();
     } else {
       delta_n += normal_opening_norm * normal_opening_norm;
       delta_n = std::sqrt(delta_n);
 
       delta_t += normal_opening_norm * normal_opening_norm * delta_c2_R2;
 
       /**
        * Delta has to be different from 0 to have finite values of
        * tangential stiffness.  At the element insertion, delta =
        * 0. Therefore, a fictictious value is defined, for the
        * evaluation of the first value of K.
        */
       if (delta_n < Math::getTolerance()) {
         delta_n = *delta_c_it / 1000.;
       }
 
       // loading
       if (delta_n >= *delta_n_max_it) {
         if (delta_n <= *delta_c_it) {
           derivative = -(*sigma_c_it) / (delta_n * delta_n);
           T = *sigma_c_it * (1 - delta_n / *delta_c_it);
         } else {
           derivative = 0.;
           T = 0.;
         }
         // unloading-reloading
       } else if (delta_n < *delta_n_max_it) {
         Real T_max = *sigma_c_it * (1 - *delta_n_max_it / *delta_c_it);
         derivative = 0.;
         T = T_max / *delta_n_max_it * delta_n;
       }
 
       /// computation of the derivative of the constitutive law (dT/ddelta)
       Matrix<Real> nn(n_outer_n);
       nn *= T / delta_n;
 
       Vector<Real> Delta_tilde(normal_opening);
       Delta_tilde *= (1. - this->beta2_kappa2);
       Vector<Real> mm(*opening_it);
       mm *= this->beta2_kappa2;
       Delta_tilde += mm;
 
       const Vector<Real> & Delta_hat(normal_opening);
-      Matrix<Real> prov(spatial_dimension, spatial_dimension);
-      prov.outerProduct(Delta_hat, Delta_tilde);
+      Matrix<Real> prov(dim, dim);
+      prov = Delta_hat * Delta_tilde.transpose();
       prov *= derivative / delta_n;
       prov += nn;
 
       Matrix<Real> prov_t = prov.transpose();
 
       *tangent_it = prov_t;
     }
 
     derivative = 0.;
     T = 0.;
 
     /// TANGENT STIFFNESS FOR SHEAR TRACTIONS
     delta_t = std::sqrt(delta_t);
 
     /**
      * Delta has to be different from 0 to have finite values of
      * tangential stiffness.  At the element insertion, delta =
      * 0. Therefore, a fictictious value is defined, for the
      * evaluation of the first value of K.
      */
     if (delta_t < Math::getTolerance()) {
       delta_t = *delta_c_it / 1000.;
     }
 
     // loading
     if (delta_t >= *delta_t_max_it) {
       if (delta_t <= *delta_c_it) {
         derivative = -(*sigma_c_it) / (delta_t * delta_t);
         T = *sigma_c_it * (1 - delta_t / *delta_c_it);
       } else {
         derivative = 0.;
         T = 0.;
       }
       // unloading-reloading
     } else if (delta_t < *delta_t_max_it) {
       Real T_max = *sigma_c_it * (1 - *delta_t_max_it / *delta_c_it);
       derivative = 0.;
       T = T_max / *delta_t_max_it * delta_t;
     }
 
     /// computation of the derivative of the constitutive law (dT/ddelta)
-    Matrix<Real> I(spatial_dimension, spatial_dimension);
-    I.eye();
-    Matrix<Real> nn(n_outer_n);
-    I -= nn;
-    I *= T / delta_t;
-
-    Vector<Real> Delta_tilde(normal_opening);
-    Delta_tilde *= (delta_c2_R2 - this->beta2_kappa2);
-    Vector<Real> mm(*opening_it);
-    mm *= this->beta2_kappa2;
-    Delta_tilde += mm;
-
-    Vector<Real> Delta_hat(tangential_opening);
-    Delta_hat *= this->beta2_kappa;
-    Matrix<Real> prov(spatial_dimension, spatial_dimension);
-    prov.outerProduct(Delta_hat, Delta_tilde);
-    prov *= derivative / delta_t;
-    prov += I;
-
-    Matrix<Real> prov_t = prov.transpose();
-
-    *tangent_it += prov_t;
+    auto I = (Matrix<Real, dim, dim>::Identity() - n_outer_n) * (T / delta_t);
+
+    auto && Delta_tilde = normal_opening * (delta_c2_R2 - this->beta2_kappa2)
+        + *opening_it  * this->beta2_kappa2;
+
+    auto && Delta_hat = tangential_opening * this->beta2_kappa;
+
+    auto && prov = Delta_hat * Delta_tilde.transpose() * derivative / delta_t + I;
+
+    *tangent_it += prov.transpose();
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear_uncoupled,
                      MaterialCohesiveLinearUncoupled);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.hh
index c7d19a437..0e8d404fc 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.hh
@@ -1,103 +1,102 @@
 /**
  * @file   material_cohesive_linear_uncoupled.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Feb 20 2020
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "material_cohesive_linear.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef AKANTU_MATERIAL_COHESIVE_LINEAR_UNCOUPLED_HH_
 #define AKANTU_MATERIAL_COHESIVE_LINEAR_UNCOUPLED_HH_
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /**
  * Cohesive material linear with two different laws for mode I and
  * mode II, for extrinsic case
  *
  * parameters in the material files :
  *  - roughness : define the interaction between mode I and mode II (default: 0)
  */
-template <UInt spatial_dimension>
-class MaterialCohesiveLinearUncoupled
-    : public MaterialCohesiveLinear<spatial_dimension> {
+template <Int dim>
+class MaterialCohesiveLinearUncoupled : public MaterialCohesiveLinear<dim> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
   //  typedef MaterialCohesiveLinear<spatial_dimension> MaterialParent;
 public:
   MaterialCohesiveLinearUncoupled(SolidMechanicsModel & model,
                                   const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material parameters
   void initMaterial() override;
 
 protected:
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /// compute tangent stiffness matrix
   void computeTangentTraction(ElementType el_type,
                               Array<Real> & tangent_matrix,
                               const Array<Real> & normal,
                               GhostType ghost_type) override;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// parameter to tune the interaction between mode II and mode I
   Real R;
 
   /// maximum normal displacement
   CohesiveInternalField<Real> delta_n_max;
 
   /// maximum tangential displacement
   CohesiveInternalField<Real> delta_t_max;
 
   /// damage associated to normal tractions
   CohesiveInternalField<Real> damage_n;
 
   /// damage associated to shear tractions
   CohesiveInternalField<Real> damage_t;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_MATERIAL_COHESIVE_LINEAR_UNCOUPLED_HH_ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
index 97e53e1c9..2bd3c6920 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.cc
@@ -1,570 +1,533 @@
 /**
  * @file   material_cohesive.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Feb 22 2012
  * @date last modification: Thu Jan 14 2021
  *
  * @brief  Specialization of the material class for cohesive elements
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive.hh"
 #include "aka_random_generator.hh"
 #include "dof_synchronizer.hh"
 #include "fe_engine_template.hh"
 #include "integrator_gauss.hh"
 #include "shape_cohesive.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MaterialCohesive::MaterialCohesive(SolidMechanicsModel & model, const ID & id)
     : Material(model, id),
       facet_filter("facet_filter", id),
       fem_cohesive(
           model.getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine")),
       reversible_energy("reversible_energy", *this),
       total_energy("total_energy", *this), opening("opening", *this),
       tractions("tractions", *this),
       contact_tractions("contact_tractions", *this),
       contact_opening("contact_opening", *this), delta_max("delta max", *this),
       use_previous_delta_max(false), use_previous_opening(false),
       damage("damage", *this), sigma_c("sigma_c", *this),
       normal(0, spatial_dimension, "normal") {
 
   AKANTU_DEBUG_IN();
 
   this->model = dynamic_cast<SolidMechanicsModelCohesive *>(&model);
 
   this->registerParam("sigma_c", sigma_c, _pat_parsable | _pat_readable,
                       "Critical stress");
   this->registerParam("delta_c", delta_c, Real(0.),
                       _pat_parsable | _pat_readable, "Critical displacement");
 
   this->element_filter.initialize(this->model->getMesh(),
                                   _spatial_dimension = spatial_dimension,
                                   _element_kind = _ek_cohesive);
   // this->model->getMesh().initElementTypeMapArray(
   //     this->element_filter, 1, spatial_dimension, false, _ek_cohesive);
 
   if (this->model->getIsExtrinsic()) {
     this->facet_filter.initialize(this->model->getMeshFacets(),
                                   _spatial_dimension = spatial_dimension - 1,
                                   _element_kind = _ek_regular);
   }
   // this->model->getMeshFacets().initElementTypeMapArray(facet_filter, 1,
   //                                                      spatial_dimension -
   //                                                      1);
 
   this->reversible_energy.initialize(1);
   this->total_energy.initialize(1);
 
   this->tractions.initialize(spatial_dimension);
   this->tractions.initializeHistory();
 
   this->contact_tractions.initialize(spatial_dimension);
   this->contact_opening.initialize(spatial_dimension);
 
   this->opening.initialize(spatial_dimension);
   this->opening.initializeHistory();
 
   this->delta_max.initialize(1);
   this->damage.initialize(1);
 
   if (this->model->getIsExtrinsic()) {
     this->sigma_c.initialize(1);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 MaterialCohesive::~MaterialCohesive() = default;
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::initMaterial() {
   AKANTU_DEBUG_IN();
   Material::initMaterial();
   if (this->use_previous_delta_max) {
     this->delta_max.initializeHistory();
   }
   if (this->use_previous_opening) {
     this->opening.initializeHistory();
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::assembleInternalForces(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
 #if defined(AKANTU_DEBUG_TOOLS)
   debug::element_manager.printData(debug::_dm_material_cohesive,
                                    "Cohesive Tractions", tractions);
 #endif
 
   auto & internal_force = const_cast<Array<Real> &>(model->getInternalForce());
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type,
                                                _ek_cohesive)) {
     auto & elem_filter = element_filter(type, ghost_type);
-    UInt nb_element = elem_filter.size();
+    auto nb_element = elem_filter.size();
     if (nb_element == 0) {
       continue;
     }
 
     const auto & shapes = fem_cohesive.getShapes(type, ghost_type);
     auto & traction = tractions(type, ghost_type);
     auto & contact_traction = contact_tractions(type, ghost_type);
 
-    UInt size_of_shapes = shapes.getNbComponent();
-    UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
-    UInt nb_quadrature_points =
+    auto size_of_shapes = shapes.getNbComponent();
+    auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+    auto nb_quadrature_points =
         fem_cohesive.getNbIntegrationPoints(type, ghost_type);
 
     /// compute @f$t_i N_a@f$
 
-    auto * traction_cpy = new Array<Real>(nb_element * nb_quadrature_points,
-                                          spatial_dimension * size_of_shapes);
+    auto traction_cpy = std::make_shared<Array<Real>>(
+        nb_element * nb_quadrature_points, spatial_dimension * size_of_shapes);
 
     auto traction_it = traction.begin(spatial_dimension, 1);
     auto contact_traction_it = contact_traction.begin(spatial_dimension, 1);
     auto shapes_filtered_begin = shapes.begin(1, size_of_shapes);
     auto traction_cpy_it =
         traction_cpy->begin(spatial_dimension, size_of_shapes);
 
     Matrix<Real> traction_tmp(spatial_dimension, 1);
 
-    for (UInt el = 0; el < nb_element; ++el) {
+    for (Int el = 0; el < nb_element; ++el) {
+      auto current_quad = elem_filter(el) * nb_quadrature_points;
 
-      UInt current_quad = elem_filter(el) * nb_quadrature_points;
+      for (Int q = 0; q < nb_quadrature_points; ++q, ++traction_it,
+               ++contact_traction_it, ++current_quad, ++traction_cpy_it) {
 
-      for (UInt q = 0; q < nb_quadrature_points; ++q, ++traction_it,
-                ++contact_traction_it, ++current_quad, ++traction_cpy_it) {
+        auto && shapes_filtered = shapes_filtered_begin[current_quad];
 
-        const Matrix<Real> & shapes_filtered =
-            shapes_filtered_begin[current_quad];
-
-        traction_tmp.copy(*traction_it);
-        traction_tmp += *contact_traction_it;
-
-        traction_cpy_it->mul<false, false>(traction_tmp, shapes_filtered);
+        *traction_cpy_it =
+            (*traction_it + *contact_traction_it) * shapes_filtered;
       }
     }
 
     /**
      * compute @f$\int t \cdot N\, dS@f$ by  @f$ \sum_q \mathbf{N}^t
      * \mathbf{t}_q \overline w_q J_q@f$
      */
-    auto * partial_int_t_N = new Array<Real>(
+    auto partial_int_t_N = std::make_shared<Array<Real>>(
         nb_element, spatial_dimension * size_of_shapes, "int_t_N");
 
     fem_cohesive.integrate(*traction_cpy, *partial_int_t_N,
                            spatial_dimension * size_of_shapes, type, ghost_type,
                            elem_filter);
 
-    delete traction_cpy;
-
-    auto * int_t_N = new Array<Real>(
+    auto int_t_N = std::make_shared<Array<Real>>(
         nb_element, 2 * spatial_dimension * size_of_shapes, "int_t_N");
 
-    Real * int_t_N_val = int_t_N->storage();
-    Real * partial_int_t_N_val = partial_int_t_N->storage();
-    for (UInt el = 0; el < nb_element; ++el) {
+    auto * int_t_N_val = int_t_N->data();
+    auto * partial_int_t_N_val = partial_int_t_N->data();
+    for (Int el = 0; el < nb_element; ++el) {
       std::copy_n(partial_int_t_N_val, size_of_shapes * spatial_dimension,
                   int_t_N_val);
       std::copy_n(partial_int_t_N_val, size_of_shapes * spatial_dimension,
                   int_t_N_val + size_of_shapes * spatial_dimension);
 
-      for (UInt n = 0; n < size_of_shapes * spatial_dimension; ++n) {
+      for (Int n = 0; n < size_of_shapes * spatial_dimension; ++n) {
         int_t_N_val[n] *= -1.;
       }
 
       int_t_N_val += nb_nodes_per_element * spatial_dimension;
       partial_int_t_N_val += size_of_shapes * spatial_dimension;
     }
 
-    delete partial_int_t_N;
-
     /// assemble
     model->getDOFManager().assembleElementalArrayLocalArray(
         *int_t_N, internal_force, type, ghost_type, 1, elem_filter);
-
-    delete int_t_N;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::assembleStiffnessMatrix(GhostType ghost_type) {
 
   AKANTU_DEBUG_IN();
 
   for (auto type : element_filter.elementTypes(spatial_dimension, ghost_type,
                                                _ek_cohesive)) {
-    UInt nb_quadrature_points =
+    auto nb_quadrature_points =
         fem_cohesive.getNbIntegrationPoints(type, ghost_type);
-    UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
+    auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
-    const Array<Real> & shapes = fem_cohesive.getShapes(type, ghost_type);
-    Array<UInt> & elem_filter = element_filter(type, ghost_type);
-
-    UInt nb_element = elem_filter.size();
+    const auto & shapes = fem_cohesive.getShapes(type, ghost_type);
+    auto & elem_filter = element_filter(type, ghost_type);
+    auto nb_element = elem_filter.size();
 
     if (nb_element == 0U) {
       continue;
     }
 
-    UInt size_of_shapes = shapes.getNbComponent();
+    auto size_of_shapes = shapes.getNbComponent();
 
-    auto * shapes_filtered = new Array<Real>(nb_element * nb_quadrature_points,
-                                             size_of_shapes, "filtered shapes");
+    auto shapes_filtered = std::make_shared<Array<Real>>(
+        nb_element * nb_quadrature_points, size_of_shapes, "filtered shapes");
 
-    Real * shapes_filtered_val = shapes_filtered->storage();
-    UInt * elem_filter_val = elem_filter.data();
-
-    for (UInt el = 0; el < nb_element; ++el) {
-      auto * shapes_val = shapes.data() + elem_filter_val[el] *
-                                                 size_of_shapes *
-                                                 nb_quadrature_points;
-      memcpy(shapes_filtered_val, shapes_val,
-             size_of_shapes * nb_quadrature_points * sizeof(Real));
-      shapes_filtered_val += size_of_shapes * nb_quadrature_points;
+    for (auto && data :
+         zip(filter(elem_filter,
+                    make_view(shapes, size_of_shapes, nb_quadrature_points)),
+             make_view(*shapes_filtered, size_of_shapes,
+                       nb_quadrature_points))) {
+      std::get<1>(data) = std::get<0>(data);
     }
 
     Matrix<Real> A(spatial_dimension * size_of_shapes,
                    spatial_dimension * nb_nodes_per_element);
 
-    for (UInt i = 0; i < spatial_dimension * size_of_shapes; ++i) {
+    for (Int i = 0; i < spatial_dimension * size_of_shapes; ++i) {
       A(i, i) = 1;
       A(i, i + spatial_dimension * size_of_shapes) = -1;
     }
 
     /// get the tangent matrix @f$\frac{\partial{(t/\delta)}}{\partial{\delta}}
     /// @f$
-    auto * tangent_stiffness_matrix = new Array<Real>(
+    auto tangent_stiffness_matrix = std::make_unique<Array<Real>>(
         nb_element * nb_quadrature_points,
         spatial_dimension * spatial_dimension, "tangent_stiffness_matrix");
-
-    //    Array<Real> * normal = new Array<Real>(nb_element *
-    //    nb_quadrature_points, spatial_dimension, "normal");
     normal.resize(nb_quadrature_points);
 
     computeNormal(model->getCurrentPosition(), normal, type, ghost_type);
 
     /// compute openings @f$\mathbf{\delta}@f$
     // computeOpening(model->getDisplacement(), opening(type, ghost_type), type,
     // ghost_type);
 
     tangent_stiffness_matrix->zero();
 
     computeTangentTraction(type, *tangent_stiffness_matrix, normal, ghost_type);
 
-    // delete normal;
-
     UInt size_at_nt_d_n_a = spatial_dimension * nb_nodes_per_element *
                             spatial_dimension * nb_nodes_per_element;
-    auto * at_nt_d_n_a = new Array<Real>(nb_element * nb_quadrature_points,
-                                         size_at_nt_d_n_a, "A^t*N^t*D*N*A");
-
-    Array<Real>::iterator<Vector<Real>> shapes_filt_it =
-        shapes_filtered->begin(size_of_shapes);
-
-    Array<Real>::matrix_iterator D_it =
-        tangent_stiffness_matrix->begin(spatial_dimension, spatial_dimension);
+    auto at_nt_d_n_a = std::make_unique<Array<Real>>(
+        nb_element * nb_quadrature_points, size_at_nt_d_n_a, "A^t*N^t*D*N*A");
 
-    Array<Real>::matrix_iterator At_Nt_D_N_A_it =
-        at_nt_d_n_a->begin(spatial_dimension * nb_nodes_per_element,
-                           spatial_dimension * nb_nodes_per_element);
+    Matrix<Real> N(spatial_dimension, spatial_dimension * nb_nodes_per_element);
 
-    Array<Real>::matrix_iterator At_Nt_D_N_A_end =
-        at_nt_d_n_a->end(spatial_dimension * nb_nodes_per_element,
-                         spatial_dimension * nb_nodes_per_element);
+    for (auto && data :
+         zip(make_view(*at_nt_d_n_a, spatial_dimension * nb_nodes_per_element,
+                       spatial_dimension * nb_nodes_per_element),
+             make_view(*tangent_stiffness_matrix, spatial_dimension,
+                       spatial_dimension),
+             make_view(*shapes_filtered, size_of_shapes))) {
 
-    Matrix<Real> N(spatial_dimension, spatial_dimension * size_of_shapes);
-    Matrix<Real> N_A(spatial_dimension,
-                     spatial_dimension * nb_nodes_per_element);
-    Matrix<Real> D_N_A(spatial_dimension,
-                       spatial_dimension * nb_nodes_per_element);
-
-    for (; At_Nt_D_N_A_it != At_Nt_D_N_A_end;
-         ++At_Nt_D_N_A_it, ++D_it, ++shapes_filt_it) {
+      auto && At_Nt_D_N_A = std::get<0>(data);
+      auto && D = std::get<1>(data);
+      auto && shapes = std::get<2>(data);
       N.zero();
       /**
        * store  the   shapes  in  voigt   notations  matrix  @f$\mathbf{N}  =
        * \begin{array}{cccccc} N_0(\xi) & 0 & N_1(\xi)  &0 & N_2(\xi) & 0 \\
        * 0 & * N_0(\xi)& 0 &N_1(\xi)& 0 & N_2(\xi) \end{array} @f$
        **/
-      for (UInt i = 0; i < spatial_dimension; ++i) {
-        for (UInt n = 0; n < size_of_shapes; ++n) {
-          N(i, i + spatial_dimension * n) = (*shapes_filt_it)(n);
+      for (Int i = 0; i < spatial_dimension; ++i) {
+        for (Int n = 0; n < size_of_shapes; ++n) {
+          N(i, i + spatial_dimension * n) = shapes(n);
         }
       }
 
       /**
-       * compute stiffness matrix  @f$   \mathbf{K}    =    \delta \mathbf{U}^T
-       * \int_{\Gamma_c}    {\mathbf{P}^t \frac{\partial{\mathbf{t}}}
+       * compute stiffness matrix  @f$   \mathbf{K}    =    \delta
+       *\mathbf{U}^T \int_{\Gamma_c}    {\mathbf{P}^t
+       *\frac{\partial{\mathbf{t}}}
        *{\partial{\delta}}
        * \mathbf{P} d\Gamma \Delta \mathbf{U}}  @f$
        **/
-      N_A.mul<false, false>(N, A);
-      D_N_A.mul<false, false>(*D_it, N_A);
-      (*At_Nt_D_N_A_it).mul<true, false>(D_N_A, N_A);
+      auto && NA = N * A;
+      At_Nt_D_N_A = (D * NA).transpose() * NA;
     }
 
-    delete tangent_stiffness_matrix;
-    delete shapes_filtered;
-
-    auto * K_e = new Array<Real>(nb_element, size_at_nt_d_n_a, "K_e");
+    auto K_e =
+        std::make_unique<Array<Real>>(nb_element, size_at_nt_d_n_a, "K_e");
 
     fem_cohesive.integrate(*at_nt_d_n_a, *K_e, size_at_nt_d_n_a, type,
                            ghost_type, elem_filter);
 
-    delete at_nt_d_n_a;
-
     model->getDOFManager().assembleElementalMatricesToMatrix(
         "K", "displacement", *K_e, type, ghost_type, _unsymmetric, elem_filter);
-
-    delete K_e;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- *
  * Compute traction from displacements
  *
  * @param[in] ghost_type compute the residual for _ghost or _not_ghost element
  */
 void MaterialCohesive::computeTraction(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
 #if defined(AKANTU_DEBUG_TOOLS)
   debug::element_manager.printData(debug::_dm_material_cohesive,
                                    "Cohesive Openings", opening);
 #endif
 
-  for (const auto & type : element_filter.elementTypes(
-           spatial_dimension, ghost_type, _ek_cohesive)) {
-    Array<UInt> & elem_filter = element_filter(type, ghost_type);
-
-    UInt nb_element = elem_filter.size();
+  for (auto & type : element_filter.elementTypes(spatial_dimension, ghost_type,
+                                                 _ek_cohesive)) {
+    auto & elem_filter = element_filter(type, ghost_type);
+    auto nb_element = elem_filter.size();
     if (nb_element == 0) {
       continue;
     }
 
-    UInt nb_quadrature_points =
+    auto nb_quadrature_points =
         nb_element * fem_cohesive.getNbIntegrationPoints(type, ghost_type);
 
     normal.resize(nb_quadrature_points);
 
     /// compute normals @f$\mathbf{n}@f$
     computeNormal(model->getCurrentPosition(), normal, type, ghost_type);
 
     /// compute openings @f$\mathbf{\delta}@f$
     computeOpening(model->getDisplacement(), opening(type, ghost_type), type,
                    ghost_type);
 
     /// compute traction @f$\mathbf{t}@f$
     computeTraction(normal, type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::computeNormal(const Array<Real> & position,
                                      Array<Real> & normal, ElementType type,
                                      GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto & fem_cohesive =
       this->model->getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine");
 
   normal.zero();
 
 #define COMPUTE_NORMAL(type)                                                   \
   fem_cohesive.getShapeFunctions()                                             \
       .computeNormalsOnIntegrationPoints<type, CohesiveReduceFunctionMean>(    \
           position, normal, ghost_type, element_filter(type, ghost_type));
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_NORMAL);
 #undef COMPUTE_NORMAL
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::computeOpening(const Array<Real> & displacement,
                                       Array<Real> & opening, ElementType type,
                                       GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   auto & fem_cohesive =
       this->model->getFEEngineClass<MyFEEngineCohesiveType>("CohesiveFEEngine");
 
 #define COMPUTE_OPENING(type)                                                  \
   fem_cohesive.getShapeFunctions()                                             \
       .interpolateOnIntegrationPoints<type, CohesiveReduceFunctionOpening>(    \
           displacement, opening, spatial_dimension, ghost_type,                \
           element_filter(type, ghost_type));
 
   AKANTU_BOOST_COHESIVE_ELEMENT_SWITCH(COMPUTE_OPENING);
 #undef COMPUTE_OPENING
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MaterialCohesive::updateEnergies(ElementType type) {
   AKANTU_DEBUG_IN();
 
   if (Mesh::getKind(type) != _ek_cohesive) {
     return;
   }
 
   Vector<Real> b(spatial_dimension);
   Vector<Real> h(spatial_dimension);
   auto erev = reversible_energy(type).begin();
   auto etot = total_energy(type).begin();
   auto traction_it = tractions(type).begin(spatial_dimension);
   auto traction_old_it = tractions.previous(type).begin(spatial_dimension);
   auto opening_it = opening(type).begin(spatial_dimension);
   auto opening_old_it = opening.previous(type).begin(spatial_dimension);
 
   auto traction_end = tractions(type).end(spatial_dimension);
 
   /// loop on each quadrature point
   for (; traction_it != traction_end; ++traction_it, ++traction_old_it,
                                       ++opening_it, ++opening_old_it, ++erev,
                                       ++etot) {
     /// trapezoidal integration
     b = *opening_it;
     b -= *opening_old_it;
 
     h = *traction_old_it;
     h += *traction_it;
 
     *etot += .5 * b.dot(h);
     *erev = .5 * traction_it->dot(*opening_it);
   }
 
   /// update old values
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Real MaterialCohesive::getReversibleEnergy() {
   AKANTU_DEBUG_IN();
   Real erev = 0.;
 
   /// integrate reversible energy for each type of elements
   for (const auto & type : element_filter.elementTypes(
            spatial_dimension, _not_ghost, _ek_cohesive)) {
     erev +=
         fem_cohesive.integrate(reversible_energy(type, _not_ghost), type,
                                _not_ghost, element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return erev;
 }
 
 /* -------------------------------------------------------------------------- */
 Real MaterialCohesive::getDissipatedEnergy() {
   AKANTU_DEBUG_IN();
   Real edis = 0.;
 
   /// integrate dissipated energy for each type of elements
   for (const auto & type : element_filter.elementTypes(
            spatial_dimension, _not_ghost, _ek_cohesive)) {
     Array<Real> dissipated_energy(total_energy(type, _not_ghost));
     dissipated_energy -= reversible_energy(type, _not_ghost);
     edis += fem_cohesive.integrate(dissipated_energy, type, _not_ghost,
                                    element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return edis;
 }
 
 /* -------------------------------------------------------------------------- */
 Real MaterialCohesive::getContactEnergy() {
   AKANTU_DEBUG_IN();
   Real econ = 0.;
 
   /// integrate contact energy for each type of elements
   for (const auto & type : element_filter.elementTypes(
            spatial_dimension, _not_ghost, _ek_cohesive)) {
 
     auto & el_filter = element_filter(type, _not_ghost);
     UInt nb_quad_per_el = fem_cohesive.getNbIntegrationPoints(type, _not_ghost);
     UInt nb_quad_points = el_filter.size() * nb_quad_per_el;
     Array<Real> contact_energy(nb_quad_points);
 
     auto contact_traction_it =
         contact_tractions(type, _not_ghost).begin(spatial_dimension);
     auto contact_opening_it =
         contact_opening(type, _not_ghost).begin(spatial_dimension);
 
     /// loop on each quadrature point
     for (UInt q = 0; q < nb_quad_points;
          ++contact_traction_it, ++contact_opening_it, ++q) {
 
       contact_energy(q) = .5 * contact_traction_it->dot(*contact_opening_it);
     }
 
     econ += fem_cohesive.integrate(contact_energy, type, _not_ghost, el_filter);
   }
 
   AKANTU_DEBUG_OUT();
   return econ;
 }
 
 /* -------------------------------------------------------------------------- */
 Real MaterialCohesive::getEnergy(const std::string & type) {
   if (type == "reversible") {
     return getReversibleEnergy();
   }
   if (type == "dissipated") {
     return getDissipatedEnergy();
   }
   if (type == "cohesive contact") {
     return getContactEnergy();
   }
 
   return 0.;
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive.hh
index b584246f2..44cf3c6d6 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,236 +1,235 @@
 /**
  * @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: Thu Jan 14 2021
  *
  * @brief  Specialization of the material class for cohesive elements
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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:
   using MyFEEngineCohesiveType =
       FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>;
 
 public:
   MaterialCohesive(SolidMechanicsModel & model, const ID & id = "");
   ~MaterialCohesive() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the material computed parameter
   void initMaterial() override;
 
   /// compute tractions (including normals and openings)
   void computeTraction(GhostType ghost_type = _not_ghost);
 
   /// assemble residual
   void assembleInternalForces(GhostType ghost_type = _not_ghost) override;
 
   /// check stress for cohesive elements' insertion, by default it
   /// also updates the cohesive elements' data
   virtual void checkInsertion(bool /*check_only*/ = false) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// interpolate   stress  on   given   positions  for   each  element   (empty
   /// implemantation to avoid the generic call to be done on cohesive elements)
   virtual void interpolateStress(const ElementType /*type*/,
                                  Array<Real> & /*result*/) {}
 
   /// compute the stresses
   void computeAllStresses(GhostType /*ghost_type*/ = _not_ghost) override{};
 
   // add the facet to be handled by the material
-  UInt addFacet(const Element & element);
+  Idx addFacet(const Element & element);
 
 protected:
   virtual void computeTangentTraction(ElementType /*el_type*/,
                                       Array<Real> & /*tangent_matrix*/,
                                       const Array<Real> & /*normal*/,
                                       GhostType /*ghost_type*/ = _not_ghost) {
     AKANTU_TO_IMPLEMENT();
   }
 
   /// compute the normal
   void computeNormal(const Array<Real> & position, Array<Real> & normal,
                      ElementType type, GhostType ghost_type);
 
   /// compute the opening
   void computeOpening(const Array<Real> & displacement, Array<Real> & opening,
                       ElementType type, GhostType ghost_type);
 
   template <ElementType type>
   void computeNormal(const Array<Real> & position, Array<Real> & normal,
                      GhostType ghost_type);
 
   /// assemble stiffness
   void assembleStiffnessMatrix(GhostType ghost_type) override;
 
   /// constitutive law
   virtual void computeTraction(const Array<Real> & normal, ElementType el_type,
                                GhostType ghost_type = _not_ghost) = 0;
 
   /// parallelism functions
-  inline UInt getNbData(const Array<Element> & elements,
+  inline Int 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;
 
 protected:
   void updateEnergies(ElementType el_type) override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the opening
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Opening, opening, Real);
 
   /// get the traction
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Traction, tractions, Real);
 
   /// get damage
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Damage, damage, Real);
 
   /// get facet filter
-  AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetFilter, facet_filter, UInt);
-  AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetFilter, facet_filter, UInt);
-  AKANTU_GET_MACRO(FacetFilter, facet_filter,
-                   const ElementTypeMapArray<UInt> &);
+  AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetFilter, facet_filter, Idx);
+  AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetFilter, facet_filter, Idx);
+  AKANTU_GET_MACRO_AUTO(FacetFilter, facet_filter);
   // AKANTU_GET_MACRO(ElementFilter, element_filter, const
   // ElementTypeMapArray<UInt> &);
 
   /// compute reversible energy
   Real getReversibleEnergy();
 
   /// compute dissipated energy
   Real getDissipatedEnergy();
 
   /// compute contact energy
   Real getContactEnergy();
 
   /// get energy
   Real getEnergy(const std::string & type) override;
 
   /// return the energy (identified by id) for the provided element
   Real getEnergy(const std::string & energy_id, ElementType type,
-                 UInt index) override {
+                 Idx index) override {
     return Material::getEnergy(energy_id, type, index);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// list of facets assigned to this material
-  ElementTypeMapArray<UInt> facet_filter;
+  ElementTypeMapArray<Idx> facet_filter;
 
   /// Link to the cohesive fem object in the model
   FEEngine & fem_cohesive;
 
 private:
   /// reversible energy by quadrature point
   CohesiveInternalField<Real> reversible_energy;
 
   /// total energy by quadrature point
   CohesiveInternalField<Real> total_energy;
 
 protected:
   /// opening in all elements and quadrature points
   CohesiveInternalField<Real> opening;
 
   /// traction in all elements and quadrature points
   CohesiveInternalField<Real> tractions;
 
   /// traction due to contact
   CohesiveInternalField<Real> contact_tractions;
 
   /// normal openings for contact tractions
   CohesiveInternalField<Real> contact_opening;
 
   /// maximum displacement
   CohesiveInternalField<Real> delta_max;
 
   /// tell if the previous delta_max state is needed (in iterative schemes)
   bool use_previous_delta_max;
 
   /// tell if the previous opening state is needed (in iterative schemes)
   bool use_previous_opening;
 
   /// damage
   CohesiveInternalField<Real> damage;
 
   /// pointer to the solid mechanics model for cohesive elements
   SolidMechanicsModelCohesive * model;
 
   /// critical stress
   RandomInternalField<Real, FacetInternalField> sigma_c;
 
   /// critical displacement
   Real delta_c;
 
   /// array to temporarily store the normals
   Array<Real> normal;
 };
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_inline_impl.hh"
 #include "cohesive_internal_field_tmpl.hh"
 
 #endif /* AKANTU_MATERIAL_COHESIVE_HH_ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_inline_impl.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_inline_impl.hh
index 9234567ca..21ca7399a 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_inline_impl.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/material_cohesive_inline_impl.hh
@@ -1,110 +1,110 @@
 /**
  * @file   material_cohesive_inline_impl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  MaterialCohesive inline implementation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-inline UInt MaterialCohesive::addFacet(const Element & element) {
-  Array<UInt> & f_filter = facet_filter(element.type, element.ghost_type);
+inline Int MaterialCohesive::addFacet(const Element & element) {
+  auto & f_filter = facet_filter(element.type, element.ghost_type);
   f_filter.push_back(element.element);
   return f_filter.size() - 1;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void MaterialCohesive::computeNormal(const Array<Real> & /*position*/,
                                      Array<Real> & /*normal*/,
                                      GhostType /*ghost_type*/) {}
 
 /* -------------------------------------------------------------------------- */
-inline UInt MaterialCohesive::getNbData(const Array<Element> & elements,
+inline Int MaterialCohesive::getNbData(const Array<Element> & elements,
                                         const SynchronizationTag & tag) const {
 
   switch (tag) {
   case SynchronizationTag::_smm_stress: {
     return 2 * spatial_dimension * sizeof(Real) *
            this->getModel().getNbIntegrationPoints(elements,
                                                    "CohesiveFEEngine");
   }
   case SynchronizationTag::_smmc_damage: {
     return sizeof(Real) * this->getModel().getNbIntegrationPoints(
                               elements, "CohesiveFEEngine");
   }
   default: {
   }
   }
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void MaterialCohesive::packData(CommunicationBuffer & buffer,
                                        const Array<Element> & elements,
                                        const SynchronizationTag & tag) const {
   switch (tag) {
   case SynchronizationTag::_smm_stress: {
     packElementDataHelper(tractions, buffer, elements, "CohesiveFEEngine");
     packElementDataHelper(contact_tractions, buffer, elements,
                           "CohesiveFEEngine");
     break;
   }
   case SynchronizationTag::_smmc_damage:
     packElementDataHelper(damage, buffer, elements, "CohesiveFEEngine");
     break;
   default: {
   }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void MaterialCohesive::unpackData(CommunicationBuffer & buffer,
                                          const Array<Element> & elements,
                                          const SynchronizationTag & tag) {
   switch (tag) {
   case SynchronizationTag::_smm_stress: {
     unpackElementDataHelper(tractions, buffer, elements, "CohesiveFEEngine");
     unpackElementDataHelper(contact_tractions, buffer, elements,
                             "CohesiveFEEngine");
     break;
   }
   case SynchronizationTag::_smmc_damage:
     unpackElementDataHelper(damage, buffer, elements, "CohesiveFEEngine");
     break;
   default: {
   }
   }
 }
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
index bb08d0bf6..1ffe14fa5 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.cc
@@ -1,696 +1,686 @@
 /**
  * @file   solid_mechanics_model_cohesive.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Solid mechanics model for cohesive elements
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "aka_iterators.hh"
 #include "cohesive_element_inserter.hh"
 #include "element_synchronizer.hh"
 #include "facet_synchronizer.hh"
 #include "fe_engine_template.hh"
 #include "global_ids_updater.hh"
 #include "integrator_gauss.hh"
 #include "material_cohesive.hh"
 #include "mesh_accessor.hh"
 #include "mesh_global_data_updater.hh"
 #include "parser.hh"
 #include "shape_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 #include "dumpable_inline_impl.hh"
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_iohelper_paraview.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class CohesiveMeshGlobalDataUpdater : public MeshGlobalDataUpdater {
 public:
   CohesiveMeshGlobalDataUpdater(SolidMechanicsModelCohesive & model)
       : model(model), mesh(model.getMesh()),
         global_ids_updater(model.getMesh(), *model.cohesive_synchronizer) {}
 
   /* ------------------------------------------------------------------------ */
   std::tuple<UInt, UInt>
   updateData(NewNodesEvent & nodes_event,
              NewElementsEvent & elements_event) override {
     auto *cohesive_nodes_event =
         dynamic_cast<CohesiveNewNodesEvent *>(&nodes_event);
     if (cohesive_nodes_event == nullptr) {
       return std::make_tuple(nodes_event.getList().size(),
                              elements_event.getList().size());
     }
 
     /// update nodes type
     auto & new_nodes = cohesive_nodes_event->getList();
     auto & old_nodes = cohesive_nodes_event->getOldNodesList();
 
     auto local_nb_new_nodes = new_nodes.size();
     auto nb_new_nodes = local_nb_new_nodes;
 
     if (mesh.isDistributed()) {
       MeshAccessor mesh_accessor(mesh);
       auto & nodes_flags = mesh_accessor.getNodesFlags();
       auto nb_old_nodes = nodes_flags.size();
       nodes_flags.resize(nb_old_nodes + local_nb_new_nodes);
 
       for (auto && data : zip(old_nodes, new_nodes)) {
         UInt old_node;
         UInt new_node;
         std::tie(old_node, new_node) = data;
         nodes_flags(new_node) = nodes_flags(old_node);
       }
 
       model.updateCohesiveSynchronizers(elements_event);
       nb_new_nodes = global_ids_updater.updateGlobalIDs(new_nodes.size());
     }
 
     auto nb_new_elements = elements_event.getList().size();
     const auto & comm = mesh.getCommunicator();
     comm.allReduce(nb_new_elements, SynchronizerOperation::_sum);
 
     if (nb_new_elements > 0) {
       mesh.sendEvent(elements_event);
     }
 
     if (nb_new_nodes > 0) {
       mesh.sendEvent(nodes_event);
     }
 
     return std::make_tuple(nb_new_nodes, nb_new_elements);
   }
 
 private:
   SolidMechanicsModelCohesive & model;
   Mesh & mesh;
   GlobalIdsUpdater global_ids_updater;
 };
 
 /* -------------------------------------------------------------------------- */
 SolidMechanicsModelCohesive::SolidMechanicsModelCohesive(
     Mesh & mesh, UInt dim, const ID & id, std::shared_ptr<DOFManager> dof_manager)
     : SolidMechanicsModel(mesh, dim, id, dof_manager,
                           ModelType::_solid_mechanics_model_cohesive),
       tangents("tangents", id), facet_stress("facet_stress", id),
       facet_material("facet_material", id) {
   AKANTU_DEBUG_IN();
 
   registerFEEngineObject<MyFEEngineCohesiveType>("CohesiveFEEngine", mesh,
                                                  Model::spatial_dimension);
 
   auto && tmp_material_selector =
       std::make_shared<DefaultMaterialCohesiveSelector>(*this);
 
   tmp_material_selector->setFallback(this->material_selector);
   this->material_selector = tmp_material_selector;
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.registerDumper<DumperParaview>("cohesive elements", id);
   this->mesh.addDumpMeshToDumper("cohesive elements", mesh,
                                  Model::spatial_dimension, _not_ghost,
                                  _ek_cohesive);
 #endif
 
   if (this->mesh.isDistributed()) {
     /// create the distributed synchronizer for cohesive elements
     this->cohesive_synchronizer = std::make_unique<ElementSynchronizer>(
         mesh, "cohesive_distributed_synchronizer");
 
     auto & synchronizer = mesh.getElementSynchronizer();
     this->cohesive_synchronizer->split(synchronizer, [](auto && el) {
       return Mesh::getKind(el.type) == _ek_cohesive;
     });
 
     this->registerSynchronizer(*cohesive_synchronizer,
                                SynchronizationTag::_material_id);
     this->registerSynchronizer(*cohesive_synchronizer,
                                SynchronizationTag::_smm_stress);
     this->registerSynchronizer(*cohesive_synchronizer,
                                SynchronizationTag::_smm_boundary);
   }
 
   this->inserter = std::make_unique<CohesiveElementInserter>(
       this->mesh, id + ":cohesive_element_inserter");
 
   registerFEEngineObject<MyFEEngineFacetType>(
       "FacetsFEEngine", mesh.getMeshFacets(), Model::spatial_dimension - 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 SolidMechanicsModelCohesive::~SolidMechanicsModelCohesive() = default;
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::setTimeStep(Real time_step,
                                               const ID & solver_id) {
   SolidMechanicsModel::setTimeStep(time_step, solver_id);
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.getDumper("cohesive elements").setTimeStep(time_step);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initFullImpl(const ModelOptions & options) {
   AKANTU_DEBUG_IN();
 
   const auto & smmc_options =
       aka::as_type<SolidMechanicsModelCohesiveOptions>(options);
 
   this->is_extrinsic = smmc_options.is_extrinsic;
 
   inserter->setIsExtrinsic(is_extrinsic);
 
   if (mesh.isDistributed()) {
     auto & mesh_facets = inserter->getMeshFacets();
     auto & synchronizer =
         aka::as_type<FacetSynchronizer>(mesh_facets.getElementSynchronizer());
 
     // synchronizeGhostFacetsConnectivity();
 
     /// create the facet synchronizer for extrinsic simulations
     if (is_extrinsic) {
       facet_stress_synchronizer = std::make_unique<ElementSynchronizer>(
           synchronizer, id + ":facet_stress_synchronizer");
       facet_stress_synchronizer->swapSendRecv();
       this->registerSynchronizer(*facet_stress_synchronizer,
                                  SynchronizationTag::_smmc_facets_stress);
     }
   }
 
   MeshAccessor mesh_accessor(mesh);
   mesh_accessor.registerGlobalDataUpdater(
       std::make_unique<CohesiveMeshGlobalDataUpdater>(*this));
 
   ParserSection section;
   bool is_empty;
   std::tie(section, is_empty) = this->getParserSection();
 
   if (not is_empty) {
     auto inserter_section =
         section.getSubSections(ParserType::_cohesive_inserter);
     if (inserter_section.begin() != inserter_section.end()) {
       inserter->parseSection(*inserter_section.begin());
     }
   }
 
   SolidMechanicsModel::initFullImpl(options);
 
   AKANTU_DEBUG_OUT();
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initMaterials() {
   AKANTU_DEBUG_IN();
 
   // make sure the material are instantiated
   if (not are_materials_instantiated) {
     instantiateMaterials();
   }
 
   /// find the first cohesive material
   UInt cohesive_index = UInt(-1);
 
   for (auto && material : enumerate(materials)) {
     if (dynamic_cast<MaterialCohesive *>(std::get<1>(material).get()) !=
         nullptr) {
       cohesive_index = std::get<0>(material);
       break;
     }
   }
 
   if (cohesive_index == UInt(-1)) {
     AKANTU_EXCEPTION("No cohesive materials in the material input file");
   }
 
   material_selector->setFallback(cohesive_index);
 
   // set the facet information in the material in case of dynamic insertion
   // to know what material to call for stress checks
   const Mesh & mesh_facets = inserter->getMeshFacets();
   facet_material.initialize(
       mesh_facets, _spatial_dimension = spatial_dimension - 1,
       _with_nb_element = true,
       _default_value = material_selector->getFallbackValue());
 
   for_each_element(
       mesh_facets,
       [&](auto && element) {
         auto mat_index = (*material_selector)(element);
         auto & mat = aka::as_type<MaterialCohesive>(*materials[mat_index]);
         facet_material(element) = mat_index;
         if (is_extrinsic) {
           mat.addFacet(element);
         }
       },
       _spatial_dimension = spatial_dimension - 1, _ghost_type = _not_ghost);
 
   SolidMechanicsModel::initMaterials();
 
   if (is_extrinsic) {
     this->initAutomaticInsertion();
   } else {
     this->insertIntrinsicElements();
   }
 
   AKANTU_DEBUG_OUT();
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /**
  * Initialize the model,basically it  pre-compute the shapes, shapes derivatives
  * and jacobian
  */
 void SolidMechanicsModelCohesive::initModel() {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel::initModel();
 
   /// add cohesive type connectivity
   ElementType type = _not_defined;
   for (auto && type_ghost : ghost_types) {
     for (const auto & tmp_type :
          mesh.elementTypes(spatial_dimension, type_ghost)) {
       const auto & connectivity = mesh.getConnectivity(tmp_type, type_ghost);
       if (connectivity.empty()) {
         continue;
       }
 
       type = tmp_type;
       auto type_facet = Mesh::getFacetType(type);
       auto type_cohesive = FEEngine::getCohesiveElementType(type_facet);
       mesh.addConnectivityType(type_cohesive, type_ghost);
     }
   }
   AKANTU_DEBUG_ASSERT(type != _not_defined, "No elements in the mesh");
 
   getFEEngine("CohesiveFEEngine").initShapeFunctions(_not_ghost);
   getFEEngine("CohesiveFEEngine").initShapeFunctions(_ghost);
 
   if (is_extrinsic) {
     getFEEngine("FacetsFEEngine").initShapeFunctions(_not_ghost);
     getFEEngine("FacetsFEEngine").initShapeFunctions(_ghost);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::insertIntrinsicElements() {
   AKANTU_DEBUG_IN();
   inserter->insertIntrinsicElements();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initAutomaticInsertion() {
   AKANTU_DEBUG_IN();
 
   this->inserter->limitCheckFacets();
   this->updateFacetStressSynchronizer();
   this->resizeFacetStress();
 
   /// compute normals on facets
   this->computeNormals();
 
   this->initStressInterpolation();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::updateAutomaticInsertion() {
   AKANTU_DEBUG_IN();
 
   this->inserter->limitCheckFacets();
   this->updateFacetStressSynchronizer();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::initStressInterpolation() {
   Mesh & mesh_facets = inserter->getMeshFacets();
 
   /// compute quadrature points coordinates on facets
   Array<Real> & position = mesh.getNodes();
 
   ElementTypeMapArray<Real> quad_facets("quad_facets", id);
   quad_facets.initialize(mesh_facets, _nb_component = Model::spatial_dimension,
                          _spatial_dimension = Model::spatial_dimension - 1);
   // mesh_facets.initElementTypeMapArray(quad_facets, Model::spatial_dimension,
   //                                     Model::spatial_dimension - 1);
 
   getFEEngine("FacetsFEEngine")
       .interpolateOnIntegrationPoints(position, quad_facets);
 
   /// compute elements quadrature point positions and build
   /// element-facet quadrature points data structure
   ElementTypeMapArray<Real> elements_quad_facets("elements_quad_facets", id);
 
   elements_quad_facets.initialize(
       mesh, _nb_component = Model::spatial_dimension,
       _spatial_dimension = Model::spatial_dimension);
   // mesh.initElementTypeMapArray(elements_quad_facets,
   // Model::spatial_dimension,
   //                              Model::spatial_dimension);
 
   for (auto elem_gt : ghost_types) {
     for (const auto & type : mesh.elementTypes(Model::spatial_dimension, elem_gt)) {
       UInt nb_element = mesh.getNbElement(type, elem_gt);
       if (nb_element == 0) {
         continue;
       }
 
       /// compute elements' quadrature points and list of facet
       /// quadrature points positions by element
       const auto & facet_to_element =
           mesh_facets.getSubelementToElement(type, elem_gt);
       auto & el_q_facet = elements_quad_facets(type, elem_gt);
 
       auto facet_type = Mesh::getFacetType(type);
       auto nb_quad_per_facet =
           getFEEngine("FacetsFEEngine").getNbIntegrationPoints(facet_type);
       auto nb_facet_per_elem = facet_to_element.getNbComponent();
 
       // small hack in the loop to skip boundary elements, they are silently
       // initialized to NaN to see if this causes problems
       el_q_facet.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet,
                         std::numeric_limits<Real>::quiet_NaN());
 
       for (auto && data :
            zip(make_view(facet_to_element),
                make_view(el_q_facet, spatial_dimension, nb_quad_per_facet))) {
         const auto & global_facet = std::get<0>(data);
         auto & el_q = std::get<1>(data);
 
         if (global_facet == ElementNull) {
           continue;
         }
 
         Matrix<Real> quad_f =
             make_view(quad_facets(global_facet.type, global_facet.ghost_type),
                       spatial_dimension, nb_quad_per_facet)
                 .begin()[global_facet.element];
 
         el_q = quad_f;
       }
     }
   }
 
   /// loop over non cohesive materials
   for (auto && material : materials) {
     if (aka::is_of_type<MaterialCohesive>(material)) {
       continue;
     }
     /// initialize the interpolation function
     material->initElementalFieldInterpolation(elements_quad_facets);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::assembleInternalForces() {
   AKANTU_DEBUG_IN();
 
   // f_int += f_int_cohe
   for (auto & material : this->materials) {
     try {
       auto & mat = aka::as_type<MaterialCohesive>(*material);
       mat.computeTraction(_not_ghost);
     } catch (std::bad_cast & bce) {
     }
   }
 
   SolidMechanicsModel::assembleInternalForces();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::computeNormals() {
   AKANTU_DEBUG_IN();
 
   Mesh & mesh_facets = this->inserter->getMeshFacets();
   this->getFEEngine("FacetsFEEngine")
       .computeNormalsOnIntegrationPoints(_not_ghost);
 
   /**
    *  @todo store tangents while computing normals instead of
    *  recomputing them as follows:
    */
   /* ------------------------------------------------------------------------ */
   UInt tangent_components =
       Model::spatial_dimension * (Model::spatial_dimension - 1);
 
   tangents.initialize(mesh_facets, _nb_component = tangent_components,
                       _spatial_dimension = Model::spatial_dimension - 1);
-  // mesh_facets.initElementTypeMapArray(tangents, tangent_components,
-  //                                     Model::spatial_dimension - 1);
 
   for (auto facet_type :
        mesh_facets.elementTypes(Model::spatial_dimension - 1)) {
     const Array<Real> & normals =
         this->getFEEngine("FacetsFEEngine")
             .getNormalsOnIntegrationPoints(facet_type);
 
     Array<Real> & tangents = this->tangents(facet_type);
 
     Math::compute_tangents(normals, tangents);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::interpolateStress() {
   ElementTypeMapArray<Real> by_elem_result("temporary_stress_by_facets", id);
 
   for (auto & material : materials) {
     if (not aka::is_of_type<MaterialCohesive>(material)) {
       /// interpolate stress on facet quadrature points positions
       material->interpolateStressOnFacets(facet_stress, by_elem_result);
     }
   }
 
   this->synchronize(SynchronizationTag::_smmc_facets_stress);
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModelCohesive::checkCohesiveStress() {
   AKANTU_DEBUG_IN();
 
   if (not is_extrinsic) {
     AKANTU_EXCEPTION(
         "This function can only be used for extrinsic cohesive elements");
   }
 
   interpolateStress();
 
   for (auto & mat : materials) {
     if (aka::is_of_type<MaterialCohesive>(mat)) {
       /// check which not ghost cohesive elements are to be created
       auto * mat_cohesive = aka::as_type<MaterialCohesive>(mat.get());
       mat_cohesive->checkInsertion();
     }
   }
 
-  /// communicate data among processors
-  // this->synchronize(SynchronizationTag::_smmc_facets);
-
   /// insert cohesive elements
   UInt nb_new_elements = inserter->insertElements();
 
-  // if (nb_new_elements > 0) {
-  //   this->reinitializeSolver();
-  // }
-
   AKANTU_DEBUG_OUT();
 
   return nb_new_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::onElementsAdded(
     const Array<Element> & element_list, const NewElementsEvent & event) {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel::onElementsAdded(element_list, event);
 
   if (is_extrinsic) {
     resizeFacetStress();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-void SolidMechanicsModelCohesive::onNodesAdded(const Array<UInt> & new_nodes,
+void SolidMechanicsModelCohesive::onNodesAdded(const Array<Idx> & new_nodes,
                                                const NewNodesEvent & event) {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel::onNodesAdded(new_nodes, event);
 
   const CohesiveNewNodesEvent * cohesive_event;
   if ((cohesive_event = dynamic_cast<const CohesiveNewNodesEvent *>(&event)) ==
       nullptr) {
     return;
   }
 
   const auto & old_nodes = cohesive_event->getOldNodesList();
 
   auto copy = [this, &new_nodes, &old_nodes](auto & arr) {
     UInt new_node;
     UInt old_node;
 
     auto view = make_view(arr, spatial_dimension);
     auto begin = view.begin();
 
     for (auto && pair : zip(new_nodes, old_nodes)) {
       std::tie(new_node, old_node) = pair;
 
       auto old_ = begin + old_node;
       auto new_ = begin + new_node;
 
       *new_ = *old_;
     }
   };
 
   copy(*displacement);
   copy(*blocked_dofs);
 
   if (velocity) {
     copy(*velocity);
   }
 
   if (acceleration) {
     copy(*acceleration);
   }
 
   if (current_position) {
     copy(*current_position);
   }
 
   if (previous_displacement) {
     copy(*previous_displacement);
   }
 
   if (displacement_increment) {
     copy(*displacement_increment);
   }
 
   copy(getDOFManager().getSolution("displacement"));
-  // this->assembleMassLumped();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::afterSolveStep(bool converged) {
   AKANTU_DEBUG_IN();
 
   /*
    * This is required because the Cauchy stress is the stress measure that
    * is used to check the insertion of cohesive elements
    */
   if (converged) {
     for (auto & mat : materials) {
       if (mat->isFiniteDeformation()) {
         mat->computeAllCauchyStresses(_not_ghost);
       }
     }
   }
 
   SolidMechanicsModel::afterSolveStep(converged);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::printself(std::ostream & stream,
                                             int indent) const {
   std::string space(indent, AKANTU_INDENT);
 
   stream << space << "SolidMechanicsModelCohesive ["
          << "\n";
   SolidMechanicsModel::printself(stream, indent + 2);
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::resizeFacetStress() {
   AKANTU_DEBUG_IN();
 
   this->facet_stress.initialize(getFEEngine("FacetsFEEngine"),
                                 _nb_component =
                                     2 * spatial_dimension * spatial_dimension,
                                 _spatial_dimension = spatial_dimension - 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::addDumpGroupFieldToDumper(
     const std::string & dumper_name, const std::string & field_id,
     const std::string & group_name, ElementKind element_kind,
     bool padding_flag) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = Model::spatial_dimension;
   ElementKind _element_kind = element_kind;
   if (dumper_name == "cohesive elements") {
     _element_kind = _ek_cohesive;
   } else if (dumper_name == "facets") {
     spatial_dimension = Model::spatial_dimension - 1;
   }
 
   SolidMechanicsModel::addDumpGroupFieldToDumper(dumper_name, field_id,
                                                  group_name, spatial_dimension,
                                                  _element_kind, padding_flag);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 void SolidMechanicsModelCohesive::onDump() {
   this->flattenAllRegisteredInternals(_ek_cohesive);
   SolidMechanicsModel::onDump();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
index 85ce58462..b7804cd65 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive.hh
@@ -1,310 +1,309 @@
 /**
  * @file   solid_mechanics_model_cohesive.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Solid mechanics model for cohesive elements
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "cohesive_element_inserter.hh"
 #include "material_selector_cohesive.hh"
 #include "random_internal_field.hh" // included to have the specialization of
                                     // ParameterTyped::operator Real()
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH_
 #define AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH_
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 class FacetSynchronizer;
 class FacetStressSynchronizer;
 class ElementSynchronizer;
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 struct FacetsCohesiveIntegrationOrderFunctor {
   template <ElementType type, ElementType cohesive_type =
                                   CohesiveFacetProperty<type>::cohesive_type>
   struct _helper {
     static constexpr int get() {
       return ElementClassProperty<cohesive_type>::polynomial_degree;
     }
   };
 
   template <ElementType type> struct _helper<type, _not_defined> {
     static constexpr int get() {
       return ElementClassProperty<type>::polynomial_degree;
     }
   };
 
   template <ElementType type> static inline constexpr int getOrder() {
     return _helper<type>::get();
   }
 };
 
 /* -------------------------------------------------------------------------- */
 /* Solid Mechanics Model for Cohesive elements                                */
 /* -------------------------------------------------------------------------- */
 class SolidMechanicsModelCohesive : public SolidMechanicsModel,
                                     public SolidMechanicsModelEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   class NewCohesiveNodesEvent : public NewNodesEvent {
   public:
     AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
     AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
 
   protected:
     Array<UInt> old_nodes;
   };
 
   using MyFEEngineCohesiveType =
       FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_cohesive>;
   using MyFEEngineFacetType =
       FEEngineTemplate<IntegratorGauss, ShapeLagrange, _ek_regular,
                        FacetsCohesiveIntegrationOrderFunctor>;
 
   SolidMechanicsModelCohesive(Mesh & mesh, UInt dim = _all_dimensions,
                               const ID & id = "solid_mechanics_model_cohesive",
                               std::shared_ptr<DOFManager> dof_manager = nullptr);
 
   ~SolidMechanicsModelCohesive() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// initialize the cohesive model
   void initFullImpl(const ModelOptions & options) override;
 
 public:
   /// set the value of the time step
   void setTimeStep(Real time_step, const ID & solver_id = "") override;
 
   /// assemble the residual for the explicit scheme
   void assembleInternalForces() override;
 
   /// function to perform a stress check on each facet and insert
   /// cohesive elements if needed (returns the number of new cohesive
   /// elements)
   UInt checkCohesiveStress();
 
   /// interpolate stress on facets
   void interpolateStress();
 
   /// update automatic insertion after a change in the element inserter
   void updateAutomaticInsertion();
 
   /// insert intrinsic cohesive elements
   void insertIntrinsicElements();
 
   // template <SolveConvergenceMethod cmethod, SolveConvergenceCriteria
   // criteria> bool solveStepCohesive(Real tolerance, Real & error, UInt
   // max_iteration = 100,
   //                        bool load_reduction = false,
   //                        Real tol_increase_factor = 1.0,
   //                        bool do_not_factorize = false);
 
 protected:
   /// initialize stress interpolation
   void initStressInterpolation();
 
   /// initialize the model
   void initModel() override;
 
   /// initialize cohesive material
   void initMaterials() override;
 
   /// init facet filters for cohesive materials
   void initFacetFilter();
 
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
 private:
   /// insert cohesive elements along a given physical surface of the mesh
   void insertElementsFromMeshData(const std::string & physical_name);
 
   /// initialize completely the model for extrinsic elements
   void initAutomaticInsertion();
 
   /// compute facets' normals
   void computeNormals();
 
   /// resize facet stress
   void resizeFacetStress();
 
   /// init facets_check array
   void initFacetsCheck();
 
   /* ------------------------------------------------------------------------ */
   /* Mesh Event Handler inherited members                                     */
   /* ------------------------------------------------------------------------ */
 
 protected:
-  void onNodesAdded(const Array<UInt> & new_nodes,
+  void onNodesAdded(const Array<Idx> & nodes_list,
                     const NewNodesEvent & event) override;
   void onElementsAdded(const Array<Element> & element_list,
                        const NewElementsEvent & event) override;
 
   /* ------------------------------------------------------------------------ */
   /* SolidMechanicsModelEventHandler inherited members                        */
   /* ------------------------------------------------------------------------ */
 public:
   void afterSolveStep(bool converged = true) override;
 
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface                                                       */
   /* ------------------------------------------------------------------------ */
 public:
   void onDump() override;
 
   void addDumpGroupFieldToDumper(const std::string & dumper_name,
                                  const std::string & field_id,
                                  const std::string & group_name,
                                  ElementKind element_kind,
                                  bool padding_flag) override;
 
 public:
   /// register the tags associated with the parallel synchronizer for
   /// cohesive elements
   // void initParallel(MeshPartition * partition,
   //                DataAccessor * data_accessor = NULL,
   //                bool extrinsic = false);
 
 protected:
-  //void synchronizeGhostFacetsConnectivity();
+  // void synchronizeGhostFacetsConnectivity();
 
   void updateCohesiveSynchronizers(NewElementsEvent & elements_event);
   void updateFacetStressSynchronizer();
 
   friend class CohesiveElementInserter;
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
-  UInt getNbData(const Array<Element> & elements,
-                 const SynchronizationTag & tag) const override;
+  Int getNbData(const Array<Element> & elements,
+                const SynchronizationTag & tag) const override;
 
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const SynchronizationTag & tag) const override;
 
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const SynchronizationTag & tag) override;
 
 protected:
-  UInt getNbQuadsForFacetCheck(const Array<Element> & elements) const;
+  Int getNbQuadsForFacetCheck(const Array<Element> & elements) const;
 
   template <typename T>
   void packFacetStressDataHelper(const ElementTypeMapArray<T> & data_to_pack,
                                  CommunicationBuffer & buffer,
                                  const Array<Element> & elements) const;
 
   template <typename T>
   void unpackFacetStressDataHelper(ElementTypeMapArray<T> & data_to_unpack,
                                    CommunicationBuffer & buffer,
                                    const Array<Element> & elements) const;
 
   template <typename T, bool pack_helper>
   void packUnpackFacetStressDataHelper(ElementTypeMapArray<T> & data_to_pack,
                                        CommunicationBuffer & buffer,
                                        const Array<Element> & element) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get facet mesh
-  AKANTU_GET_MACRO(MeshFacets, mesh.getMeshFacets(), const Mesh &);
+  AKANTU_GET_MACRO_AUTO(MeshFacets, mesh.getMeshFacets());
 
   /// get stress on facets vector
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(StressOnFacets, facet_stress, Real);
 
   /// get facet material
-  AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetMaterial, facet_material, UInt);
+  AKANTU_GET_MACRO_BY_ELEMENT_TYPE(FacetMaterial, facet_material, Idx);
 
   /// get facet material
-  AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetMaterial, facet_material, UInt);
+  AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(FacetMaterial, facet_material, Idx);
 
   /// get facet material
-  AKANTU_GET_MACRO(FacetMaterial, facet_material,
-                   const ElementTypeMapArray<UInt> &);
+  AKANTU_GET_MACRO_AUTO(FacetMaterial, facet_material);
 
   /// @todo THIS HAS TO BE CHANGED
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Tangents, tangents, Real);
 
   /// get element inserter
   AKANTU_GET_MACRO_NOT_CONST(ElementInserter, *inserter,
                              CohesiveElementInserter &);
 
   /// get is_extrinsic boolean
   AKANTU_GET_MACRO(IsExtrinsic, is_extrinsic, bool);
 
   /// get cohesive elements synchronizer
   AKANTU_GET_MACRO_NOT_CONST(CohesiveSynchronizer, *cohesive_synchronizer,
                    ElementSynchronizer &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   friend class CohesiveMeshGlobalDataUpdater;
 
   /// @todo store tangents when normals are computed:
   ElementTypeMapArray<Real> tangents;
 
   /// stress on facets on the two sides by quadrature point
   ElementTypeMapArray<Real> facet_stress;
 
   /// material to use if a cohesive element is created on a facet
-  ElementTypeMapArray<UInt> facet_material;
+  ElementTypeMapArray<Idx> facet_material;
 
   bool is_extrinsic{false};
 
   /// cohesive element inserter
   std::unique_ptr<CohesiveElementInserter> inserter;
 
   /// facet stress synchronizer
   std::unique_ptr<ElementSynchronizer> facet_stress_synchronizer;
 
   /// cohesive elements synchronizer
   std::unique_ptr<ElementSynchronizer> cohesive_synchronizer;
 };
 
 } // namespace akantu
 
 #include "solid_mechanics_model_cohesive_inline_impl.hh"
 
 #endif /* AKANTU_SOLID_MECHANICS_MODEL_COHESIVE_HH_ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/solid_mechanics_model_cohesive_parallel.cc
index bfd5e2ed8..983573f75 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,524 +1,524 @@
 /**
  * @file   solid_mechanics_model_cohesive_parallel.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Oct 13 2017
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Functions for parallel cohesive elements
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free software: you can redistribute it and/or modify it under the
  * terms of the GNU Lesser General Public License as published by the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  * 
  * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  * details.
  * 
  * You should have received a copy of the GNU Lesser General Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "communicator.hh"
 #include "element_synchronizer.hh"
 #include "material_cohesive.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "solid_mechanics_model_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 // void SolidMechanicsModelCohesive::synchronizeGhostFacetsConnectivity() {
 //   AKANTU_DEBUG_IN();
 
 //   const Communicator & comm = mesh.getCommunicator();
 //   Int psize = comm.getNbProc();
 
 //   if (psize == 1) {
 //     AKANTU_DEBUG_OUT();
 //     return;
 //   }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::updateCohesiveSynchronizers(
     NewElementsEvent & elements_event) {
   /// update synchronizers if needed
 
   if (not mesh.isDistributed()) {
     return;
   }
 
   ElementTypeMap<Int> nb_new_cohesive_elements;
   for (auto ghost_type : ghost_types) {
     for(auto cohesive_type : mesh.elementTypes(spatial_dimension, ghost_type, _ek_cohesive)){
       nb_new_cohesive_elements(cohesive_type, ghost_type) = 0;
     }
   }
 
   for(auto & el : elements_event.getList()) {
     if(el.kind() != _ek_cohesive) continue;
     ++nb_new_cohesive_elements(el.type, el.ghost_type);
   }
 
   auto & mesh_facets = inserter->getMeshFacets();
   auto & facet_synchronizer = mesh_facets.getElementSynchronizer();
   const auto & cfacet_synchronizer = facet_synchronizer;
 
   // update the cohesive element synchronizer
   cohesive_synchronizer->updateSchemes([&](auto && scheme, auto && proc,
                                            auto && direction) {
     auto & facet_scheme =
         cfacet_synchronizer.getCommunications().getScheme(proc, direction);
 
     for (auto && facet : facet_scheme) {
       const auto & cohesive_element = const_cast<const Mesh &>(mesh_facets)
                                           .getElementToSubelement(facet)[1];
 
       if (cohesive_element == ElementNull or
           cohesive_element.kind() != _ek_cohesive) {
         continue;
       }
 
       auto && cohesive_type = FEEngine::getCohesiveElementType(facet.type);
       auto old_nb_cohesive_elements =
           mesh.getNbElement(cohesive_type, facet.ghost_type);
       old_nb_cohesive_elements -=
           nb_new_cohesive_elements(cohesive_type, facet.ghost_type);
 
       if (cohesive_element.element >= old_nb_cohesive_elements) {
         scheme.push_back(cohesive_element);
       }
     }
   });
 
   if (not facet_stress_synchronizer) {
     return;
   }
 
   const auto & element_synchronizer = mesh.getElementSynchronizer();
   const auto & comm = mesh.getCommunicator();
   auto && my_rank = comm.whoAmI();
 
   // update the facet stress synchronizer
   facet_stress_synchronizer->updateSchemes([&](auto && scheme, auto && proc,
                                                auto && /*direction*/) {
     auto it_element = scheme.begin();
     for (auto && element : scheme) {
       auto && facet_check = inserter->getCheckFacets(
           element.type, element.ghost_type)(element.element); // slow access
                                                               // here
 
       if (facet_check) {
         auto && connected_elements = mesh_facets.getElementToSubelement(
             element.type, element.ghost_type)(element.element); // slow access
                                                                 // here
         auto && rank_left = element_synchronizer.getRank(connected_elements[0]);
         auto && rank_right =
             element_synchronizer.getRank(connected_elements[1]);
 
         // keep element if the element is still a boundary element between two
         // processors
         if ((rank_left == Int(proc) and rank_right == my_rank) or
             (rank_left == my_rank and rank_right == Int(proc))) {
           *it_element = element;
           ++it_element;
         }
       }
     }
     scheme.resize(it_element - scheme.begin());
   });
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModelCohesive::updateFacetStressSynchronizer() {
   if (facet_stress_synchronizer != nullptr) {
     const auto & rank_to_element =
         mesh.getElementSynchronizer().getElementToRank();
     const auto & facet_checks = inserter->getCheckFacets();
     const auto & mesh_facets = inserter->getMeshFacets();
     const auto & element_to_facet = mesh_facets.getElementToSubelement();
     UInt rank = mesh.getCommunicator().whoAmI();
 
     facet_stress_synchronizer->updateSchemes(
         [&](auto & scheme, auto & proc, auto & /*direction*/) {
           UInt el = 0;
           for (auto && element : scheme) {
             if (not facet_checks(element)) {
               continue;
             }
 
             const auto & next_el = element_to_facet(element);
             UInt rank_left = rank_to_element(next_el[0]);
             UInt rank_right = rank_to_element(next_el[1]);
 
             if ((rank_left == rank and rank_right == proc) or
                 (rank_left == proc and rank_right == rank)) {
               scheme[el] = element;
               ++el;
             }
           }
           scheme.resize(el);
         });
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void SolidMechanicsModelCohesive::packFacetStressDataHelper(
     const ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & elements) const {
   packUnpackFacetStressDataHelper<T, true>(
       const_cast<ElementTypeMapArray<T> &>(data_to_pack), buffer, elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void SolidMechanicsModelCohesive::unpackFacetStressDataHelper(
     ElementTypeMapArray<T> & data_to_unpack, CommunicationBuffer & buffer,
     const Array<Element> & elements) const {
   packUnpackFacetStressDataHelper<T, false>(data_to_unpack, buffer, elements);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, bool pack_helper>
 void SolidMechanicsModelCohesive::packUnpackFacetStressDataHelper(
     ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & elements) const {
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   UInt nb_quad_per_elem = 0;
   UInt sp2 = spatial_dimension * spatial_dimension;
   UInt nb_component = sp2 * 2;
   bool element_rank = false;
   Mesh & mesh_facets = inserter->getMeshFacets();
 
   Array<T> * vect = nullptr;
   const Array<std::vector<Element>> * element_to_facet = nullptr;
 
   auto & fe_engine = this->getFEEngine("FacetsFEEngine");
   for (auto && el : elements) {
     if (el.type == _not_defined) {
       AKANTU_EXCEPTION(
           "packUnpackFacetStressDataHelper called with wrong inputs");
     }
 
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
       vect = &data_to_pack(el.type, el.ghost_type);
 
       element_to_facet =
           &(mesh_facets.getElementToSubelement(el.type, el.ghost_type));
 
       nb_quad_per_elem =
           fe_engine.getNbIntegrationPoints(el.type, el.ghost_type);
     }
 
     if (pack_helper) {
       element_rank =
           (*element_to_facet)(el.element)[0].ghost_type != _not_ghost;
     } else {
       element_rank =
           (*element_to_facet)(el.element)[0].ghost_type == _not_ghost;
     }
 
     for (UInt q = 0; q < nb_quad_per_elem; ++q) {
-      Vector<T> data(vect->storage() +
+      VectorProxy<T> data(vect->data() +
                          (el.element * nb_quad_per_elem + q) * nb_component +
                          element_rank * sp2,
                      sp2);
 
       if (pack_helper) {
         buffer << data;
       } else {
         buffer >> data;
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-UInt SolidMechanicsModelCohesive::getNbQuadsForFacetCheck(
+Int SolidMechanicsModelCohesive::getNbQuadsForFacetCheck(
     const Array<Element> & elements) const {
-  UInt nb_quads = 0;
-  UInt nb_quad_per_facet = 0;
+  Int nb_quads = 0;
+  Int nb_quad_per_facet = 0;
 
-  ElementType current_element_type = _not_defined;
-  GhostType current_ghost_type = _casper;
-  auto & fe_engine = this->getFEEngine("FacetsFEEngine");
+  auto current_element_type = _not_defined;
+  auto current_ghost_type = _casper;
+  const auto & fe_engine = this->getFEEngine("FacetsFEEngine");
   for (const auto & el : elements) {
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
 
       nb_quad_per_facet =
           fe_engine.getNbIntegrationPoints(el.type, el.ghost_type);
     }
 
     nb_quads += nb_quad_per_facet;
   }
 
   return nb_quads;
 }
 
 /* -------------------------------------------------------------------------- */
-UInt SolidMechanicsModelCohesive::getNbData(
+Int SolidMechanicsModelCohesive::getNbData(
     const Array<Element> & elements, const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
-  UInt size = 0;
+  Int size = 0;
   if (elements.empty()) {
     return 0;
   }
 
   /// regular element case
   if (elements(0).kind() == _ek_regular) {
     switch (tag) {
     // case SynchronizationTag::_smmc_facets: {
     //   size += elements.size() * sizeof(bool);
     //   break;
     // }
     case SynchronizationTag::_smmc_facets_stress: {
-      UInt nb_quads = getNbQuadsForFacetCheck(elements);
+      auto nb_quads = getNbQuadsForFacetCheck(elements);
       size += nb_quads * spatial_dimension * spatial_dimension * sizeof(Real);
       break;
     }
     case SynchronizationTag::_material_id: {
       for (auto && element : elements) {
         if (Mesh::getSpatialDimension(element.type) ==
             (spatial_dimension - 1)) {
           size += sizeof(UInt);
         }
       }
 
       size += SolidMechanicsModel::getNbData(elements, tag);
       break;
     }
 
     default: {
       size += SolidMechanicsModel::getNbData(elements, tag);
     }
     }
   }
   /// cohesive element case
   else if (elements(0).kind() == _ek_cohesive) {
 
     switch (tag) {
     case SynchronizationTag::_material_id: {
       size += elements.size() * sizeof(UInt);
       break;
     }
     case SynchronizationTag::_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 != SynchronizationTag::_material_id &&
         tag != SynchronizationTag::_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.empty()) {
     return;
   }
 
   if (elements(0).kind() == _ek_regular) {
     switch (tag) {
     // case SynchronizationTag::_smmc_facets: {
     //   packElementalDataHelper(inserter->getInsertionFacetsByElement(),
     //   buffer,
     //                           elements, false, getFEEngine());
     //   break;
     // }
     case SynchronizationTag::_smmc_facets_stress: {
       packFacetStressDataHelper(facet_stress, buffer, elements);
       break;
     }
     case SynchronizationTag::_material_id: {
       for (auto && element : elements) {
         if (Mesh::getSpatialDimension(element.type) !=
             (spatial_dimension - 1)) {
           continue;
         }
         buffer << material_index(element);
       }
 
       SolidMechanicsModel::packData(buffer, elements, tag);
       break;
     }
     default: {
       SolidMechanicsModel::packData(buffer, elements, tag);
     }
     }
 
     AKANTU_DEBUG_OUT();
     return;
   }
 
   if (elements(0).kind() == _ek_cohesive) {
     switch (tag) {
     case SynchronizationTag::_material_id: {
       packElementalDataHelper(material_index, buffer, elements, false,
                               getFEEngine("CohesiveFEEngine"));
       break;
     }
     case SynchronizationTag::_smm_boundary: {
       packNodalDataHelper(*internal_force, buffer, elements, mesh);
       packNodalDataHelper(*velocity, buffer, elements, mesh);
       packNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
       break;
     }
     default: {
     }
     }
 
     if (tag != SynchronizationTag::_material_id &&
         tag != SynchronizationTag::_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.empty()) {
     return;
   }
 
   if (elements(0).kind() == _ek_regular) {
     switch (tag) {
     // case SynchronizationTag::_smmc_facets: {
     //   unpackElementalDataHelper(inserter->getInsertionFacetsByElement(),
     //   buffer,
     //                             elements, false, getFEEngine());
     //   break;
     // }
     case SynchronizationTag::_smmc_facets_stress: {
       unpackFacetStressDataHelper(facet_stress, buffer, elements);
       break;
     }
     case SynchronizationTag::_material_id: {
       for (auto && element : elements) {
         if (Mesh::getSpatialDimension(element.type) !=
             (spatial_dimension - 1)) {
           continue;
         }
 
-        UInt recv_mat_index;
+        Int recv_mat_index;
         buffer >> recv_mat_index;
-        UInt & mat_index = material_index(element);
-        if (mat_index != UInt(-1)) {
+        auto & mat_index = material_index(element);
+        if (mat_index != Int(-1)) {
           continue;
         }
 
         // add ghosts element to the correct material
         mat_index = recv_mat_index;
         auto & mat = aka::as_type<MaterialCohesive>(*materials[mat_index]);
         if (is_extrinsic) {
           mat.addFacet(element);
         }
         facet_material(element) = recv_mat_index;
       }
       SolidMechanicsModel::unpackData(buffer, elements, tag);
       break;
     }
     default: {
       SolidMechanicsModel::unpackData(buffer, elements, tag);
     }
     }
 
     AKANTU_DEBUG_OUT();
     return;
   }
 
   if (elements(0).kind() == _ek_cohesive) {
     switch (tag) {
     case SynchronizationTag::_material_id: {
       for (auto && element : elements) {
-        UInt recv_mat_index;
+        Int recv_mat_index;
         buffer >> recv_mat_index;
-        UInt & mat_index = material_index(element);
-        if (mat_index != UInt(-1)) {
+        auto & mat_index = material_index(element);
+        if (mat_index != Int(-1)) {
           continue;
         }
 
         // add ghosts element to the correct material
         mat_index = recv_mat_index;
-        UInt index = materials[mat_index]->addElement(element);
+        auto index = materials[mat_index]->addElement(element);
         material_local_numbering(element) = index;
       }
       break;
     }
     case SynchronizationTag::_smm_boundary: {
       unpackNodalDataHelper(*internal_force, buffer, elements, mesh);
       unpackNodalDataHelper(*velocity, buffer, elements, mesh);
       unpackNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
       break;
     }
     default: {
     }
     }
 
     if (tag != SynchronizationTag::_material_id &&
         tag != SynchronizationTag::_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_inline_impl.hh b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.hh
index 5a62684d9..c1256e9ab 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.hh
@@ -1,108 +1,107 @@
 /**
  * @file   solid_mechanics_model_inline_impl.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: Wed Aug 04 2010
  * @date last modification: Fri Mar 26 2021
  *
  * @brief  Implementation of the inline functions of the SolidMechanicsModel
  * class
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_named_argument.hh"
 #include "material_selector.hh"
 #include "material_selector_tmpl.hh"
-#include "solid_mechanics_model.hh"
+//#include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_SOLID_MECHANICS_MODEL_INLINE_IMPL_HH_
 #define AKANTU_SOLID_MECHANICS_MODEL_INLINE_IMPL_HH_
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto) SolidMechanicsModel::getMaterials() {
   return make_dereference_adaptor(materials);
 }
 
 /* -------------------------------------------------------------------------- */
 inline decltype(auto) SolidMechanicsModel::getMaterials() const {
   return make_dereference_adaptor(materials);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Material & SolidMechanicsModel::getMaterial(UInt mat_index) {
   AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
                       "The model " << id << " has no material no "
                                    << mat_index);
   return *materials.at(mat_index);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Material & SolidMechanicsModel::getMaterial(UInt mat_index) const {
   AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
                       "The model " << id << " has no material no "
                                    << mat_index);
   return *materials.at(mat_index);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Material & SolidMechanicsModel::getMaterial(const std::string & name) {
-  std::map<std::string, UInt>::const_iterator it =
-      materials_names_to_id.find(name);
+  auto it = materials_names_to_id.find(name);
   if(it == materials_names_to_id.end()) {
     AKANTU_SILENT_EXCEPTION("The model " << id << " has no material named " << name);
   }
 
   return *materials[it->second];
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt
+inline Int
 SolidMechanicsModel::getMaterialIndex(const std::string & name) const {
   auto it = materials_names_to_id.find(name);
   if (it == materials_names_to_id.end()) {
     AKANTU_SILENT_EXCEPTION("The model " << id << " has no material named " << name);
   }
   
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Material &
 SolidMechanicsModel::getMaterial(const std::string & name) const {
   auto it = materials_names_to_id.find(name);
   if(it == materials_names_to_id.end()) {
     AKANTU_SILENT_EXCEPTION("The model " << id << " has no material named " << name);
   }
   return *materials[it->second];
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #endif /* AKANTU_SOLID_MECHANICS_MODEL_INLINE_IMPL_HH_ */
diff --git a/src/synchronizer/communicator.hh b/src/synchronizer/communicator.hh
index 0c0ff2f0c..5e21dba7e 100644
--- a/src/synchronizer/communicator.hh
+++ b/src/synchronizer/communicator.hh
@@ -1,559 +1,559 @@
 /**
  * @file   communicator.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Wed Dec 09 2020
  *
  * @brief  Class handling the parallel communications
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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"
 #include "communicator_event_handler.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKANTU_STATIC_COMMUNICATOR_HH_
 #define AKANTU_STATIC_COMMUNICATOR_HH_
 
 namespace akantu {
 
 namespace debug {
   class CommunicationException : public Exception {
   public:
     CommunicationException()
         : Exception("An exception happen during a communication process.") {}
   };
 } // namespace debug
 
 /// @enum SynchronizerOperation reduce operation that the synchronizer can
 /// perform
 enum class SynchronizerOperation {
   _sum,
   _min,
   _max,
   _prod,
   _land,
   _band,
   _lor,
   _bor,
   _lxor,
   _bxor,
   _min_loc,
   _max_loc,
   _null
 };
 
 enum class CommunicationMode { _auto, _synchronous, _ready };
 
 namespace {
   int _any_source = -1;
 }
 } // namespace akantu
 
 namespace akantu {
 
 struct CommunicatorInternalData {
   virtual ~CommunicatorInternalData() = default;
 };
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 class Communicator : public EventHandlerManager<CommunicatorEventHandler> {
   struct private_member {};
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   Communicator(int & argc, char **& argv, const private_member & /*m*/);
   Communicator(const private_member & /*unused*/ = private_member{});
   ~Communicator() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Point to Point                                                           */
   /* ------------------------------------------------------------------------ */
   template <typename T>
   void probe(Int sender, Int tag, CommunicationStatus & status) const;
 
   template <typename T>
   bool asyncProbe(Int sender, Int tag, CommunicationStatus & status) const;
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void receive(Array<T> & values, Int sender, Int tag) const {
     return this->receiveImpl(
         values.data(), values.size() * values.getNbComponent(), sender, tag);
   }
 
   template <typename T>
   inline void receive(std::vector<T> & values, Int sender, Int tag) const {
     return this->receiveImpl(values.data(), values.size(), sender, tag);
   }
 
   template <typename Tensor>
   inline void
   receive(Tensor & values, Int sender, Int tag,
           std::enable_if_t<aka::is_tensor<Tensor>::value> * /*unused*/ =
               nullptr) const {
     return this->receiveImpl(values.data(), values.size(), sender, tag);
   }
 
   inline void receive(CommunicationBufferTemplated<true> & values, Int sender,
                       Int tag) const {
     return this->receiveImpl(values.data(), values.size(), sender, tag);
   }
 
   inline void receive(CommunicationBufferTemplated<false> & values, Int sender,
                       Int tag) const {
     CommunicationStatus status;
     this->probe<char>(sender, tag, status);
     values.reserve(status.size());
     return this->receiveImpl(values.data(), 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> * /*unused*/ =
               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.data(),
                           values.size() * values.getNbComponent(), receiver,
                           tag, mode);
   }
 
   template <typename T>
   inline void
   send(const std::vector<T> & values, Int receiver, Int tag,
        const CommunicationMode & mode = CommunicationMode::_auto) const {
     return this->sendImpl(values.data(), values.size(), 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<aka::is_tensor<Tensor>::value> * /*unused*/ =
            nullptr) const {
     return this->sendImpl(values.data(), 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.data(), 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> * /*unused*/ =
                        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.data(),
                                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<aka::is_tensor<Tensor>::value> * /*unused*/ =
                 nullptr) const {
     return this->asyncSendImpl(values.data(), 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.data(), 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> * /*unused*/ =
                 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.data(), 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<aka::is_tensor<Tensor>::value>>
   inline CommunicationRequest asyncReceive(Tensor & values, Int sender,
                                            Int tag) const {
     return this->asyncReceiveImpl(values.data(), values.size(), sender, tag);
   }
   template <bool is_static>
   inline CommunicationRequest
   asyncReceive(CommunicationBufferTemplated<is_static> & values, Int sender,
                Int tag) const {
     return this->asyncReceiveImpl(values.data(), values.size(), sender, tag);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Collectives                                                              */
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void
   allReduce(Array<T> & values,
             SynchronizerOperation op = SynchronizerOperation::_sum) const {
     this->allReduceImpl(values.data(),
                         values.size() * values.getNbComponent(), op);
   }
 
   template <typename Derived>
   inline void
   allReduce(Eigen::MatrixBase<Derived> & values,
             SynchronizerOperation op = SynchronizerOperation::_sum) const {
     this->allReduceImpl(values.derived().data(), values.size(), op);
   }
 
   template <typename T>
   inline void
   allReduce(T & values, SynchronizerOperation op = SynchronizerOperation::_sum,
             std::enable_if_t<std::is_arithmetic<T>::value> * /*unused*/ =
                 nullptr) const {
     this->allReduceImpl(&values, 1, op);
   }
 
   template <typename T>
   inline void
   scan(Array<T> & values,
        SynchronizerOperation op = SynchronizerOperation::_sum) const {
     this->scanImpl(values.data(), values.data(),
                    values.size() * values.getNbComponent(), op);
   }
 
   template <typename Tensor>
   inline void
   scan(Tensor & values, SynchronizerOperation op,
        std::enable_if_t<aka::is_tensor<Tensor>::value> * /*unused*/ =
            nullptr) const {
     this->scanImpl(values.data(), values.data(), values.size(), op);
   }
 
   template <typename T>
   inline void scan(T & values,
                    SynchronizerOperation op = SynchronizerOperation::_sum,
                    std::enable_if_t<std::is_arithmetic<T>::value> * /*unused*/ =
                        nullptr) const {
     this->scanImpl(&values, &values, 1, op);
   }
 
   template <typename T>
   inline void
   exclusiveScan(Array<T> & values,
                 SynchronizerOperation op = SynchronizerOperation::_sum) const {
     this->exclusiveScanImpl(values.data(), values.data(),
                             values.size() * values.getNbComponent(), op);
   }
 
   template <typename Tensor>
   inline void
   exclusiveScan(Tensor & values,
                 SynchronizerOperation op = SynchronizerOperation::_sum,
                 std::enable_if_t<aka::is_tensor<Tensor>::value> * /*unused*/ =
                     nullptr) const {
     this->exclusiveScanImpl(values.data(), values.data(), values.size(),
                             op);
   }
 
   template <typename T>
   inline void
   exclusiveScan(T & values,
                 SynchronizerOperation op = SynchronizerOperation::_sum,
                 std::enable_if_t<std::is_arithmetic<T>::value> * /*unused*/ =
                     nullptr) const {
     this->exclusiveScanImpl(&values, &values, 1, op);
   }
 
   template <typename T>
   inline void
   exclusiveScan(T & values, T & result,
                 SynchronizerOperation op = SynchronizerOperation::_sum,
                 std::enable_if_t<std::is_arithmetic<T>::value> * /*unused*/ =
                     nullptr) const {
     this->exclusiveScanImpl(&values, &result, 1, op);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T> inline void allGather(Array<T> & values) const {
-    AKANTU_DEBUG_ASSERT(UInt(getNbProc()) == values.size(),
+    AKANTU_DEBUG_ASSERT(getNbProc() == values.size(),
                         "The array size is not correct");
     this->allGatherImpl(values.data(), values.getNbComponent());
   }
 
   template <typename Tensor,
             typename = std::enable_if_t<aka::is_tensor<Tensor>::value>>
   inline void allGather(Tensor & values) const {
     AKANTU_DEBUG_ASSERT(values.size() / getNbProc() > 0,
                         "The vector size is not correct");
     this->allGatherImpl(values.data(), values.size() / getNbProc());
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void allGatherV(Array<T> & values, const Array<Int> & sizes) const {
     this->allGatherVImpl(values.data(), sizes.data());
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void reduce(Array<T> & values, SynchronizerOperation op,
                      int root = 0) const {
     this->reduceImpl(values.data(), values.size() * values.getNbComponent(),
                      op, root);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename Tensor>
   inline void
   gather(Tensor & values, int root = 0,
          std::enable_if_t<aka::is_tensor<Tensor>::value> * /*unused*/ =
              nullptr) const {
     this->gatherImpl(values.data(), values.getNbComponent(), root);
   }
   template <typename T>
   inline void
   gather(T values, int root = 0,
          std::enable_if_t<std::is_arithmetic<T>::value> * /*unused*/ =
              nullptr) const {
     this->gatherImpl(&values, 1, root);
   }
   /* ------------------------------------------------------------------------ */
   template <typename Tensor, typename T>
   inline void
   gather(Tensor & values, Array<T> & gathered,
          std::enable_if_t<aka::is_tensor<Tensor>::value> * /*unused*/ =
              nullptr) const {
     AKANTU_DEBUG_ASSERT(values.size() == gathered.getNbComponent(),
                         "The array size is not correct");
     gathered.resize(getNbProc());
     this->gatherImpl(values.data(), values.size(), gathered.data(),
                      gathered.getNbComponent());
   }
 
   template <typename T>
   inline void
   gather(T values, Array<T> & gathered,
          std::enable_if_t<std::is_arithmetic<T>::value> * /*unused*/ =
              nullptr) const {
     this->gatherImpl(&values, 1, gathered.data(), 1);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void gatherV(Array<T> & values, const Array<Int> & sizes,
                       int root = 0) const {
     this->gatherVImpl(values.data(), sizes.data(), root);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void broadcast(Array<T> & values, int root = 0) const {
     this->broadcastImpl(values.data(),
                         values.size() * values.getNbComponent(), root);
   }
 
   template <typename T>
   inline void broadcast(std::vector<T> & values, int root = 0) const {
     this->broadcastImpl(values.data(), values.size(), root);
   }
 
   inline void broadcast(CommunicationBufferTemplated<true> & buffer,
                         int root = 0) const {
     this->broadcastImpl(buffer.data(), buffer.size(), root);
   }
 
   inline void broadcast(CommunicationBufferTemplated<false> & buffer,
                         int root = 0) const {
     UInt buffer_size = buffer.size();
     this->broadcastImpl(&buffer_size, 1, root);
     if (whoAmI() != root) {
       buffer.reserve(buffer_size);
     }
 
     if (buffer_size == 0) {
       return;
     }
     this->broadcastImpl(buffer.data(), buffer.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                                                         */
   /* ------------------------------------------------------------------------ */
   static bool test(CommunicationRequest & request);
   static bool testAll(std::vector<CommunicationRequest> & request);
   static void wait(CommunicationRequest & request);
   static void waitAll(std::vector<CommunicationRequest> & requests);
   static UInt waitAny(std::vector<CommunicationRequest> & requests);
   static inline void freeCommunicationRequest(CommunicationRequest & request);
   static inline void
   freeCommunicationRequest(std::vector<CommunicationRequest> & requests);
 
   template <typename T, typename MsgProcessor>
   inline void
   receiveAnyNumber(std::vector<CommunicationRequest> & send_requests,
                    MsgProcessor && processor, Int tag) 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, SynchronizerOperation op) const;
 
   template <typename T>
   void scanImpl(T * values, T * results, int nb_values,
                 SynchronizerOperation op) const;
 
   template <typename T>
   void exclusiveScanImpl(T * values, T * results, int nb_values,
                          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, 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;
   Int whoAmI() const;
 
   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:
   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/data_accessor.hh b/src/synchronizer/data_accessor.hh
index df3370722..0b42dc403 100644
--- a/src/synchronizer/data_accessor.hh
+++ b/src/synchronizer/data_accessor.hh
@@ -1,354 +1,354 @@
 /**
  * @file   data_accessor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Sep 01 2010
  * @date last modification: Fri Apr 09 2021
  *
  * @brief  Interface of accessors for pack_unpack system
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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;
 } // namespace akantu
 
 namespace akantu {
 
 class DataAccessorBase {
 public:
   DataAccessorBase() = default;
   virtual ~DataAccessorBase() = default;
 };
 
 template <class T> class DataAccessor : public virtual DataAccessorBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DataAccessor() = default;
   ~DataAccessor() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /**
    * @brief get  the number of  data to exchange  for a given array of T
    * (elements or dofs) and a given akantu::SynchronizationTag
    */
-  virtual UInt getNbData(const Array<T> & elements,
-                         const SynchronizationTag & tag) const = 0;
+  virtual Int getNbData(const Array<T> & elements,
+                        const SynchronizationTag & tag) const = 0;
 
   /**
    * @brief pack the data for a given array of T (elements or dofs) and a given
    * akantu::SynchronizationTag
    */
   virtual void packData(CommunicationBuffer & buffer, const Array<T> & element,
                         const SynchronizationTag & tag) const = 0;
 
   /**
    * @brief unpack the data for a given array of T (elements or dofs) and a
    * given akantu::SynchronizationTag
    */
   virtual void unpackData(CommunicationBuffer & buffer,
                           const Array<T> & element,
                           const SynchronizationTag & tag) = 0;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Specialization                                                             */
 /* -------------------------------------------------------------------------- */
 template <> class DataAccessor<Element> : public virtual DataAccessorBase {
 public:
   DataAccessor() = default;
   ~DataAccessor() override = default;
 
-  virtual UInt getNbData(const Array<Element> & elements,
-                         const SynchronizationTag & tag) const = 0;
+  virtual Int 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 {
+template <> class DataAccessor<Idx> : public virtual DataAccessorBase {
 public:
   DataAccessor() = default;
   ~DataAccessor() override = default;
 
-  virtual UInt getNbData(const Array<UInt> & elements,
-                         const SynchronizationTag & tag) const = 0;
+  virtual Int getNbData(const Array<Idx> & elements,
+                        const SynchronizationTag & tag) const = 0;
   virtual void packData(CommunicationBuffer & buffer,
-                        const Array<UInt> & element,
+                        const Array<Idx> & element,
                         const SynchronizationTag & tag) const = 0;
   virtual void unpackData(CommunicationBuffer & buffer,
-                          const Array<UInt> & element,
+                          const Array<Idx> & element,
                           const SynchronizationTag & tag) = 0;
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T, bool pack_helper>
   static void packUnpackDOFDataHelper(Array<T> & data,
                                       CommunicationBuffer & buffer,
-                                      const Array<UInt> & dofs);
+                                      const Array<Idx> & dofs);
 
   template <typename T>
   static inline void packDOFDataHelper(const Array<T> & data_to_pack,
                                        CommunicationBuffer & buffer,
-                                       const Array<UInt> & dofs) {
+                                       const Array<Idx> & 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) {
+                                         const Array<Idx> & 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 & /*unused*/, T & b) { return b; };
 };
 /* -------------------------------------------------------------------------- */
 
 
 /* -------------------------------------------------------------------------- */
 template <class Entity, template <class> class Op, class T>
 class ReduceDataAccessor : public virtual DataAccessor<Entity> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ReduceDataAccessor(Array<T> & data, const SynchronizationTag & tag)
       : data(data), tag(tag) {}
 
   ~ReduceDataAccessor() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
-  UInt getNbData(const Array<Entity> & entities,
+  Int getNbData(const Array<Entity> & entities,
                  const SynchronizationTag & tag) const override {
     if (tag != this->tag) {
       return 0;
     }
 
     Vector<T> tmp(data.getNbComponent());
     return entities.size() * CommunicationBuffer::sizeInBuffer(tmp);
   }
 
   /* ------------------------------------------------------------------------ */
   void packData(CommunicationBuffer & buffer, const Array<Entity> & entities,
                 const SynchronizationTag & tag) const override {
     if (tag != this->tag) {
       return;
     }
 
     auto data_it = data.begin(data.getNbComponent());
     for (auto el : entities) {
       buffer << Vector<T>(data_it[el]);
     }
   }
 
   /* ------------------------------------------------------------------------ */
   void unpackData(CommunicationBuffer & buffer, const Array<Entity> & entities,
                   const SynchronizationTag & tag) override {
     if (tag != this->tag) {
       return;
     }
 
     auto data_it = data.begin(data.getNbComponent());
     for (auto el : entities) {
       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 = ReduceDataAccessor<UInt, IdentityOperation, T>;
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 class SimpleElementDataAccessor : public virtual DataAccessor<Element> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SimpleElementDataAccessor(ElementTypeMapArray<T> & data,
                           const SynchronizationTag & tag)
       : data(data), tag(tag) {}
 
   ~SimpleElementDataAccessor() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   UInt getNbData(const Array<Element> & elements,
                  const SynchronizationTag & tag) const override {
     if (tag != this->tag)
       return 0;
 
     Int size = 0;
 
     for (auto & el : elements) {
       auto && data_type = data(el.type, el.ghost_type);
       size += sizeof(T) * data_type.getNbComponent();
     }
 
     return size;
   }
 
   /* ------------------------------------------------------------------------ */
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const SynchronizationTag & tag) const override {
     if (tag != this->tag)
       return;
 
     for (auto & el : elements) {
       auto && data_type = data(el.type, el.ghost_type);
       for (auto c : arange(data_type.getNbComponent())) {
         const auto & data_per_element = data_type(el.element, c);
         buffer << data_per_element;
       }
     }
   }
 
   /* ------------------------------------------------------------------------ */
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const SynchronizationTag & tag) override {
     if (tag != this->tag)
       return;
 
     for (auto & el : elements) {
       auto && data_type = data(el.type, el.ghost_type);
       for (auto c : arange(data_type.getNbComponent())) {
         auto & data_per_element = data_type(el.element, c);
         buffer >> data_per_element;
       }
     }
   }
 
 protected:
   /// data to (un)pack
   ElementTypeMapArray<T> & data;
 
   /// Tag to consider
   SynchronizationTag tag;
 };
 
 } // namespace akantu
 
 #endif /* AKANTU_DATA_ACCESSOR_HH_ */
diff --git a/src/synchronizer/element_synchronizer.hh b/src/synchronizer/element_synchronizer.hh
index 34f6e9de1..996d4e2b4 100644
--- a/src/synchronizer/element_synchronizer.hh
+++ b/src/synchronizer/element_synchronizer.hh
@@ -1,202 +1,202 @@
 /**
  * @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: Wed Mar 04 2020
  *
  * @brief  Main element synchronizer
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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",
                       bool register_to_event_manager = true,
                       EventHandlerPriority event_priority = _ehp_synchronizer);
 
   ElementSynchronizer(const ElementSynchronizer & other,
                       const ID & id = "element_synchronizer_copy",
                       bool register_to_event_manager = true,
                       EventHandlerPriority event_priority = _ehp_synchronizer);
 
 public:
   ~ElementSynchronizer() override;
 
   friend class ElementInfoPerProc;
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /// mesh event handler onElementsChanged
   void onElementsChanged(const Array<Element> & old_elements_list,
                          const Array<Element> & new_elements_list,
-                         const ElementTypeMapArray<UInt> & new_numbering,
+                         const ElementTypeMapArray<Idx> & new_numbering,
                          const ChangedElementsEvent & event) override;
 
   /// mesh event handler onRemovedElement
-  void onElementsRemoved(const Array<Element> & element_to_remove,
-                         const ElementTypeMapArray<UInt> & new_numbering,
+  void onElementsRemoved(const Array<Element> & element_list,
+                         const ElementTypeMapArray<Idx> & new_numbering,
                          const RemovedElementsEvent & event) override;
 
 protected:
   /// 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);
+  void renumberElements(const ElementTypeMapArray<Idx> & 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, ElementType el_type,
                      const Array<UInt> & partition_num);
 
   template <typename T>
   void fillTagBufferTemplated(const MeshData & mesh_data,
                               DynamicCommunicationBuffer * buffers,
                               const std::string & tag_name,
                               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, 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,
                                   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,
                                   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,
                                        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,
                                        ElementType type);
 
   /// function that handles the preexisting groups in the mesh
   static void synchronizeNodeGroupsMaster(ElementSynchronizer & communicator,
                                           UInt root, Mesh & mesh);
 
   /// function that handles the preexisting groups in the mesh
   static void synchronizeNodeGroupsSlaves(ElementSynchronizer & communicator,
                                           UInt root, Mesh & mesh);
 
   template <class CommunicationBuffer>
   static void fillNodeGroupsFromBuffer(ElementSynchronizer & communicator,
                                        Mesh & mesh,
                                        CommunicationBuffer & buffer);
 
   /// substitute elements in the send and recv arrays
   void
   substituteElements(const std::map<Element, Element> & old_to_new_elements);
 
   /* ------------------------------------------------------------------------ */
   /* Sanity checks                                                            */
   /* ------------------------------------------------------------------------ */
   UInt sanityCheckDataSize(const Array<Element> & elements,
                            const SynchronizationTag & tag,
                            bool from_comm_desc = true) const override;
   void packSanityCheckData(CommunicationBuffer & /*buffer*/,
                            const Array<Element> & /*elements*/,
                            const SynchronizationTag & /*tag*/) const override;
   void unpackSanityCheckData(CommunicationBuffer & /*buffer*/,
                              const Array<Element> & /*elements*/,
                              const SynchronizationTag & /*tag*/, UInt /*proc*/,
                              UInt /*rank*/) const override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Mesh, mesh, Mesh &);
   AKANTU_GET_MACRO(ElementToRank, element_to_prank,
                    const ElementTypeMapArray<Int> &);
 
   Int getRank(const Element & element) const final;
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// reference to the underlying mesh
   Mesh & mesh;
 
   friend class FacetSynchronizer;
 
   ElementTypeMapArray<Int> element_to_prank;
 };
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
 
 #endif /* AKANTU_ELEMENT_SYNCHRONIZER_HH_ */
diff --git a/src/synchronizer/synchronizer_impl_tmpl.hh b/src/synchronizer/synchronizer_impl_tmpl.hh
index 7bfe86d43..2b0e9d9a0 100644
--- a/src/synchronizer/synchronizer_impl_tmpl.hh
+++ b/src/synchronizer/synchronizer_impl_tmpl.hh
@@ -1,869 +1,869 @@
 /**
  * @file   synchronizer_impl_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 02 2016
  * @date last modification: Wed Dec 09 2020
  *
  * @brief  Implementation of the SynchronizerImpl
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_impl.hh"
+//#include "synchronizer_impl.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 SynchronizerImpl<Entity>::SynchronizerImpl(const Communicator & comm,
                                            const ID & id)
 
     : Synchronizer(comm, id), communications(comm) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 SynchronizerImpl<Entity>::SynchronizerImpl(const SynchronizerImpl & other,
                                            const ID & id)
     : Synchronizer(other), communications(other.communications) {
   this->id = id;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::communicateOnce(
     const std::tuple<CommunicationSendRecv, CommunicationSendRecv> &
         send_recv_schemes,
     const Tag::CommTags & comm_tag, DataAccessor<Entity> & data_accessor,
     const SynchronizationTag & tag) const {
   // no need to synchronize
   if (this->nb_proc == 1) {
     return;
   }
 
   CommunicationSendRecv send_dir;
   CommunicationSendRecv recv_dir;
   std::tie(send_dir, recv_dir) = send_recv_schemes;
 
   using CommunicationRequests = std::vector<CommunicationRequest>;
   using CommunicationBuffers = std::map<UInt, CommunicationBuffer>;
 
   CommunicationRequests send_requests;
   CommunicationRequests recv_requests;
   CommunicationBuffers send_buffers;
   CommunicationBuffers recv_buffers;
 
   auto postComm = [&](const auto & sr, auto & buffers,
                       auto & requests) -> void {
     for (auto && pair : communications.iterateSchemes(sr)) {
       auto & proc = pair.first;
       const auto & scheme = pair.second;
 
       if (scheme.empty()) {
         continue;
       }
 
       auto & buffer = buffers[proc];
 
       auto buffer_size = data_accessor.getNbData(scheme, tag);
       if (buffer_size == 0) {
         continue;
       }
 
 #ifndef AKANTU_NDEBUG
       buffer_size += this->sanityCheckDataSize(scheme, tag, false);
 #endif
 
       buffer.resize(buffer_size);
 
       if (sr == recv_dir) {
         requests.push_back(communicator.asyncReceive(
             buffer, proc,
             Tag::genTag(this->rank, UInt(tag), comm_tag, this->hash_id)));
       } else {
 #ifndef AKANTU_NDEBUG
         this->packSanityCheckData(buffer, scheme, tag);
 #endif
         data_accessor.packData(buffer, scheme, tag);
 
         AKANTU_DEBUG_ASSERT(
             buffer.getPackedSize() == buffer.size(),
             "The data accessor did not pack all the data it "
             "promised  in communication with tag "
                 << tag << " (Promised: " << buffer.size()
                 << "bytes, packed: " << buffer.getPackedSize() << "bytes [avg: "
                 << Real(buffer.size() - buffer.getPackedSize()) / scheme.size()
                 << "bytes per entity missing])");
 
         send_requests.push_back(communicator.asyncSend(
             buffer, proc,
             Tag::genTag(proc, UInt(tag), comm_tag, this->hash_id)));
       }
     }
   };
 
   // post the receive requests
   postComm(recv_dir, recv_buffers, recv_requests);
 
   // post the send data requests
   postComm(send_dir, send_buffers, send_requests);
 
   // treat the receive requests
   UInt request_ready;
   while ((request_ready = Communicator::waitAny(recv_requests)) != UInt(-1)) {
     auto & req = recv_requests[request_ready];
     auto proc = req.getSource();
 
     auto & buffer = recv_buffers[proc];
     const auto & scheme = this->communications.getScheme(proc, recv_dir);
 
 #ifndef AKANTU_NDEBUG
     this->unpackSanityCheckData(buffer, scheme, tag, proc, this->rank);
 #endif
 
     data_accessor.unpackData(buffer, scheme, tag);
 
     AKANTU_DEBUG_ASSERT(
         buffer.getLeftToUnpack() == 0,
         "The data accessor ignored some data in communication with tag "
             << tag);
 
     req.free();
     recv_requests.erase(recv_requests.begin() + request_ready);
   }
 
   Communicator::waitAll(send_requests);
   Communicator::freeCommunicationRequest(send_requests);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::slaveReductionOnceImpl(
     DataAccessor<Entity> & data_accessor,
     const SynchronizationTag & tag) const {
   communicateOnce(std::make_tuple(_recv, _send), Tag::_reduce, data_accessor,
                   tag);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::synchronizeOnceImpl(
     DataAccessor<Entity> & data_accessor,
     const SynchronizationTag & tag) const {
   communicateOnce(std::make_tuple(_send, _recv), Tag::_synchronize,
                   data_accessor, tag);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::asynchronousSynchronizeImpl(
     const DataAccessor<Entity> & data_accessor,
     const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   if (not this->communications.hasCommunicationSize(tag)) {
     this->computeBufferSize(data_accessor, tag);
   }
 
   this->communications.incrementCounter(tag);
 
   // Posting the receive -------------------------------------------------------
   if (this->communications.hasPendingRecv(tag)) {
     AKANTU_CUSTOM_EXCEPTION_INFO(
         debug::CommunicationException(),
         "There must still be some pending receive communications."
             << " Tag is " << tag << " Cannot start new ones");
   }
 
   for (auto && comm_desc : this->communications.iterateRecv(tag)) {
     comm_desc.postRecv(this->hash_id);
   }
 
   // Posting the sends -------------------------------------------------------
   if (communications.hasPendingSend(tag)) {
     AKANTU_CUSTOM_EXCEPTION_INFO(
         debug::CommunicationException(),
         "There must be some pending sending communications."
             << " Tag is " << tag);
   }
 
   for (auto && comm_desc : this->communications.iterateSend(tag)) {
     comm_desc.resetBuffer();
 
 #ifndef AKANTU_NDEBUG
     this->packSanityCheckData(comm_desc);
 #endif
 
     comm_desc.packData(data_accessor);
     comm_desc.postSend(this->hash_id);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::waitEndSynchronizeImpl(
     DataAccessor<Entity> & data_accessor, const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
 #ifndef AKANTU_NDEBUG
   if (this->communications.begin(tag, _recv) !=
           this->communications.end(tag, _recv) &&
       !this->communications.hasPendingRecv(tag)) {
     AKANTU_CUSTOM_EXCEPTION_INFO(debug::CommunicationException(),
                                  "No pending communication with the tag \""
                                      << tag);
   }
 #endif
 
   auto recv_end = this->communications.end(tag, _recv);
   decltype(recv_end) recv_it;
 
   while ((recv_it = this->communications.waitAnyRecv(tag)) != recv_end) {
     auto && comm_desc = *recv_it;
 #ifndef AKANTU_NDEBUG
     this->unpackSanityCheckData(comm_desc);
 #endif
 
     comm_desc.unpackData(data_accessor);
     comm_desc.resetBuffer();
     comm_desc.freeRequest();
   }
 
   this->communications.waitAllSend(tag);
   this->communications.freeSendRequests(tag);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::computeAllBufferSizes(
     const DataAccessor<Entity> & data_accessor) {
   for (auto && tag : this->communications.iterateTags()) {
     this->computeBufferSize(data_accessor, tag);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::computeBufferSizeImpl(
     const DataAccessor<Entity> & data_accessor,
     const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   if (not this->communications.hasCommunication(tag)) {
     this->communications.initializeCommunications(tag);
     AKANTU_DEBUG_ASSERT(communications.hasCommunication(tag) == true,
                         "Communications where not properly initialized");
   }
 
   for (auto sr : iterate_send_recv) {
     for (auto && pair : this->communications.iterateSchemes(sr)) {
       auto proc = pair.first;
       const auto & scheme = pair.second;
       UInt size = 0;
 #ifndef AKANTU_NDEBUG
       size += this->sanityCheckDataSize(scheme, tag);
 #endif
       size += data_accessor.getNbData(scheme, tag);
       AKANTU_DEBUG_INFO("I have "
                         << size << "(" << printMemorySize<char>(size) << " - "
                         << scheme.size() << " element(s)) data to "
                         << std::string(sr == _recv ? "receive from" : "send to")
                         << proc << " for tag " << tag);
 
       this->communications.setCommunicationSize(tag, proc, size, sr);
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename Entity> void SynchronizerImpl<Entity>::reset() {
   AKANTU_DEBUG_IN();
   communications.resetSchemes();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename Entity>
 template <typename Pred>
 void SynchronizerImpl<Entity>::split(SynchronizerImpl<Entity> & in_synchronizer,
                                      Pred && pred) {
   AKANTU_DEBUG_IN();
 
   auto filter_list = [&](auto & list, auto & new_list) {
     auto copy = list;
     list.resize(0);
     new_list.resize(0);
 
     for (auto && entity : copy) {
       if (std::forward<Pred>(pred)(entity)) {
         new_list.push_back(entity);
       } else {
         list.push_back(entity);
       }
     }
   };
 
   for (auto sr : iterate_send_recv) {
     for (auto & scheme_pair :
          in_synchronizer.communications.iterateSchemes(sr)) {
       auto proc = scheme_pair.first;
       auto & scheme = scheme_pair.second;
       auto & new_scheme = communications.createScheme(proc, sr);
       filter_list(scheme, new_scheme);
     }
   }
 
   in_synchronizer.communications.invalidateSizes();
   communications.invalidateSizes();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename Entity>
 template <typename Updater>
 void SynchronizerImpl<Entity>::updateSchemes(Updater && scheme_updater) {
   for (auto sr : iterate_send_recv) {
     for (auto & scheme_pair : communications.iterateSchemes(sr)) {
       auto proc = scheme_pair.first;
       auto & scheme = scheme_pair.second;
       std::forward<Updater>(scheme_updater)(scheme, proc, sr);
     }
   }
 
   communications.invalidateSizes();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename Entity>
 template <typename Pred>
 void SynchronizerImpl<Entity>::filterScheme(Pred && pred) {
   std::vector<CommunicationRequest> requests;
   std::unordered_map<UInt, Array<UInt>> keep_entities;
 
   auto filter_list = [](const auto & keep, auto & list) {
     Array<Entity> new_list;
     for (const auto & keep_entity : keep) {
       const Entity & entity = list(keep_entity);
       new_list.push_back(entity);
     }
     list.copy(new_list);
   };
 
   // loop over send_schemes
   for (auto & scheme_pair : communications.iterateSchemes(_recv)) {
     auto proc = scheme_pair.first;
     auto & scheme = scheme_pair.second;
 
     auto & keep_entity = keep_entities[proc];
     for (auto && entity : enumerate(scheme)) {
       if (pred(std::get<1>(entity))) {
         keep_entity.push_back(std::get<0>(entity));
       }
     }
 
     auto tag = Tag::genTag(this->rank, 0, Tag::_modify_scheme);
     AKANTU_DEBUG_INFO("I have " << keep_entity.size()
                                 << " elements to still receive from processor "
                                 << proc << " (communication tag : " << tag
                                 << ")");
 
     filter_list(keep_entity, scheme);
     requests.push_back(communicator.asyncSend(keep_entity, proc, tag));
   }
 
   // clean the receive scheme
   for (auto & scheme_pair : communications.iterateSchemes(_send)) {
     auto proc = scheme_pair.first;
     auto & scheme = scheme_pair.second;
 
     auto tag = Tag::genTag(proc, 0, Tag::_modify_scheme);
     AKANTU_DEBUG_INFO("Waiting list of elements to keep from processor "
                       << proc << " (communication tag : " << tag << ")");
 
     CommunicationStatus status;
     communicator.probe<UInt>(proc, tag, status);
 
     Array<UInt> keep_entity(status.size(), 1, "keep_element");
     AKANTU_DEBUG_INFO("I have "
                       << keep_entity.size()
                       << " elements to keep in my send list to processor "
                       << proc << " (communication tag : " << tag << ")");
 
     communicator.receive(keep_entity, proc, tag);
 
     filter_list(keep_entity, scheme);
   }
 
   Communicator::waitAll(requests);
   Communicator::freeCommunicationRequest(requests);
   communications.invalidateSizes();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity> void SynchronizerImpl<Entity>::swapSendRecv() {
   communications.swapSendRecv();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::copySchemes(const SynchronizerImpl & other) {
   reset();
 
   for (auto sr : iterate_send_recv) {
     for (auto & scheme_pair : other.communications.iterateSchemes(sr)) {
       auto proc = scheme_pair.first;
       auto & other_scheme = scheme_pair.second;
       auto & scheme = communications.createScheme(proc, sr);
       scheme.copy(other_scheme);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 SynchronizerImpl<Entity> &
 SynchronizerImpl<Entity>::operator=(const SynchronizerImpl & other) {
   copySchemes(other);
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 UInt SynchronizerImpl<Entity>::sanityCheckDataSize(
     const Array<Entity> & /*unused*/, const SynchronizationTag & /*unused*/,
     bool is_comm_desc) const {
   if (not is_comm_desc) {
     return 0;
   }
 
   UInt size = 0;
   size += sizeof(SynchronizationTag); // tag
   size += sizeof(UInt);               // comm_desc.getNbData();
   size += sizeof(UInt);               // comm_desc.getProc();
   size += sizeof(this->rank);         // mesh.getCommunicator().whoAmI();
 
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::packSanityCheckData(
     CommunicationDescriptor<Entity> & comm_desc) const {
   auto & buffer = comm_desc.getBuffer();
   buffer << comm_desc.getTag();
   buffer << comm_desc.getNbData();
   buffer << comm_desc.getProc();
   buffer << this->rank;
 
   const auto & tag = comm_desc.getTag();
   const auto & send_element = comm_desc.getScheme();
 
   this->packSanityCheckData(buffer, send_element, tag);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::unpackSanityCheckData(
     CommunicationDescriptor<Entity> & comm_desc) const {
   auto & buffer = comm_desc.getBuffer();
   const auto & tag = comm_desc.getTag();
 
   auto nb_data = comm_desc.getNbData();
   auto proc = comm_desc.getProc();
   auto rank = this->rank;
 
   decltype(nb_data) recv_nb_data;
   decltype(proc) recv_proc;
   decltype(rank) recv_rank;
 
   SynchronizationTag t;
   buffer >> t;
   buffer >> recv_nb_data;
   buffer >> recv_proc;
   buffer >> recv_rank;
 
   AKANTU_DEBUG_ASSERT(
       t == tag, "The tag received does not correspond to the tag expected");
 
   AKANTU_DEBUG_ASSERT(
       nb_data == recv_nb_data,
       "The nb_data received does not correspond to the nb_data expected");
 
   AKANTU_DEBUG_ASSERT(UInt(recv_rank) == proc,
                       "The rank received does not correspond to the proc");
 
   AKANTU_DEBUG_ASSERT(recv_proc == UInt(rank),
                       "The proc received does not correspond to the rank");
 
   auto & recv_element = comm_desc.getScheme();
   this->unpackSanityCheckData(buffer, recv_element, tag, proc, rank);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity> bool SynchronizerImpl<Entity>::hasChanged() {
   communicator.allReduce(entities_changed, SynchronizerOperation::_lor);
   return entities_changed;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 void SynchronizerImpl<Entity>::initScatterGatherCommunicationScheme() {
   if (this->nb_proc == 1) {
     entities_changed = false;
     AKANTU_DEBUG_OUT();
     return;
   }
 
   AKANTU_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void SynchronizerImpl<UInt>::initScatterGatherCommunicationScheme() {
   AKANTU_DEBUG_IN();
 
   if (this->nb_proc == 1) {
     entities_changed = false;
     AKANTU_DEBUG_OUT();
     return;
   }
 
   this->entities_from_root.clear();
   this->master_receive_entities.clear();
 
   Array<UInt> entities_to_send;
   fillEntityToSend(entities_to_send);
 
   std::vector<CommunicationRequest> requests;
 
   if (this->rank == UInt(this->root)) {
     master_receive_entities[this->root].copy(entities_to_send);
 
-    Array<UInt> nb_entities_per_proc(this->nb_proc);
+    Array<Int> nb_entities_per_proc(this->nb_proc);
     communicator.gather(entities_to_send.size(), nb_entities_per_proc);
 
     for (UInt p = 0; p < nb_proc; ++p) {
       if (p == UInt(this->root)) {
         continue;
       }
 
       auto & receive_per_proc = master_receive_entities[p];
       receive_per_proc.resize(nb_entities_per_proc(p));
       if (nb_entities_per_proc(p) == 0) {
         continue;
       }
 
       requests.push_back(communicator.asyncReceive(
           receive_per_proc, p,
           Tag::genTag(p, 0, Tag::_gather_initialization, this->hash_id)));
     }
   } else {
     communicator.gather(entities_to_send.size(), this->root);
     AKANTU_DEBUG(dblDebug, "I have " << entities_to_send.size()
                                      << " entities to send to master proc");
 
     if (not entities_to_send.empty()) {
       requests.push_back(communicator.asyncSend(
           entities_to_send, this->root,
           Tag::genTag(this->rank, 0, Tag::_gather_initialization,
                       this->hash_id)));
     }
   }
 
   entities_changed = false;
   Communicator::waitAll(requests);
   Communicator::freeCommunicationRequest(requests);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 template <typename T>
 void SynchronizerImpl<Entity>::gather(const Array<T> & to_gather,
                                       Array<T> & gathered) {
   if (this->hasChanged()) {
     initScatterGatherCommunicationScheme();
   }
 
   AKANTU_DEBUG_ASSERT(this->rank == UInt(this->root),
                       "This function cannot be called on a slave processor");
   AKANTU_DEBUG_ASSERT(to_gather.size() == this->canScatterSize(),
                       "The array to gather does not have the correct size");
   AKANTU_DEBUG_ASSERT(gathered.size() == this->gatheredSize(),
                       "The gathered array does not have the correct size");
 
   if (this->nb_proc == 1) {
     gathered.copy(to_gather, true);
 
     AKANTU_DEBUG_OUT();
     return;
   }
 
   std::map<UInt, CommunicationBuffer> buffers;
   std::vector<CommunicationRequest> requests;
   for (UInt p = 0; p < this->nb_proc; ++p) {
     if (p == UInt(this->root)) {
       continue;
     }
 
     auto receive_it = this->master_receive_entities.find(p);
     AKANTU_DEBUG_ASSERT(receive_it != this->master_receive_entities.end(),
                         "Could not find the receive list for dofs of proc "
                             << p);
     const auto & receive_entities = receive_it->second;
     if (receive_entities.empty()) {
       continue;
     }
 
     CommunicationBuffer & buffer = buffers[p];
 
     buffer.resize(receive_entities.size() * to_gather.getNbComponent() *
                   sizeof(T));
 
     AKANTU_DEBUG_INFO(
         "Preparing to receive data for "
         << receive_entities.size() << " entities from processor " << p << " "
         << Tag::genTag(p, this->root, Tag::_gather, this->hash_id));
 
     requests.push_back(communicator.asyncReceive(
         buffer, p, Tag::genTag(p, this->root, Tag::_gather, this->hash_id)));
   }
 
   auto data_gathered_it = gathered.begin(to_gather.getNbComponent());
 
   { // copy master data
     auto data_to_gather_it = to_gather.begin(to_gather.getNbComponent());
     for (auto local_entity : entities_from_root) {
       UInt global_entity = localToGlobalEntity(local_entity);
 
       Vector<T> entity_data_gathered = data_gathered_it[global_entity];
       Vector<T> entity_data_to_gather = data_to_gather_it[local_entity];
       entity_data_gathered = entity_data_to_gather;
     }
   }
 
   auto rr = UInt(-1);
   while ((rr = Communicator::waitAny(requests)) != UInt(-1)) {
     auto & request = requests[rr];
     auto sender = request.getSource();
 
     AKANTU_DEBUG_ASSERT(this->master_receive_entities.find(sender) !=
                                 this->master_receive_entities.end() &&
                             buffers.find(sender) != buffers.end(),
                         "Missing infos concerning proc " << sender);
 
     const auto & receive_entities =
         this->master_receive_entities.find(sender)->second;
     auto & buffer = buffers[sender];
 
     for (auto global_entity : receive_entities) {
       Vector<T> entity_data = data_gathered_it[global_entity];
       buffer >> entity_data;
     }
 
     requests.erase(requests.begin() + rr);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 template <typename T>
 void SynchronizerImpl<Entity>::gather(const Array<T> & to_gather) {
   AKANTU_DEBUG_IN();
 
   if (this->hasChanged()) {
     initScatterGatherCommunicationScheme();
   }
 
   AKANTU_DEBUG_ASSERT(this->rank != UInt(this->root),
                       "This function cannot be called on the root processor");
   AKANTU_DEBUG_ASSERT(to_gather.size() == this->canScatterSize(),
                       "The array to gather does not have the correct size");
 
   if (this->entities_from_root.empty()) {
     AKANTU_DEBUG_OUT();
     return;
   }
   CommunicationBuffer buffer(this->entities_from_root.size() *
                              to_gather.getNbComponent() * sizeof(T));
 
   auto data_it = to_gather.begin(to_gather.getNbComponent());
   for (auto entity : this->entities_from_root) {
     Vector<T> data = data_it[entity];
     buffer << data;
   }
 
   AKANTU_DEBUG_INFO("Gathering data for "
                     << to_gather.size() << " dofs on processor " << this->root
                     << " "
                     << Tag::genTag(this->rank, 0, Tag::_gather, this->hash_id));
 
   communicator.send(buffer, this->root,
                     Tag::genTag(this->rank, 0, Tag::_gather, this->hash_id));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 template <typename T>
 void SynchronizerImpl<Entity>::scatter(Array<T> & scattered,
                                        const Array<T> & to_scatter) {
   AKANTU_DEBUG_IN();
 
   if (this->hasChanged()) {
     initScatterGatherCommunicationScheme();
   }
 
   AKANTU_DEBUG_ASSERT(this->rank == UInt(this->root),
                       "This function cannot be called on a slave processor");
   AKANTU_DEBUG_ASSERT(scattered.size() == this->canScatterSize(),
                       "The scattered array does not have the correct size");
   AKANTU_DEBUG_ASSERT(to_scatter.size() == this->gatheredSize(),
                       "The array to scatter does not have the correct size");
 
   if (this->nb_proc == 1) {
     scattered.copy(to_scatter, true);
     AKANTU_DEBUG_OUT();
     return;
   }
 
   std::map<UInt, CommunicationBuffer> buffers;
   std::vector<CommunicationRequest> requests;
 
   for (UInt p = 0; p < nb_proc; ++p) {
     auto data_to_scatter_it = to_scatter.begin(to_scatter.getNbComponent());
 
     if (p == this->rank) {
       auto data_scattered_it = scattered.begin(to_scatter.getNbComponent());
 
       // copy the data for the local processor
       for (auto local_entity : entities_from_root) {
         auto global_entity = localToGlobalEntity(local_entity);
 
         Vector<T> entity_data_to_scatter = data_to_scatter_it[global_entity];
         Vector<T> entity_data_scattered = data_scattered_it[local_entity];
         entity_data_scattered = entity_data_to_scatter;
       }
 
       continue;
     }
 
     const auto & receive_entities =
         this->master_receive_entities.find(p)->second;
 
     // prepare the send buffer
     CommunicationBuffer & buffer = buffers[p];
     buffer.resize(receive_entities.size() * scattered.getNbComponent() *
                   sizeof(T));
 
     // pack the data
     for (auto global_entity : receive_entities) {
       Vector<T> entity_data_to_scatter = data_to_scatter_it[global_entity];
       buffer << entity_data_to_scatter;
     }
 
     // send the data
     requests.push_back(communicator.asyncSend(
         buffer, p, Tag::genTag(p, 0, Tag::_scatter, this->hash_id)));
   }
 
   // wait a clean communications
   Communicator::waitAll(requests);
   Communicator::freeCommunicationRequest(requests);
 
   // synchronize slave and ghost nodes
   synchronizeArray(scattered);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 template <typename T>
 void SynchronizerImpl<Entity>::scatter(Array<T> & scattered) {
   AKANTU_DEBUG_IN();
 
   if (this->hasChanged()) {
     this->initScatterGatherCommunicationScheme();
   }
 
   AKANTU_DEBUG_ASSERT(this->rank != UInt(this->root),
                       "This function cannot be called on the root processor");
   AKANTU_DEBUG_ASSERT(scattered.size() == this->canScatterSize(),
                       "The scattered array does not have the correct size");
 
   // prepare the data
   auto data_scattered_it = scattered.begin(scattered.getNbComponent());
   CommunicationBuffer buffer(this->entities_from_root.size() *
                              scattered.getNbComponent() * sizeof(T));
 
   // receive the data
   communicator.receive(
       buffer, this->root,
       Tag::genTag(this->rank, 0, Tag::_scatter, this->hash_id));
 
   // unpack the data
   for (auto local_entity : entities_from_root) {
     Vector<T> data_scattered(data_scattered_it[local_entity]);
     buffer >> data_scattered;
   }
 
   // synchronize the ghosts
   synchronizeArray(scattered);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 template <typename T>
 void SynchronizerImpl<Entity>::synchronizeArray(Array<T> & array) const {
   static_assert(std::is_same<Entity, UInt>::value,
                 "Not implemented for other type than UInt");
   SimpleUIntDataAccessor<T> data_accessor(array, SynchronizationTag::_whatever);
   this->synchronizeOnce(data_accessor, SynchronizationTag::_whatever);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Entity>
 template <template <class> class Op, typename T>
 void SynchronizerImpl<Entity>::reduceSynchronizeArray(Array<T> & array) const {
   static_assert(std::is_same<Entity, UInt>::value,
                 "Not implemented for other type than UInt");
   ReduceDataAccessor<UInt, Op, T> data_accessor(array,
                                                 SynchronizationTag::_whatever);
   this->slaveReductionOnceImpl(data_accessor, SynchronizationTag::_whatever);
   this->synchronizeArray(array);
 }
 
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
diff --git a/test/test_common/test_voigt_helper.cc b/test/test_common/test_voigt_helper.cc
index e9445d361..fd9b4760f 100644
--- a/test/test_common/test_voigt_helper.cc
+++ b/test/test_common/test_voigt_helper.cc
@@ -1,164 +1,164 @@
 /**
  * @file   test_voigt_helper.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 27 2019
  * @date last modification:  Wed Nov 18 2020
  *
  * @brief  unit tests for VoigtHelper
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "test_gtest_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <aka_voigthelper.hh>
 /* -------------------------------------------------------------------------- */
 #include <gtest/gtest.h>
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 template <class Dim_v> class VoigtHelperFixture : public ::testing::Test {
 protected:
   using voigt_h = VoigtHelper<Dim_v::value>;
   constexpr static UInt dim = Dim_v::value;
 
   VoigtHelperFixture() {
     switch (this->dim) {
     case 1: {
       indices.push_back({0, 0});
       matrix = Matrix<Real>{{10}};
       vector = Vector<Real>{10};
       vector_factor = Vector<Real>{10};
       break;
     }
     case 2: {
       indices.push_back({0, 0});
       indices.push_back({1, 1});
       indices.push_back({0, 1});
 
       matrix = Matrix<Real>{{10, 33}, {0, 56}};
       vector = Vector<Real>{10, 56, 33};
       vector_factor = Vector<Real>{10, 56, 2 * 33};
       break;
     }
     case 3: {
       indices.push_back({0, 0});
       indices.push_back({1, 1});
       indices.push_back({2, 2});
       indices.push_back({1, 2});
       indices.push_back({0, 2});
       indices.push_back({0, 1});
 
       matrix = Matrix<Real>{{10, 33, 20}, {0, 56, 27}, {0, 0, 98}};
       vector = Vector<Real>{10, 56, 98, 27, 20, 33};
       vector_factor = Vector<Real>{10, 56, 98, 2 * 27, 2 * 20, 2 * 33};
       break;
     }
     }
   }
 
   void SetUp() override {}
 
   std::vector<std::pair<UInt, UInt>> indices;
   Matrix<Real> matrix;
   Vector<Real> vector;
   Vector<Real> vector_factor;
 };
 
-template <UInt dim>
+template <Int dim>
 using spatial_dimension_t = std::integral_constant<UInt, dim>;
 
 using TestTypes =
     ::testing::Types<spatial_dimension_t<1>, spatial_dimension_t<2>,
                      spatial_dimension_t<3>>;
 TYPED_TEST_SUITE(VoigtHelperFixture, TestTypes, );
 
 TYPED_TEST(VoigtHelperFixture, Size) {
   using voigt_h = typename TestFixture::voigt_h;
   switch (this->dim) {
   case 1:
     EXPECT_EQ(voigt_h::size, 1);
     break;
   case 2:
     EXPECT_EQ(voigt_h::size, 3);
     break;
   case 3:
     EXPECT_EQ(voigt_h::size, 6);
     break;
   }
 }
 
 TYPED_TEST(VoigtHelperFixture, Indicies) {
   using voigt_h = typename TestFixture::voigt_h;
 
   for (UInt I = 0; I < voigt_h::size; ++I) {
     EXPECT_EQ(this->indices[I].first, voigt_h::vec[I][0]);
     EXPECT_EQ(this->indices[I].second, voigt_h::vec[I][1]);
   }
 }
 
 TYPED_TEST(VoigtHelperFixture, Factors) {
   using voigt_h = typename TestFixture::voigt_h;
   for (UInt I = 0; I < voigt_h::size; ++I) {
     if (I < this->dim) {
       EXPECT_EQ(voigt_h::factors[I], 1);
     } else {
       EXPECT_EQ(voigt_h::factors[I], 2);
     }
   }
 }
 
 TYPED_TEST(VoigtHelperFixture, MatrixToVoight) {
   using voigt_h = typename TestFixture::voigt_h;
 
   auto voigt = voigt_h::matrixToVoigt(this->matrix);
 
   for (UInt I = 0; I < voigt_h::size; ++I) {
     EXPECT_EQ(voigt(I), this->vector(I));
   }
 }
 
 TYPED_TEST(VoigtHelperFixture, MatrixToVoightFactors) {
   using voigt_h = typename TestFixture::voigt_h;
 
   auto voigt = voigt_h::matrixToVoigtWithFactors(this->matrix);
 
   for (UInt I = 0; I < voigt_h::size; ++I) {
     EXPECT_EQ(voigt(I), this->vector_factor(I));
   }
 }
 
 TYPED_TEST(VoigtHelperFixture, VoightToMatrix) {
   using voigt_h = typename TestFixture::voigt_h;
 
   auto matrix = voigt_h::voigtToMatrix(this->vector);
 
   for (UInt i = 0; i < this->dim; ++i) {
     for (UInt j = 0; j < this->dim; ++j) {
       EXPECT_EQ(matrix(i, j), this->matrix(std::min(i, j), std::max(i, j)));
     }
   }
 }
diff --git a/test/test_model/test_common/test_non_local_toolbox/test_material.cc b/test/test_model/test_common/test_non_local_toolbox/test_material.cc
index 654f808c3..6aa13cd33 100644
--- a/test/test_model/test_common/test_non_local_toolbox/test_material.cc
+++ b/test/test_model/test_common/test_non_local_toolbox/test_material.cc
@@ -1,57 +1,57 @@
 /**
  * @file   test_material.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
  * @date last modification:  Wed Jan 30 2019
  *
  * @brief  Implementation of test material for the non-local neighborhood base
  * test
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "test_material.hh"
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 TestMaterial<dim>::TestMaterial(SolidMechanicsModel & model, const ID & id)
     : Parent(model, id), grad_u_nl("grad_u non local", *this) {
   this->is_non_local = true;
   this->grad_u_nl.initialize(dim * dim);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void TestMaterial<dim>::registerNonLocalVariables() {
+template <Int dim> void TestMaterial<dim>::registerNonLocalVariables() {
   this->model.getNonLocalManager().registerNonLocalVariable(
       this->gradu.getName(), grad_u_nl.getName(), dim * dim);
 
   this->model.getNonLocalManager()
       .getNeighborhood(this->getNeighborhoodName())
       .registerNonLocalVariable(grad_u_nl.getName());
 }
 
 /* -------------------------------------------------------------------------- */
 // Instantiate the material for the 3 dimensions
 INSTANTIATE_MATERIAL(test_material, TestMaterial);
 /* -------------------------------------------------------------------------- */
diff --git a/test/test_model/test_common/test_non_local_toolbox/test_material.hh b/test/test_model/test_common/test_non_local_toolbox/test_material.hh
index 9b0130132..55b8e09a5 100644
--- a/test/test_model/test_common/test_non_local_toolbox/test_material.hh
+++ b/test/test_model/test_common/test_non_local_toolbox/test_material.hh
@@ -1,73 +1,73 @@
 /**
  * @file   test_material.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Sun Oct 19 2014
  * @date last modification:  Wed Jan 30 2019
  *
  * @brief  test material for the non-local neighborhood base test
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_damage.hh"
 #include "material_damage_non_local.hh"
 
 #ifndef TEST_MATERIAL_HH_
 #define TEST_MATERIAL_HH_
 
 using namespace akantu;
 
-template <UInt dim>
+template <Int dim>
 class TestMaterial
     : public MaterialDamageNonLocal<dim, MaterialDamage<dim, MaterialElastic>> {
   /* ------------------------------------------------------------------------ */
   /* Constructor/Destructor */
   /* ------------------------------------------------------------------------ */
 public:
   using Parent =
       MaterialDamageNonLocal<dim, MaterialDamage<dim, MaterialElastic>>;
 
   TestMaterial(SolidMechanicsModel & model, const ID & id);
 
   /* ------------------------------------------------------------------------ */
   /* Methods */
   /* ------------------------------------------------------------------------ */
 public:
   void registerNonLocalVariables() override final;
 
   void computeNonLocalStress(ElementType, GhostType) override final{};
 
   void computeNonLocalStresses(GhostType) override final{};
 
 protected:
   ID getNeighborhoodName() override { return "test_region"; }
 
   /* ------------------------------------------------------------------------ */
   /* Members */
   /* ------------------------------------------------------------------------ */
 private:
   InternalField<Real> grad_u_nl;
 };
 
 #endif /* TEST_MATERIAL_HH_ */
diff --git a/test/test_model/test_common/test_non_local_toolbox/test_material_damage.cc b/test/test_model/test_common/test_non_local_toolbox/test_material_damage.cc
index b64e75bfa..34c4366af 100644
--- a/test/test_model/test_common/test_non_local_toolbox/test_material_damage.cc
+++ b/test/test_model/test_common/test_non_local_toolbox/test_material_damage.cc
@@ -1,59 +1,59 @@
 /**
  * @file   test_material_damage.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
  * @date last modification:  Wed Jan 30 2019
  *
  * @brief  Implementation of test material damage
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "test_material_damage.hh"
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 TestMaterialDamage<dim>::TestMaterialDamage(SolidMechanicsModel & model,
                                             const ID & id)
     : Parent(model, id), grad_u_nl("grad_u non local", *this) {
   this->is_non_local = true;
   this->grad_u_nl.initialize(dim * dim);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void TestMaterialDamage<dim>::registerNonLocalVariables() {
+template <Int dim> void TestMaterialDamage<dim>::registerNonLocalVariables() {
   this->model.getNonLocalManager().registerNonLocalVariable(
       this->gradu.getName(), grad_u_nl.getName(), dim * dim);
 
   this->model.getNonLocalManager()
       .getNeighborhood(this->getNeighborhoodName())
       .registerNonLocalVariable(grad_u_nl.getName());
 }
 
 /* -------------------------------------------------------------------------- */
 // Instantiate the material for the 3 dimensions
 INSTANTIATE_MATERIAL(test_material, TestMaterialDamage);
 /* -------------------------------------------------------------------------- */
diff --git a/test/test_model/test_common/test_non_local_toolbox/test_material_damage.hh b/test/test_model/test_common/test_non_local_toolbox/test_material_damage.hh
index 6b1c38081..725c6e042 100644
--- a/test/test_model/test_common/test_non_local_toolbox/test_material_damage.hh
+++ b/test/test_model/test_common/test_non_local_toolbox/test_material_damage.hh
@@ -1,75 +1,75 @@
 /**
  * @file   test_material_damage.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Oct 19 2014
  * @date last modification:  Wed Jan 30 2019
  *
  * @brief  test material damage for the non-local remove damage test
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_damage.hh"
 #include "material_damage_non_local.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef TEST_MATERIAL_DAMAGE_HH_
 #define TEST_MATERIAL_DAMAGE_HH_
 
 using namespace akantu;
 
-template <UInt dim>
+template <Int dim>
 class TestMaterialDamage
     : public MaterialDamageNonLocal<dim, MaterialDamage<dim, MaterialElastic>> {
 
   using Parent =
       MaterialDamageNonLocal<dim, MaterialDamage<dim, MaterialElastic>>;
 
   /* ------------------------------------------------------------------------ */
   /* Constructor/Destructor */
   /* ------------------------------------------------------------------------ */
 public:
   TestMaterialDamage(SolidMechanicsModel & model, const ID & id);
   /* ------------------------------------------------------------------------ */
   /* Methods */
   /* ------------------------------------------------------------------------ */
 public:
   void registerNonLocalVariables() override final;
 
   void computeNonLocalStress(ElementType, GhostType) override final{};
 
   void insertQuadsInNeighborhoods(GhostType ghost_type);
 
 protected:
   // ID getNeighborhoodName() override { return "test_region"; }
 
   /* ------------------------------------------------------------------------ */
   /* Members */
   /* ------------------------------------------------------------------------ */
 private:
   InternalField<Real> grad_u_nl;
 };
 
 #endif /* TEST_MATERIAL_DAMAGE_HH_ */
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_linear.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_linear.cc
index 2225bf121..d5a393261 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_linear.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_materials/test_material_cohesive_linear.cc
@@ -1,195 +1,195 @@
 /**
  * @file   test_material_cohesive_linear.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Feb 21 2018
  * @date last modification:  Wed Nov 18 2020
  *
  * @brief  Test material cohesive linear
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "test_material_cohesive_fixture.hh"
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear.hh"
 /* -------------------------------------------------------------------------- */
 
-template <UInt dim>
+template <Int dim>
 struct TestMaterialCohesiveLinear
     : public TestMaterialCohesive<MaterialCohesiveLinear, dim> {
 
   TestMaterialCohesiveLinear(SolidMechanicsModel & model)
       : TestMaterialCohesive<MaterialCohesiveLinear, dim>(model) {}
 
   void SetUp() override {
     this->is_extrinsic = true;
 
     this->beta = 2.;
     this->kappa = 2;
 
     this->G_c = 10.;
     this->sigma_c_ = 1e6;
     this->penalty = 1e11;
 
     this->delta_c_ = 2. * this->G_c / this->sigma_c_;
   }
 
   void resetInternal() override {
     normal_opening = Vector<Real>(dim, 0.);
     tangential_opening = Vector<Real>(dim, 0.);
     contact_traction = Vector<Real>(dim, 0.);
     contact_opening = Vector<Real>(dim, 0.);
   }
 
   void computeTractions(Array<Real> & openings, const Vector<Real> & normal,
                         Array<Real> & tractions) override {
     for (auto && data :
          zip(make_view(openings, dim), make_view(tractions, dim))) {
       auto & opening = std::get<0>(data);
       auto & traction = std::get<1>(data);
 
       this->computeTractionOnQuad(
           traction, opening, normal, delta_max, this->delta_c_,
           this->insertion_stress_, this->sigma_c_, normal_opening,
           tangential_opening, normal_opening_norm, tangential_opening_norm,
           damage, penetration, contact_traction, contact_opening);
 
       opening += contact_opening;
       traction += contact_traction;
     }
   }
 
   Real delta(const Vector<Real> & opening, const Vector<Real> & normal) {
     auto beta = this->beta;
     auto kappa = this->kappa;
 
     auto normal_opening = opening.dot(normal) * normal;
     auto tangential_opening = opening - normal_opening;
 
     return std::sqrt(std::pow(normal_opening.norm(), 2) +
                      std::pow(tangential_opening.norm() * beta / kappa, 2));
   }
 
   Vector<Real> traction(const Vector<Real> & opening,
                         const Vector<Real> & normal) {
     auto delta_c = this->delta_c_;
     auto sigma_c = this->sigma_c_;
     auto beta = this->beta;
     auto kappa = this->kappa;
 
     auto normal_opening = opening.dot(normal) * normal;
     auto tangential_opening = opening - normal_opening;
 
     auto delta_ = this->delta(opening, normal);
     if (delta_ < 1e-16) {
       return this->insertion_stress_;
     }
 
     if (opening.dot(normal) / delta_c < -Math::getTolerance()) {
       ADD_FAILURE() << "This is contact";
       return Vector<Real>(dim, 0.);
     }
 
     auto T = sigma_c * (delta_c - delta_) / delta_c / delta_ *
              (normal_opening + tangential_opening * beta * beta / kappa);
 
     return T;
   }
 
   Vector<Real> tractionModeI(const Vector<Real> & opening,
                              const Vector<Real> & normal) {
     return traction(opening, normal);
   }
 
   Vector<Real> tractionModeII(const Vector<Real> & opening,
                               const Vector<Real> & normal) {
     return traction(opening, normal);
   }
 
 public:
   Real delta_c_{0};
 
   Real delta_max{0.};
   Real normal_opening_norm{0};
   Real tangential_opening_norm{0};
   Real damage{0};
   bool penetration{false};
 
   Real etot{0.};
   Real edis{0.};
 
   Vector<Real> normal_opening;
   Vector<Real> tangential_opening;
 
   Vector<Real> contact_traction;
   Vector<Real> contact_opening;
 };
 
 template <typename dim_>
 using TestMaterialCohesiveLinearFixture =
     TestMaterialCohesiveFixture<TestMaterialCohesiveLinear, dim_>;
 
 using coh_types = gtest_list_t<TestAllDimensions>;
 
 TYPED_TEST_SUITE(TestMaterialCohesiveLinearFixture, coh_types, );
 
 TYPED_TEST(TestMaterialCohesiveLinearFixture, ModeI) {
   this->checkModeI(this->material->delta_c_, this->material->get("G_c"));
 
   Real G_c = this->material->get("G_c");
   EXPECT_NEAR(G_c, this->dissipated(), 1e-6);
 }
 
 TYPED_TEST(TestMaterialCohesiveLinearFixture, ModeII) {
   this->checkModeII(this->material->delta_c_);
 
   if (this->dim != 1) {
     Real G_c = this->material->get("G_c");
     Real beta = this->material->get("beta");
     Real dis = beta * G_c;
     EXPECT_NEAR(dis, this->dissipated(), 1e-6);
   }
 }
 
 TYPED_TEST(TestMaterialCohesiveLinearFixture, Cycles) {
   auto delta_c = this->material->delta_c_;
   auto sigma_c = this->material->sigma_c_;
 
   this->material->insertion_stress_ = this->normal * sigma_c;
 
   this->addOpening(this->normal, 0, 0.1 * delta_c, 100);
   this->addOpening(this->normal, 0.1 * delta_c, 0., 100);
   this->addOpening(this->normal, 0., 0.5 * delta_c, 100);
   this->addOpening(this->normal, 0.5 * delta_c, -1.e-5, 100);
   this->addOpening(this->normal, -1.e-5, 0.9 * delta_c, 100);
   this->addOpening(this->normal, 0.9 * delta_c, 0., 100);
   this->addOpening(this->normal, 0., delta_c, 100);
 
   this->material->computeTractions(*this->openings, this->normal,
                                    *this->tractions);
 
   Real G_c = this->material->get("G_c");
   EXPECT_NEAR(G_c, this->dissipated(), 2e-3); // due to contact dissipation at 0
   this->output_csv();
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc
index 79846b81a..d284284a7 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.cc
@@ -1,96 +1,96 @@
 /**
  * @file   custom_non_local_test_material.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Mar 01 2015
  * @date last modification:  Mon Sep 11 2017
  *
  * @brief  Custom material to test the non local implementation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2015-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 "custom_non_local_test_material.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 CustomNonLocalTestMaterial<dim>::CustomNonLocalTestMaterial(
     SolidMechanicsModel & model, const ID & id)
     : MyNonLocalParent(model, id), local_damage("local_damage", *this),
       damage("damage", *this) {
   // Initialize the internal field by specifying the number of components
   this->local_damage.initialize(1);
   this->damage.initialize(1);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void CustomNonLocalTestMaterial<dim>::registerNonLocalVariables() {
   /// register the non-local variable in the manager
   this->model.getNonLocalManager().registerNonLocalVariable(
       this->local_damage.getName(), this->damage.getName(), 1);
 
   this->model.getNonLocalManager()
       .getNeighborhood(this->name)
       .registerNonLocalVariable(damage.getName());
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> void CustomNonLocalTestMaterial<dim>::initMaterial() {
+template <Int dim> void CustomNonLocalTestMaterial<dim>::initMaterial() {
   MyNonLocalParent::initMaterial();
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void CustomNonLocalTestMaterial<dim>::computeStress(ElementType el_type,
                                                     GhostType ghost_type) {
   MyNonLocalParent::computeStress(el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim>
+template <Int dim>
 void CustomNonLocalTestMaterial<dim>::computeNonLocalStress(
     ElementType el_type, GhostType ghost_type) {
   Array<Real>::const_scalar_iterator dam =
       this->damage(el_type, ghost_type).begin();
   Array<Real>::matrix_iterator stress =
       this->stress(el_type, ghost_type).begin(dim, dim);
   Array<Real>::matrix_iterator stress_end =
       this->stress(el_type, ghost_type).end(dim, dim);
 
   // compute the damage and update the stresses
   for (; stress != stress_end; ++stress, ++dam) {
     *stress *= (1. - *dam);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 // Instantiate the material for the 3 dimensions
 INSTANTIATE_MATERIAL(custom_non_local_test_material,
                      CustomNonLocalTestMaterial);
 /* -------------------------------------------------------------------------- */
 } // namespace akantu
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
index 75d2e4f7c..e7b6fe531 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_non_local/custom_non_local_test_material.hh
@@ -1,81 +1,81 @@
 /**
  * @file   custom_non_local_test_material.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Oct 19 2014
  * @date last modification:  Fri Jun 26 2020
  *
  * @brief  Custom material to test the non local implementation
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_elastic.hh"
 #include "material_non_local.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef CUSTOM_NON_LOCAL_TEST_MATERIAL_HH_
 #define CUSTOM_NON_LOCAL_TEST_MATERIAL_HH_
 
 namespace akantu {
 
-template <UInt dim>
+template <Int dim>
 class CustomNonLocalTestMaterial
     : public MaterialNonLocal<dim, MaterialElastic<dim>> {
 public:
   using MyNonLocalParent = MaterialNonLocal<dim, MaterialElastic<dim>>;
 
   CustomNonLocalTestMaterial(SolidMechanicsModel & model, const ID & id);
 
   /* ------------------------------------------------------------------------ */
   void initMaterial() override;
 
   void computeNonLocalStress(ElementType el_type, GhostType ghost_type);
   void computeStress(ElementType el_type, GhostType ghost_type) override;
 
 protected:
   void registerNonLocalVariables() override;
 
   /* ------------------------------------------------------------------------ */
   void computeNonLocalStresses(GhostType ghost_type) override {
     AKANTU_DEBUG_IN();
 
     for (auto & type : this->element_filter.elementTypes(dim, ghost_type)) {
       computeNonLocalStress(type, ghost_type);
     }
 
     AKANTU_DEBUG_OUT();
   }
 
 public:
   void setDamage(Real dam) { this->local_damage.setDefaultValue(dam); }
 
 protected:
   InternalField<Real> local_damage;
   InternalField<Real> damage;
 };
 
 } // namespace akantu
 
 #endif /* CUSTOM_NON_LOCAL_TEST_MATERIAL_HH_ */
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc
index 1c6dec0ea..c469daf81 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_dynamics.cc
@@ -1,323 +1,323 @@
 /**
  * @file   test_solid_mechanics_model_dynamics.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 29 2017
  * @date last modification:  Wed Nov 18 2020
  *
  * @brief  test of the class SolidMechanicsModel on the 3d cube
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2016-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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_functor.hh"
 #include "test_solid_mechanics_model_fixture.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 namespace {
 
 const Real A = 1e-1;
 const Real E = 1.;
 const Real poisson = 3. / 10;
 const Real lambda = E * poisson / (1 + poisson) / (1 - 2 * poisson);
 const Real mu = E / 2 / (1. + poisson);
 const Real rho = 1.;
 const Real cp = std::sqrt((lambda + 2 * mu) / rho);
 const Real cs = std::sqrt(mu / rho);
 const Real c = std::sqrt(E / rho);
 
 const Vector<Real> k = {.5, 0., 0.};
 const Vector<Real> psi1 = {0., 0., 1.};
 const Vector<Real> psi2 = {0., 1., 0.};
 const Real knorm = k.norm();
 
 /* -------------------------------------------------------------------------- */
-template <UInt dim> struct Verification {};
+template <Int dim> struct Verification {};
 
 /* -------------------------------------------------------------------------- */
 template <> struct Verification<1> {
   void displacement(Vector<Real> & disp, const Vector<Real> & coord,
                     Real current_time) {
     const auto & x = coord(_x);
     const Real omega = c * k[0];
     disp(_x) = A * cos(k[0] * x - omega * current_time);
   }
 
   void velocity(Vector<Real> & vel, const Vector<Real> & coord,
                 Real current_time) {
     const auto & x = coord(_x);
     const Real omega = c * k[0];
     vel(_x) = omega * A * sin(k[0] * x - omega * current_time);
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct Verification<2> {
   void displacement(Vector<Real> & disp, const Vector<Real> & X,
                     Real current_time) {
     Vector<Real> kshear = {k[1], k[0]};
     Vector<Real> kpush = {k[0], k[1]};
 
     const Real omega_p = knorm * cp;
     const Real omega_s = knorm * cs;
 
     Real phase_p = X.dot(kpush) - omega_p * current_time;
     Real phase_s = X.dot(kpush) - omega_s * current_time;
 
     disp = A * (kpush * cos(phase_p) + kshear * cos(phase_s));
   }
 
   void velocity(Vector<Real> & vel, const Vector<Real> & X, Real current_time) {
     Vector<Real> kshear = {k[1], k[0]};
     Vector<Real> kpush = {k[0], k[1]};
 
     const Real omega_p = knorm * cp;
     const Real omega_s = knorm * cs;
 
     Real phase_p = X.dot(kpush) - omega_p * current_time;
     Real phase_s = X.dot(kpush) - omega_s * current_time;
 
     vel =
         A * (kpush * omega_p * cos(phase_p) + kshear * omega_s * cos(phase_s));
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <> struct Verification<3> {
   void displacement(Vector<Real> & disp, const Vector<Real> & coord,
                     Real current_time) {
     const auto & X = coord;
     Vector<Real> kpush = k;
     Vector<Real> kshear1(3);
     Vector<Real> kshear2(3);
     kshear1.crossProduct(k, psi1);
     kshear2.crossProduct(k, psi2);
 
     const Real omega_p = knorm * cp;
     const Real omega_s = knorm * cs;
 
     Real phase_p = X.dot(kpush) - omega_p * current_time;
     Real phase_s = X.dot(kpush) - omega_s * current_time;
 
     disp = A * (kpush * cos(phase_p) + kshear1 * cos(phase_s) +
                 kshear2 * cos(phase_s));
   }
 
   void velocity(Vector<Real> & vel, const Vector<Real> & coord,
                 Real current_time) {
     const auto & X = coord;
     Vector<Real> kpush = k;
     Vector<Real> kshear1(3);
     Vector<Real> kshear2(3);
     kshear1.crossProduct(k, psi1);
     kshear2.crossProduct(k, psi2);
 
     const Real omega_p = knorm * cp;
     const Real omega_s = knorm * cs;
 
     Real phase_p = X.dot(kpush) - omega_p * current_time;
     Real phase_s = X.dot(kpush) - omega_s * current_time;
 
     vel =
         A * (kpush * omega_p * cos(phase_p) + kshear1 * omega_s * cos(phase_s) +
              kshear2 * omega_s * cos(phase_s));
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <ElementType _type>
 class SolutionFunctor : public BC::Dirichlet::DirichletFunctor {
 public:
   SolutionFunctor(Real current_time, SolidMechanicsModel & model)
       : current_time(current_time), model(model) {}
 
 public:
   static constexpr UInt dim = ElementClass<_type>::getSpatialDimension();
 
   inline void operator()(UInt node, Vector<bool> & flags, Vector<Real> & primal,
                          const Vector<Real> & coord) const {
     flags(0) = true;
     auto & vel = model.getVelocity();
     auto it = vel.begin(model.getSpatialDimension());
     Vector<Real> v = it[node];
 
     Verification<dim> verif;
     verif.displacement(primal, coord, current_time);
     verif.velocity(v, coord, current_time);
   }
 
 private:
   Real current_time;
   SolidMechanicsModel & model;
 };
 
 /* -------------------------------------------------------------------------- */
 // This fixture uses somewhat finer meshes representing bars.
 template <typename type_, typename analysis_method_>
 class TestSMMFixtureBar : public TestSMMFixture<type_> {
   using parent = TestSMMFixture<type_>;
 
 public:
   void SetUp() override {
     this->mesh_file =
         "../patch_tests/data/bar" + std::to_string(this->type) + ".msh";
     parent::SetUp();
 
     auto analysis_method = analysis_method_::value;
     this->initModel("test_solid_mechanics_model_"
                     "dynamics_material.dat",
                     analysis_method);
 
     const auto & position = this->mesh->getNodes();
     auto & displacement = this->model->getDisplacement();
     auto & velocity = this->model->getVelocity();
 
     constexpr auto dim = parent::spatial_dimension;
 
     Verification<dim> verif;
 
     for (auto && tuple :
          zip(make_view(position, dim), make_view(displacement, dim),
              make_view(velocity, dim))) {
       verif.displacement(std::get<1>(tuple), std::get<0>(tuple), 0.);
       verif.velocity(std::get<2>(tuple), std::get<0>(tuple), 0.);
     }
 
     if (this->dump_paraview)
       this->model->dump();
 
     /// boundary conditions
     this->model->applyBC(SolutionFunctor<parent::type>(0., *this->model), "BC");
 
     wave_velocity = 1.; // sqrt(E/rho) = sqrt(1/1) = 1
     simulation_time = 5 / wave_velocity;
     time_step = this->model->getTimeStep();
 
     max_steps = simulation_time / time_step; // 100
   }
 
   void solveStep() {
     constexpr auto dim = parent::spatial_dimension;
     Real current_time = 0.;
     const auto & position = this->mesh->getNodes();
     const auto & displacement = this->model->getDisplacement();
     UInt nb_nodes = this->mesh->getNbNodes();
     UInt nb_global_nodes = this->mesh->getNbGlobalNodes();
 
     max_error = -1.;
 
     Array<Real> displacement_solution(nb_nodes, dim);
     Verification<dim> verif;
 
     auto ndump = 50;
     auto dump_freq = max_steps / ndump;
 
     for (UInt s = 0; s < this->max_steps;
          ++s, current_time += this->time_step) {
       if (s % dump_freq == 0 && this->dump_paraview)
         this->model->dump();
 
       /// boundary conditions
       this->model->applyBC(
           SolutionFunctor<parent::type>(current_time, *this->model), "BC");
 
       // compute the disp solution
       for (auto && tuple : zip(make_view(position, dim),
                                make_view(displacement_solution, dim))) {
         verif.displacement(std::get<1>(tuple), std::get<0>(tuple),
                            current_time);
       }
 
       // compute the error solution
       Real disp_error = 0.;
       auto n = 0;
       for (auto && tuple : zip(make_view(displacement, dim),
                                make_view(displacement_solution, dim))) {
         if (this->mesh->isLocalOrMasterNode(n)) {
           auto diff = std::get<1>(tuple) - std::get<0>(tuple);
           disp_error += diff.dot(diff);
         }
         ++n;
       }
 
       this->mesh->getCommunicator().allReduce(disp_error,
                                               SynchronizerOperation::_sum);
 
       disp_error = sqrt(disp_error) / nb_global_nodes;
       max_error = std::max(disp_error, max_error);
 
       this->model->solveStep();
     }
   }
 
 protected:
   Real time_step;
   Real wave_velocity;
   Real simulation_time;
   UInt max_steps;
   Real max_error{-1};
 };
 
 template <AnalysisMethod t>
 using analysis_method_t = std::integral_constant<AnalysisMethod, t>;
 
 using TestTypes = gtest_list_t<TestElementTypes>;
 
 template <typename type_>
 using TestSMMFixtureBarExplicit =
     TestSMMFixtureBar<type_, analysis_method_t<_explicit_lumped_mass>>;
 
 TYPED_TEST_SUITE(TestSMMFixtureBarExplicit, TestTypes, );
 
 /* -------------------------------------------------------------------------- */
 TYPED_TEST(TestSMMFixtureBarExplicit, Dynamics) {
   this->solveStep();
   EXPECT_NEAR(this->max_error, 0., 2e-3);
   // std::cout << "max error: " << max_error << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_IMPLICIT)
 template <typename type_>
 using TestSMMFixtureBarImplicit =
     TestSMMFixtureBar<type_, analysis_method_t<_implicit_dynamic>>;
 
 TYPED_TEST_SUITE(TestSMMFixtureBarImplicit, TestTypes, );
 
 TYPED_TEST(TestSMMFixtureBarImplicit, Dynamics) {
   if (this->type == _segment_2 and
       (this->mesh->getCommunicator().getNbProc() > 2)) {
     // The error are just to high after (hopefully because of the two small test
     // case)
     SUCCEED();
     return;
   }
   this->solveStep();
   EXPECT_NEAR(this->max_error, 0., 2e-3);
 }
 #endif
 
 } // namespace
diff --git a/test/test_synchronizer/test_grid_tools.hh b/test/test_synchronizer/test_grid_tools.hh
index 4b8ecacb7..66337adfe 100644
--- a/test/test_synchronizer/test_grid_tools.hh
+++ b/test/test_synchronizer/test_grid_tools.hh
@@ -1,116 +1,116 @@
 /**
  * @file   test_grid_tools.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sun Oct 19 2014
  * @date last modification:  Fri Jan 15 2016
  *
  * @brief  Tools to help for the akantu::Grid class tests
  *
  *
  * @section LICENSE
  *
  * Copyright (©) 2014-2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free 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 <map>
 
 #include "aka_common.hh"
 #include "aka_types.hh"
 
 #define TOLERANCE 1e-7
 
-template <UInt dim> class Point {
+template <Int dim> class Point {
 public:
   Point() : id(0), tol(TOLERANCE) {
     for (UInt i = 0; i < dim; ++i)
       pos[i] = 0.;
   }
 
   Point(const Point & pt) : id(pt.id), tol(pt.tol) {
     for (UInt i = 0; i < dim; ++i)
       pos[i] = pt.pos[i];
   }
 
   Point(const Vector<Real> & pt, UInt id = 0) : id(id), tol(TOLERANCE) {
     for (UInt i = 0; i < dim; ++i)
       pos[i] = pt(i);
   }
 
   bool operator==(const Point & pt) const {
     for (UInt i = 0; i < dim; ++i) {
       //      std::cout << i << " " << pos[i] << " " << pt.pos[i] << " " <<
       //      std::abs(pos[i] - pt.pos[i]);
       if (std::abs(pos[i] - pt.pos[i]) > tol) {
         //        std::cout << " " << false << std::endl;
         return false;
       } // else
       //        std::cout << " " << true << std::endl;
     }
     return true;
   }
 
   bool operator<(const Point & pt) const {
     UInt i = 0, j = 0;
     for (; (i < dim) && (j < dim); i++, j++) {
       if (pos[i] < pt.pos[j])
         return true;
       if (pt.pos[j] < pos[i])
         return false;
     }
     return (i == dim) && (j != dim);
   }
 
   bool operator!=(const Point & pt) const { return !(operator==(pt)); }
 
   Real & operator()(UInt d) { return pos[d]; }
   const Real & operator()(UInt d) const { return pos[d]; }
 
   void read(const std::string & str) {
     std::stringstream sstr(str);
     for (UInt i = 0; i < dim; ++i)
       sstr >> pos[i];
   }
 
   void write(std::ostream & ostr) const {
     for (UInt i = 0; i < dim; ++i) {
       if (i != 0)
         ostr << " ";
       //    ostr << std::setprecision(std::numeric_limits<Real>::digits) <<
       //    pos[i];
       ostr << std::setprecision(9) << pos[i];
     }
   }
 
 private:
   UInt id;
   Real pos[dim];
   double tol;
 };
 
-template <UInt dim> struct neighbors_map_t {
+template <Int dim> struct neighbors_map_t {
   typedef std::map<Point<dim>, std::vector<Point<dim>>> type;
 };
 
-template <UInt dim>
+template <Int dim>
 inline std::ostream & operator<<(std::ostream & stream,
                                  const Point<dim> & _this) {
   _this.write(stream);
   return stream;
 }
diff --git a/third-party/akantu_iterators/include/iterators/aka_filter_iterator.hh b/third-party/akantu_iterators/include/iterators/aka_filter_iterator.hh
index 11885da1a..45bdb3460 100644
--- a/third-party/akantu_iterators/include/iterators/aka_filter_iterator.hh
+++ b/third-party/akantu_iterators/include/iterators/aka_filter_iterator.hh
@@ -1,157 +1,159 @@
 /**
  * @file   aka_filter_iterator.hh
  *
  * @author Nicolas Richart
  *
  * @date creation  jeu déc 12 2019
  *
  * @brief A Documented file.
  *
  *
  * 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 <iterator>
 #include <utility>
 /* -------------------------------------------------------------------------- */
 
 #ifndef AKA_FILTER_ITERATOR_H
 #define AKA_FILTER_ITERATOR_H
 
 #ifndef AKANTU_ITERATORS_NAMESPACE
 #define AKANTU_ITERATORS_NAMESPACE akantu
 #endif
 
 namespace AKANTU_ITERATORS_NAMESPACE {
 
 /* -------------------------------------------------------------------------- */
 namespace iterators {
   template <class filter_iterator_t, class container_iterator_t>
   class FilterIterator {
   public:
     using value_type =
         decltype(std::declval<container_iterator_t>().operator[](0));
-    using difference_type = typename filter_iterator_t::difference_type;
+    using difference_type = typename std::decay_t<filter_iterator_t>::difference_type;
     using pointer = std::decay_t<value_type> *;
     using reference = value_type &;
-    using iterator_category = typename filter_iterator_t::iterator_category;
+    using iterator_category = typename std::decay_t<filter_iterator_t>::iterator_category;
 
     FilterIterator(filter_iterator_t filter_it,
-                   container_iterator_t container_begin)
+                   container_iterator_t && container_begin)
         : filter_it(std::move(filter_it)),
           container_begin(std::move(container_begin)) {}
 
     FilterIterator(const FilterIterator &) = default;
 
     FilterIterator & operator++() {
       ++filter_it;
       return *this;
     }
 
     decltype(auto) operator*() {
       auto container_it = this->container_begin + *this->filter_it;
       return *container_it;
     }
 
     decltype(auto) operator*() const {
       auto container_it = this->container_begin + *this->filter_it;
       return *container_it;
     }
 
     bool operator==(const FilterIterator & other) const {
       return (filter_it == other.filter_it) and
              (container_begin == other.container_begin);
     }
 
     bool operator!=(const FilterIterator & other) const {
       return filter_it != other.filter_it;
     }
 
   private:
     filter_iterator_t filter_it;
     container_iterator_t container_begin;
   };
 
   template <class filter_iterator_t, class container_iterator_t>
   decltype(auto) make_filter_iterator(filter_iterator_t && filter_it,
                                       container_iterator_t && container_begin) {
     return FilterIterator<filter_iterator_t, container_iterator_t>(
         std::forward<filter_iterator_t>(filter_it),
         std::forward<container_iterator_t>(container_begin));
   }
 } // namespace iterators
 
 namespace containers {
   template <class filter_t, class Container> class FilterAdaptor {
   public:
     FilterAdaptor(filter_t && filter, Container && container)
         : filter(std::forward<filter_t>(filter)),
           container(std::forward<Container>(container)) {
       static_assert(
           std::is_same<typename decltype(container.begin())::iterator_category,
                        std::random_access_iterator_tag>::value,
           "Containers must all have random iterators");
     }
 
     decltype(auto) begin() const {
       return iterators::make_filter_iterator(filter.begin(), container.begin());
     }
+
     decltype(auto) begin() {
       return iterators::make_filter_iterator(filter.begin(), container.begin());
     }
 
     decltype(auto) end() const {
       return iterators::make_filter_iterator(filter.end(), container.begin());
     }
+
     decltype(auto) end() {
       return iterators::make_filter_iterator(filter.end(), container.begin());
     }
 
   private:
     filter_t filter;
     Container container;
   };
 } // namespace containers
 
 template <class filter_t, class Container>
 decltype(auto) filter(filter_t && filter, Container && container) {
   return containers::FilterAdaptor<filter_t, Container>(
       std::forward<filter_t>(filter), std::forward<Container>(container));
 }
 
 } // namespace AKANTU_ITERATORS_NAMESPACE
 
 namespace std {
 template <class filter_iterator_t, class container_iterator_t>
 struct iterator_traits<::AKANTU_ITERATORS_NAMESPACE::iterators::FilterIterator<
     filter_iterator_t, container_iterator_t>> {
 private:
   using iterator_type =
       typename ::AKANTU_ITERATORS_NAMESPACE::iterators::FilterIterator<
           filter_iterator_t, container_iterator_t>;
 
 public:
   using iterator_category = typename iterator_type::iterator_category;
   using value_type = typename iterator_type::value_type;
   using difference_type = typename iterator_type::difference_type;
   using pointer = typename iterator_type::pointer;
   using reference = typename iterator_type::reference;
 };
 } // namespace std
 
 #endif // AKA_FILTER_ITERATOR_H