diff --git a/doc/manual/manual-gettingstarted.tex b/doc/manual/manual-gettingstarted.tex
index 13538ecfb..4e5eebbae 100644
--- a/doc/manual/manual-gettingstarted.tex
+++ b/doc/manual/manual-gettingstarted.tex
@@ -1,450 +1,450 @@
 \chapter{Getting Started}
 \section{Downloading the Code}
 
 The \akantu source code can be requested using the form accessible at the URL
 \url{http://lsms.epfl.ch/akantu}.  There, you will be asked to accept the LGPL
 license terms.
 
 \section{Compiling \akantu}
 
 \akantu is a \code{cmake} project, so to configure it, you can either
 follow the usual way:
 \begin{command}
   > cd akantu
   > mkdir build
   > cd build
   > ccmake ..
   [ Set the options that you need ]
   > make
   > make install
 \end{command}
 
 \noindent Or, use the \code{Makefile} we added for your convenience to
 handle the \code{cmake} configuration
 
 \begin{command}
   > cd akantu
   > make config
   > make
   > make install
 \end{command}
 
 \noindent All the \akantu options are documented in Appendix
 \ref{app:package-dependencies}.
 
 
 \section{Writing a \texttt{main} Function\label{sect:common:main}}
 \label{sec:writing_main}
 
 First of all, \akantu 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 a pair of functions
 (\code{initialize} and \code{finalize}) that are used as follows:
 \begin{cpp}
 #include "aka_common.hh"
 #include "..."
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize("input_file.dat", argc, argv);
 
   // your code
   ...
 
   finalize();
 }
 \end{cpp}
 The \code{initialize} function takes the text inpute file and the program
 parameters which can be parsed by \akantu in due form (see \ref{sect:parser}). 
 Obviously it is necessary to include all files needed in main. In this manual
 all provided code implies the usage of \code{akantu} as namespace.
 
 \section{Creating and Loading a Mesh\label{sect:common:mesh}}
 
 In its current state, \akantu supports three types of meshes: Gmsh~\cite{gmsh},
 Abaqus~\cite{abaqus} and Diana~\cite{diana}. Once a \code{Mesh} object is
 created with a given spatial dimension, it can be filled by reading a mesh input file.
 The method \code{read} of the class \code{Mesh} infers the mesh type from the file extension. If a non-standard file extension is used, the mesh type has to be specified.
 
 \begin{cpp}
 UInt spatial_dimension = 2;
 Mesh mesh(spatial_dimension);
 
 // Reading Gmsh files
 mesh.read("my_gmsh_mesh.msh");
 mesh.read("my_gmsh_mesh", _miot_gmsh);
 
 
 // Reading Abaqus files
 mesh.read("my_abaqus_mesh.inp");
 mesh.read("my_abaqus_mesh", _miot_abaqus);
 
 // Reading Diana files
 mesh.read("my_diana_mesh.dat");
 mesh.read("my_diana_mesh", _miot_diana);
 \end{cpp}
 
 The Gmsh reader adds the geometrical and physical tags as mesh data. The physical
 values are stored as a \code{UInt} data called \code{tag\_0}, if a string
 name is provided it is stored as a \code{std::string} data named
 \code{physical\_names}. The geometrical tag is stored as a \code{UInt} data named
 \code{tag\_1}.
 
 
 The Abaqus reader stores the \code{ELSET} in ElementGroups and the \code{NSET}
 in NodeGroups. The material assignment can be retrieved from the
 \code{std::string} mesh data named \code{abaqus\_material}.
 
 % \akantu supports meshes generated with Gmsh~\cite{gmsh}, a free
 % software available at \url{http://geuz.org/gmsh/} where a detailed
 % documentation can be found. Consequently, this manual will not provide
 % Gmsh usage directions. Gmsh outputs meshes in \code{.msh} format that can be read
 % by \akantu. In order to import a mesh, it is necessary to create
 % a \code{Mesh} object through the following function calls:
 % \begin{cpp}
 %   UInt spatial_dimension = 2;
 %   Mesh mesh(spatial_dimension);
 % \end{cpp}
 % The only parameter that has to be specified by the user is the spatial
 % dimension of the problem. Now it is possible to read a \code{.msh} file with
 % a \code{MeshIOMSH} object that takes care of loading a mesh to memory.
 % This step is carried out by:
 % \begin{cpp}
 %   mesh.read("square.msh");
 % \end{cpp}
 % where the \code{MeshIOMSH} object is first created before being
 % used to read the \code{.msh} file. The mesh file name as well as the \code{Mesh}
 % object must be specified by the user.
 
 % The \code{MeshIOMSH} object can also write mesh files. This feature
 % is useful to save a mesh that has been modified during a
 % simulation. The \code{write} method takes care of it:
 % \begin{cpp}
 %   mesh_io.write("square_modified.msh", mesh);
 % \end{cpp}
 % which works exactly like the \code{read} method.
 
 % \akantu supports also meshes generated by
 % DIANA (\url{http://tnodiana.com}), but only in reading mode. A similar
 % procedure applies where the only
 % difference is that the \code{MeshIODiana} object should be used
 % instead of the \code{MeshIOMSH} one. Additional mesh readers can be
 % introduced into \akantu by coding new \code{MeshIO} classes.
 
 \section{Using \texttt{Arrays}}
 
 Data in \akantu can be stored in data containers implemented by
 the \code{Array} class. In its most basic usage, the \code{Array} class
 implemented in \akantu is similar to the \code{vector} class of
 the Standard Template Library (STL) for C++. A simple \code{Array}
 containing a sequence of \code{nb\_element} values (of a given type) can be generated with:
 \begin{cpp}
   Array<type> example_array(nb_element);
 \end{cpp}
 where \code{type} usually is \code{Real}, \code{Int}, \code{UInt} or
 \code{bool}. Each value is associated to an index, so that data can be
 accessed by typing:
 
 \begin{cpp}
   type & val = example_array(index)
 \end{cpp}
 
 \code{Arrays} can also contain tuples of values for each index. In
 that case, the number of components per tuple must be specified at the
 \code{Array} creation.  For example, if we want to create an
 \code{Array} to store the coordinates (sequences of three values) of
 ten nodes, the appropriate code is the following:
 \begin{cpp}
   UInt nb_nodes = 10;
   UInt spatial_dimension = 3;
 
   Array<Real> position(nb_nodes, spatial_dimension);
 \end{cpp}
 In this case the $x$ position of the eighth node number will be given by
 \code{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 \code{Array}:
 \begin{itemize}
   \item \code{resize(size)} change the size of the \code{Array}.
   \item \code{clear()} set all entries of the \code{Array} to zero.
   \item \code{set(t)} set all entries of the \code{Array} to \code{t}.
   \item \code{copy(const Array<T> $\&$ other)} copy another \code{Array} into the current one. The two \code{Array} should have the same number of components.
   \item \code{push$\_$back(tuple)} append a tuple with the correct number of components at the end of the \code{Array}.
   \item \code{erase(i) erase the value at the i-th position.}
   \item \code{find(value)} search \code{value} in the current \code{Array}. Return position index of the first occurence or $-1$ if not found.
   \item \code{storage()} Return the address of the allocated memory of the \code{Array}. 
 \end{itemize}
 
 \subsection{\texttt{Arrays} 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 \code{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:
 \begin{cpp}
   //accessing the nodal coordinates Array (spatial_dimension components)
   Array<Real> nodes = mesh.getNodes();
 
   //creating the iterators
-  Array<Real>::vector_iterator it  = nodes.begin(spatial_dimension);
-  Array<Real>::vector_iterator end = nodes.end(spatial_dimension);
+  auto it  = nodes.begin(spatial_dimension);
+  auto end = nodes.end(spatial_dimension);
 
   for (; it != end; ++it){
     Vector<Real> & coords = (*it);
 
     //do what you need
     ....
 
   }
 \end{cpp}
 In that example, each \code{Vector<Real>} is a geometrical array of
 size \code{spatial\_dimension} and the iteration is conveniently
 performed by the \code{Array} iterator.
 
 The \code{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 \code{begin} function. For instance, assuming that we
 have a \code{Array} storing stresses, we can loop over the stored
 tensors by:
 
 \begin{cpp}
   //creating the iterators
   Array<Real>::matrix_iterator it  = stresses.begin(spatial_dimension,spatial_dimension);
   Array<Real>::matrix_iterator end = stresses.end(spatial_dimension,spatial_dimension);
 
   for (; it != end; ++it){
     Matrix<Real> & stress = (*it);
 
     //do what you need
     ....
 
   }
 \end{cpp}
 In that last example, the \code{Matrix} objects are
 \code{spatial\_dimension} $\times$ \code{spatial\_dimension} matrices.
 The light objects \code{Matrix} and \code{Vector} can be used and
 combined to do most common linear algebra. If the number of component
 is 1, it is possible to use a scalar\_iterator rather than the
 vector/matrix one.
 
 
 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
 \code{ElementTypeMapArray} is provided to easily manage this kind of
 data.  It consists of a group of \code{Arrays}, each associated to an
 element type.  The following code can retrieve the
 \code{ElementTypeMapArray} which stores the connectivity arrays for a
 mesh:
 \begin{cpp}
   ElementTypeMapArray<UInt> & connectivities = mesh.getConnectivities();
 \end{cpp}
 Then, the specific array associated to a given element type can be obtained by
 \begin{cpp}
   Array<UInt> & connectivity_triangle = connectivities(_triangle_3);
 \end{cpp}
 where the first order 3-node triangular element was used in the presented piece
 of code.
 
 \subsection{Vector \& Matrix}
 
 The \code{Array} iterators as presented in the previous section can be shaped as
 \code{Vector} or \code{Matrix}. This objects represent $1^{st}$ and $2^{nd}$
 order tensors. As such they come with some functionalities that we will present
 a bit more into detail in this here.
 
 \subsubsection{\texttt{Vector<T>}}
 
 \begin{enumerate}
 \item Accessors:
   \begin{itemize}
   \item \code{v(i)} gives the $i^{th}$ component of the vector \code{v}
   \item \code{v[i]} gives the $i^{th}$ component of the vector \code{v}
   \item \code{v.size()} gives the number of component
   \end{itemize}
 \item Level 1: (results are scalars)
   \begin{itemize}
   \item \code{v.norm()} returns the geometrical norm ($L_2$)
   \item \code{v.norm<N>()} returns the $L_N$ norm defined as $\left(\sum_i
     |\code{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, \code{L\_1} for the Manhattan norm, \code{L\_2} for the
     geometrical norm and \code{L\_inf} for the norm infinity.
   \item \code{v.dot(x)} return the dot product of \code{v} and \code{x}
   \item \code{v.distance(x)} return the geometrical norm of $\code{v} -
     \code{x}$
   \end{itemize}
 \item Level 2: (results are vectors)
   \begin{itemize}
   \item \code{v += s}, \code{v -= s}, \code{v *= s}, \code{v /= s} those are
     element-wise operators that sum, substract, multiply or divide all the
     component of \code{v} by the scalar \code{s}
   \item \code{v += x}, \code{v -= x} sums or substracts the vector \code{x}
     to/from \code{v}
   \item \code{v.mul(A, x, alpha)} stores the result of $\alpha \mat{A} \vec{x}$ in \code{v},
     $\alpha$ is equal to 1 by default
   \item \code{v.solve(A, b)} stores the result of the resolution of the system $\mat{A} \vec{x} =
     \vec{b}$ in \code{v}
   \item \code{v.crossProduct(v1, v2)} computes the cross product of \code{v1} and \code{v2} and
     stores the result in \code{v}
   \end{itemize}
 \end{enumerate}
 
 \subsubsection{\texttt{Matrix<T>}}
 \begin{enumerate}
 \item Accessors:
   \begin{itemize}
   \item \code{A(i, j)} gives the component $A_{ij}$ of the matrix \code{A}
   \item \code{A(i)} gives the $i^{th}$ column of the matrix as a \code{Vector}
   \item \code{A[k]} gives the $k^{th}$ component of the matrix, matrices are
     stored in a column major way, which means that to access $A_{ij}$, $k = i +
     j M$
   \item \code{A.rows()} gives the number of rows of \code{A} ($M$)
   \item \code{A.cols()} gives the number of columns of \code{A} ($N$)
   \item \code{A.size()} gives the number of component in the matrix ($M \times N$)
   \end{itemize}
 \item Level 1: (results are scalars)
 
   \begin{itemize}
   \item \code{A.norm()} is equivalent to \code{A.norm<L\_2>()}
   \item \code{A.norm<N>()} returns the $L_N$ norm defined as
     $\left(\sum_i\sum_j |\code{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, \code{L\_1} for the Manhattan
     norm, \code{L\_2} for the geometrical norm and \code{L\_inf} for
     the norm infinity.
   \item \code{A.trace()} return the trace of \code{A}
   \item \code{A.det()} return the determinant of \code{A}
   \item \code{A.doubleDot(B)} return the double dot product of \code{A} and
     \code{B}, $\mat{A}:\mat{B}$
   \end{itemize}
 \item Level 3: (results are matrices)
   \begin{itemize}
   \item \code{A.eye(s)}, \code{Matrix<T>::eye(s)} fills/creates a matrix with
     the $s\mat{I}$ with $\mat{I}$ the identity matrix
   \item \code{A.inverse(B)} stores $\mat{B}^{-1}$ in \code{A}
   \item \code{A.transpose()} returns  $\mat{A}^{t}$
   \item \code{A.outerProduct(v1, v2)} stores $\vec{v_1} \vec{v_2}^{t}$ in
     \code{A}
   \item \code{C.mul<t\_A, t\_B>(A, B, alpha)}: stores the result of the product of
     \code{A} and code{B} time the scalar \code{alpha} in \code{C}. \code{t\_A}
     and \code{t\_B} are boolean defining if \code{A} and \code{B} should be
     transposed or not.
 
     \begin{tabular}{ccl}
       \toprule
       \code{t\_A} & \code{t\_B} & result \\
       \midrule
       false & false & $\mat{C} = \alpha \mat{A} \mat{B}$\\
       false & true  & $\mat{C} = \alpha \mat{A} \mat{B}^t$\\
       true  & false & $\mat{C} = \alpha \mat{A}^t \mat{B}$\\
       true  & true  & $\mat{C} = \alpha \mat{A}^t \mat{B}^t$\\
       \bottomrule
     \end{tabular}
   \item \code{A.eigs(d, V)} this method computes the eigenvalues and
     eigenvectors of \code{A} and store the results in \code{d} and \code{V} such
     that $\code{d(i)} = \lambda_i$ and $\code{V(i)} = \vec{v_i}$ with
     $\mat{A}\vec{v_i} = \lambda_i\vec{v_i}$ and $\lambda_1 > ... > \lambda_i >
     ... > \lambda_N$
   \end{itemize}
 \end{enumerate}
 
 \subsubsection{\texttt{Tensor3<T>}}
 Accessors:
 \begin{itemize}
   \item \code{t(i, j, k)} gives the component $T_{ijk}$ of the tensor \code{t}
   \item \code{t(k)} gives the $k^{th}$ two-dimensional tensor as a \code{Matrix}
   \item \code{t[k]} gives the $k^{th}$ two-dimensional tensor as a \code{Matrix}
 \end{itemize}
 
 
 \section{Manipulating group of nodes and/or elements\label{sect:common:groups}}
 \akantu provides the possibility to manipulate
 subgroups of elements and nodes.
 Any \code{ElementGroup} and/or \code{NodeGroup} must be managed
 by a \code{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 \code{Mesh} class
 which inheritates from the \code{GroupManager} class.
 
 For instance, the following code shows how to request
 an element group to a mesh:
 
 \begin{cpp}
   // 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 */
 \end{cpp}
 
 
 \subsection{The \texttt{NodeGroup} object}
 A group of nodes is stored in \code{NodeGroup} objects.
 They are quite simple objects which store the indexes
 of the selected nodes in a \code{Array<UInt>}.
 Nodes are selected by adding them when calling
 \code{NodeGroup::add}. For instance you can select nodes
 having a positive $X$ coordinate with the following code:
 \begin{cpp}
   Array<Real> & nodes = mesh.getNodes();
   NodeGroup & group = mesh.createNodeGroup("XpositiveNode");
 
-  Array<Real>::const_vector_iterator it  = nodes.begin(spatial_dimension);
-  Array<Real>::const_vector_iterator end = nodes.end(spatial_dimension);
+  auto it  = nodes.begin(spatial_dimension);
+  auto end = nodes.end(spatial_dimension);
 
   UInt index = 0;
 
   for (; it != end ; ++it , ++index){
     const Vector<Real> & position = *it;
     if (position(0) > 0) group.add(index);
   }
 \end{cpp}
 
 \subsection{The \texttt{ElementGroup} object}
 A group of elements is stored in \code{ElementGroup} objects.
 Since a group can contain elements of various types
 the \code{ElementGroup} object stores indexes in
 a \code{ElementTypeMapArray<UInt>} object.
 Then elements can be added to the group by calling \code{addElement}.
 
 For instance, selecting the elements for which the barycenter of the nodes
 has a positive $X$ coordinate can be made with:
 
 \begin{cpp}
   ElementGroup & group = mesh.createElementGroup("XpositiveElement");
 
   Mesh::type_iterator it  = mesh.firstType();
   Mesh::type_iterator end = mesh.lastType();
 
   Vector<Real> barycenter(spatial_dimension);
 
   for(; it != end; ++it){
     UInt nb_element  = mesh.getNbElement(*it);
     for(UInt e = 0; e < nb_element; ++e) {
       ElementType type = *it;
       mesh.getBarycenter(e, type, barycenter.storage());
       if (barycenter(0) > 0) group.add(type,e);
     }
   }
 \end{cpp}
 
 
 
 %%% Local Variables:
 %%% mode: latex
 %%% TeX-master: "manual"
 %%% End:
diff --git a/examples/io/dumper/locomotive_tools.cc b/examples/io/dumper/locomotive_tools.cc
index 74262dc67..12c5184a0 100644
--- a/examples/io/dumper/locomotive_tools.cc
+++ b/examples/io/dumper/locomotive_tools.cc
@@ -1,93 +1,93 @@
 /**
  * @file   locomotive_tools.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  *
  * @date creation: Mon Aug 17 2015
  * @date last modification: Mon Jan 18 2016
  *
  * @brief  Common functions for the dumper examples
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 #include "locomotive_tools.hh"
 /* -------------------------------------------------------------------------- */
 
 
 using namespace akantu;
 
 /* -------------------------------------------------------------------------- */
 void applyRotation(const Vector<Real> & center, Real angle,
                    const Array<Real> & nodes, Array<Real> & displacement,
                    const Array<UInt> & node_group) {
-  Array<Real>::const_vector_iterator nodes_it =
+  auto nodes_it =
       nodes.begin(nodes.getNbComponent());
-  Array<Real>::vector_iterator disp_it = displacement.begin(center.size());
+  auto disp_it = displacement.begin(center.size());
   Array<UInt>::const_scalar_iterator node_num_it = node_group.begin();
   Array<UInt>::const_scalar_iterator node_num_end = node_group.end();
 
   Vector<Real> pos_rel(center.size());
 
   for (; node_num_it != node_num_end; ++node_num_it) {
     const Vector<Real> pos = nodes_it[*node_num_it];
     for (UInt i = 0; i < pos.size(); ++i)
       pos_rel(i) = pos(i);
 
     Vector<Real> dis = disp_it[*node_num_it];
 
     pos_rel -= center;
     Real radius = pos_rel.norm();
 
     if (std::abs(radius) < Math::getTolerance())
       continue;
 
     Real phi_i = std::acos(pos_rel(_x) / radius);
     if (pos_rel(_y) < 0)
       phi_i *= -1;
 
     dis(_x) = std::cos(phi_i - angle) * radius - pos_rel(_x);
     dis(_y) = std::sin(phi_i - angle) * radius - pos_rel(_y);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void fillColour(const Mesh & mesh, ElementTypeMapArray<UInt> & colour) {
   const ElementTypeMapArray<std::string> & phys_data =
       mesh.getData<std::string>("physical_names");
   const Array<std::string> & txt_colour = phys_data(_triangle_3);
   Array<UInt> & id_colour = colour(_triangle_3);
 
   for (UInt i = 0; i < txt_colour.size(); ++i) {
     std::string phy_name = txt_colour(i);
 
     if (phy_name == "red")
       id_colour(i) = 3;
     else if (phy_name == "white" || phy_name == "lwheel_1" ||
              phy_name == "rwheel_1")
       id_colour(i) = 2;
     else
       id_colour(i) = 1;
   }
 }
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 99f1295b2..76c1e14b8 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,259 +1,255 @@
 /**
  * @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.
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_damage_iterative.hh"
-#include "solid_mechanics_model_RVE.hh"
 #include "communicator.hh"
 #include "data_accessor.hh"
+#include "solid_mechanics_model_RVE.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialDamageIterative<spatial_dimension>::MaterialDamageIterative(
     SolidMechanicsModel & model, const ID & id)
-    : MaterialDamage<spatial_dimension>(model, id),
-      Sc("Sc", *this), reduction_step("damage_step", *this),
+    : 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>
 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);
 
-  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();
+  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.clear();
     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>
 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);
+  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>
 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() ) {
-    //   Array<Real>::const_iterator<Real> equivalent_stress_it_max =
+    //   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);
-    Array<Real>::const_iterator<Real> equivalent_stress_it = e_stress.begin();
-    Array<Real>::const_iterator<Real> equivalent_stress_end = e_stress.end();
+    auto equivalent_stress_it = e_stress.begin();
+    auto equivalent_stress_end = e_stress.end();
     Array<Real> & dam = this->damage(el_type);
-    Array<Real>::iterator<Real> dam_it = dam.begin();
+    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>
 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>
 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;
     ;
 
     Mesh::type_iterator it = this->model.getFEEngine().getMesh().firstType(
         spatial_dimension, ghost_type);
     Mesh::type_iterator last_type =
         this->model.getFEEngine().getMesh().lastType(spatial_dimension,
                                                      ghost_type);
 
     for (; it != last_type; ++it) {
       ElementType el_type = *it;
 
       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();
+      auto equivalent_stress_it = e_stress.begin();
+      auto equivalent_stress_end = e_stress.end();
       Array<Real> & dam = this->damage(el_type);
-      Array<Real>::iterator<Real> dam_it = dam.begin();
-      Array<UInt>::scalar_iterator reduction_it =
-          this->reduction_step(el_type, ghost_type).begin();
+      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);
+  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>
 void MaterialDamageIterative<spatial_dimension>::updateEnergiesAfterDamage(
     ElementType el_type, GhostType ghost_type) {
   MaterialDamage<spatial_dimension>::updateEnergies(el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(damage_iterative, MaterialDamageIterative);
 
 } // namespace akantu
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 21b7c819a..aab883b2e 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,379 +1,379 @@
 /**
  * @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.
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_orthotropic_damage_iterative.hh"
 #include "communicator.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt 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>
 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);
 
-  Array<Real>::const_iterator<Real> Sc_it = Sc(el_type).begin();
-  Array<Real>::iterator<Real> equivalent_stress_it =
+  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.clear();
     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>
 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>
 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>
 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>
 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>
 void MaterialOrthotropicDamageIterative<
     spatial_dimension>::updateEnergiesAfterDamage(ElementType el_type,
                                                   GhostType ghost_type) {
   MaterialOrthotropicDamage<spatial_dimension>::updateEnergies(el_type,
                                                                ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 INSTANTIATE_MATERIAL(orthotropic_damage_iterative,
                      MaterialOrthotropicDamageIterative);
 
 } // namespace akantu
diff --git a/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_serial.cc b/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_serial.cc
index 51b1ed6bc..be7949b0c 100644
--- a/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_serial.cc
+++ b/extra_packages/extra-materials/test/test_material_damage/test_material_damage_iterative_non_local_serial.cc
@@ -1,224 +1,224 @@
 /**
  * @file   test_material_damage_iterative_non_local_serial.cc
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Thu Nov 26 12:20:15 2015
  *
  * @brief  test the material damage iterative non local in serial
  *
  * @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 "material_damage_iterative_non_local.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 /* -------------------------------------------------------------------------- */
 /* Main                                                                       */
 /* -------------------------------------------------------------------------- */
 int main(int argc, char *argv[]) {
   Math::setTolerance(1e-13);
   debug::setDebugLevel(dblWarning);
 
   initialize("material_non_local.dat" ,argc, argv);
  
   const UInt spatial_dimension = 2;
   ElementType element_type = _triangle_3;
   /// read the mesh and partion it
   Mesh mesh(spatial_dimension);
   mesh.read("plate.msh");
 
   /// model creation
   SolidMechanicsModel model(mesh);
 
   /// initialization of the model
   model.initFull(SolidMechanicsModelOptions(_static));
 
   /// boundary conditions
   /// Dirichlet BC
   mesh.createGroupsFromMeshData<std::string>("physical_names"); // creates groups from mesh names
   model.applyBC(BC::Dirichlet::FixedValue(0, _x), "left");
   model.applyBC(BC::Dirichlet::FixedValue(0, _y), "bottom");
   model.applyBC(BC::Dirichlet::FixedValue(2., _y), "top");
 
   /// add fields that should be dumped
   model.setBaseName("material_damage_iterative_test");
   model.addDumpFieldVector("displacement");;
   model.addDumpField("stress");
   model.addDumpField("blocked_dofs");
   model.addDumpField("residual");
   model.addDumpField("grad_u");
   model.addDumpField("grad_u non local");
   model.addDumpField("damage");
   model.addDumpField("partitions");
   model.addDumpField("material_index");
   model.addDumpField("Sc");
   model.addDumpField("force");
   model.addDumpField("equivalent_stress");
 
   model.dump();
  
   MaterialDamageIterativeNonLocal<spatial_dimension> & material = dynamic_cast<MaterialDamageIterativeNonLocal<spatial_dimension> & >(model.getMaterial(0));
  
   Real error;
   bool converged = false;
   Real max_eq_stress = 0;
 
   /// solve the system
   converged = model.solveStep<_scm_newton_raphson_tangent_modified, _scc_increment>(1e-4, error, 2);
 
   if (converged == false) {
     std::cout << "The error is: " << error << std::endl;
     AKANTU_DEBUG_ASSERT(converged, "Did not converge");
   }
 
   model.dump();   
 
   /// check the non-local grad_u: since grad_u is constant everywhere
   /// also the grad_u non-local has to be constant
   Array<Real> & grad_u_nl = material.getInternal<Real>("grad_u non local")(element_type, _not_ghost);
   Array<Real>::const_matrix_iterator grad_u_nl_it = grad_u_nl.begin(spatial_dimension,spatial_dimension);
   Array<Real>::const_matrix_iterator grad_u_nl_end = grad_u_nl.end(spatial_dimension,spatial_dimension);
   Real diff = 0.;
   Matrix<Real> diff_matrix(spatial_dimension, spatial_dimension);
   Matrix<Real> const_grad_u(spatial_dimension, spatial_dimension, 0.);
   const_grad_u(1,1) = 1.;
 
   for (; grad_u_nl_it != grad_u_nl_end; ++grad_u_nl_it) {
     diff_matrix = (*grad_u_nl_it) - const_grad_u;
     diff += diff_matrix.norm<L_2>();
   }  
     
   if (diff > 10.e-13) {
     std::cout << "Error in the non-local grad_u computation" << std::endl;
     return EXIT_FAILURE;
   }
 
 
   /// change the displacement in one node to modify grad_u
   Array<Real> & displ = model.getDisplacement();
   displ(0,1) = 2.6;
 
 
   /// compute stresses: this will average grad_u and compute the max. eq. stress
   model.updateResidual();
   model.dump();
   /// due to the change in the displacement element 33 and 37 will
   /// have a grad_u different then one
   const Array<Real> & grad_u = material.getInternal<Real>("grad_u")(element_type, _not_ghost);
   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);
   diff = 0.;
   diff_matrix.clear();
  
   UInt counter = 0;
   for (; grad_u_it != grad_u_end; ++grad_u_it) {
     diff_matrix = (*grad_u_it) - const_grad_u;
     if (counter == 34 || counter == 38) {
       if ((diff_matrix.norm<L_2>()) < 0.1) {
 	std::cout << "Error in the grad_u computation" << std::endl;
 	return EXIT_FAILURE;
      }
     }  
     else
       diff += diff_matrix.norm<L_2>();
     ++counter;
  }   
 
   if (diff > 10.e-13) {
     std::cout << "Error in the grad_u computation" << std::endl;
     return EXIT_FAILURE;
   }
   
 
   /// check that the non-local grad_u
   diff = 0.;
   diff_matrix.clear();
   Real nl_radius = 1.0; /// same values as in material file
   grad_u_nl_it = grad_u_nl.begin(spatial_dimension,spatial_dimension);
   ElementTypeMapReal quad_coords("quad_coords");
   mesh.initElementTypeMapArray(quad_coords, spatial_dimension, spatial_dimension, false, _ek_regular, true);
   model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
   UInt nb_elements = mesh.getNbElement(element_type, _not_ghost);
   UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(element_type);
   Array<Real> & coords = quad_coords(element_type, _not_ghost);
-  Array<Real>::const_vector_iterator coord_it = coords.begin(spatial_dimension);
+  auto coord_it = coords.begin(spatial_dimension);
   Vector<Real> q1(spatial_dimension);
   Vector<Real> q2(spatial_dimension);
   q1 = coord_it[34];
   q2 = coord_it[38];
   for (UInt e = 0; e < nb_elements; ++e) {
     for (UInt q = 0; q < nb_quads; ++q, ++coord_it, ++grad_u_nl_it) {
       diff_matrix = (*grad_u_nl_it) - const_grad_u;
       if ((q1.distance(*coord_it) <= (nl_radius + Math::getTolerance())) || 
 	  (q2.distance(*coord_it) <= (nl_radius + Math::getTolerance()))) {
 	if ((diff_matrix.norm<L_2>()) < 1.e-6) {
 	  std::cout << (diff_matrix.norm<L_2>()) << std::endl;
 	  std::cout << "Error in the non-local grad_u computation" << std::endl;
 	  return EXIT_FAILURE;
 	}
       }
       else
 	diff += diff_matrix.norm<L_2>();
     }
   }
 
   if (diff > 10.e-13) {
     std::cout << "Error in the non-local grad_u computation" << std::endl;
     return EXIT_FAILURE;
   }
 
 
   /// make sure that the normalized equivalent stress is based on the
   /// non-local grad_u for this test check the elements that have the
   /// constant stress of 1 but different non-local gradu because they
   /// are in the neighborhood of the modified elements
   coord_it = coords.begin(spatial_dimension);
   const Array<Real> & eq_stress = material.getInternal<Real>("equivalent_stress")(element_type, _not_ghost);
   Array<Real>::const_scalar_iterator eq_stress_it = eq_stress.begin();
   counter = 0;
   for (UInt e = 0; e < nb_elements; ++e) {
     for (UInt q = 0; q < nb_quads; ++q, ++coord_it, ++grad_u_nl_it, ++eq_stress_it) {
       if (counter == 34 || counter == 38)
 	continue;
       if (((q1.distance(*coord_it) <= (nl_radius + Math::getTolerance())) || 
 	   (q2.distance(*coord_it) <= (nl_radius + Math::getTolerance()))) && Math::are_float_equal(*eq_stress_it, 0.1)) {
 	std::cout << "the normalized equivalent stress is most likely based on the local, not the non-local grad_u!!!!" << std::endl;
 	finalize();
 	return EXIT_FAILURE;
       }
       ++counter;
     }
   }
 
   max_eq_stress =  material.getNormMaxEquivalentStress();
   
   if (!Math::are_float_equal(max_eq_stress, 0.1311267235941873)){
     std::cout << "the maximum equivalent stress is wrong" << std::endl;
     finalize();
     return EXIT_FAILURE;
   }
 
   model.dump();  
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc
index 625b45da2..bebc0675e 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/mIIasym_contact.cc
@@ -1,108 +1,108 @@
 /**
  * @file   mIIasym_contact.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  *
  * @brief  
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 // simtools
 #include "mIIasym_contact.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MIIASYMContact::MIIASYMContact(SolidMechanicsModel & model,
 			       const ContactID & id,
 			       const MemoryID & memory_id) :
   NTRFContact(model,id,memory_id)
 {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MIIASYMContact::updateImpedance() {
   AKANTU_DEBUG_IN();
 
   NTRFContact::updateImpedance();
 
   for (UInt i=0; i<this->impedance.getSize(); ++i) {
     this->impedance(i) *= 0.5;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /// WARNING: this is only valid for the acceleration in equilibrium
 void MIIASYMContact::computeRelativeNormalField(const Array<Real> & field,
 						Array<Real> & rel_normal_field) const {
   AKANTU_DEBUG_IN();
 
   NTRFContact::computeRelativeNormalField(field, rel_normal_field);
 
-  for (Array<Real>::iterator<Real> it_rtfield  = rel_normal_field.begin();
+  for (auto it_rtfield  = rel_normal_field.begin();
        it_rtfield != rel_normal_field.end();
        ++it_rtfield) {
 
     // in the anti-symmetric case
     *it_rtfield *= 2.;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MIIASYMContact::computeRelativeTangentialField(const Array<Real> & field,
 						    Array<Real> & rel_tang_field) const {
   AKANTU_DEBUG_IN();
 
   NTRFContact::computeRelativeTangentialField(field, rel_tang_field);
 
   UInt dim = this->model.getSpatialDimension();
   
   for (Array<Real>::iterator< Vector<Real> > it_rtfield  = rel_tang_field.begin(dim);
        it_rtfield != rel_tang_field.end(dim);
        ++it_rtfield) {
 
     // in the anti-symmetric case, the tangential fields become twice as large
     *it_rtfield *= 2.;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MIIASYMContact::computeContactPressureInEquilibrium() {
   AKANTU_DEBUG_IN();
 
   NTRFContact::computeContactPressure();
 
   AKANTU_DEBUG_OUT();
 }
 
 
 /* -------------------------------------------------------------------------- */
 void MIIASYMContact::printself(std::ostream & stream, int indent) const {
   AKANTU_DEBUG_IN();
   std::string space;
   for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
 
   stream << space << "MIIASYMContact [" << std::endl;
   NTRFContact::printself(stream,indent);
   stream << space << "]" << std::endl;
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc
index 72cae3346..2d7516a25 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_base_friction.cc
@@ -1,374 +1,374 @@
 /**
  * @file   ntn_base_friction.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  *
  * @brief  implementation of ntn base friction
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 // simtools
 #include "ntn_base_friction.hh"
 #include "dumper_text.hh"
 #include "dumper_nodal_field.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NTNBaseFriction::NTNBaseFriction(NTNBaseContact * contact,
 				 const FrictionID & id,
 				 const MemoryID & memory_id) :
   Memory(id,memory_id),
   Parsable(_st_friction, id),
   Dumpable(),
   contact(contact),
   is_sticking(0,1,true,id+":is_sticking",true,"is_sticking"),
   frictional_strength(0,1,0.,id+":frictional_strength",0.,"frictional_strength"),
   friction_traction(0,contact->getModel().getSpatialDimension(),
 		    0.,id+":friction_traction",0.,"friction_traction"),
   slip(0,1,0.,id+":slip",0.,"slip"),
   cumulative_slip(0,1,0.,id+":cumulative_slip",0.,"cumulative_slip"),
   slip_velocity(0,contact->getModel().getSpatialDimension(),
 		0.,id+":slip_velocity",0.,"slip_velocity") {
   AKANTU_DEBUG_IN();
 
   this->contact->registerSynchronizedArray(this->is_sticking);
   this->contact->registerSynchronizedArray(this->frictional_strength);
   this->contact->registerSynchronizedArray(this->friction_traction);
   this->contact->registerSynchronizedArray(this->slip);
   this->contact->registerSynchronizedArray(this->cumulative_slip);
   this->contact->registerSynchronizedArray(this->slip_velocity);
 
   contact->getModel().setIncrementFlagOn();
 
   this->registerExternalDumper(contact->getDumper(),
 			       contact->getDefaultDumperName(),
 			       true);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::updateSlip() {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel & model = this->contact->getModel();
   UInt dim = model.getSpatialDimension();
 
   // synchronize increment
   this->contact->getSynchronizerRegistry()->synchronize(_gst_cf_incr);
 
   Array<Real> rel_tan_incr(0,dim);
   this->contact->computeRelativeTangentialField(model.getIncrement(),
 						rel_tan_incr);
   Array<Real>::const_iterator< Vector<Real> > it = rel_tan_incr.begin(dim);
 
   UInt nb_nodes = this->contact->getNbContactNodes();
   for (UInt n=0; n<nb_nodes; ++n) {
     if (this->is_sticking(n)) {
       this->slip(n) = 0.;
     }
     else {
       const Vector<Real> & rti = it[n];
       this->slip(n) += rti.norm();
       this->cumulative_slip(n) += rti.norm();
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::computeFrictionTraction() {
   AKANTU_DEBUG_IN();
 
   this->computeStickTraction();
   this->computeFrictionalStrength();
 
   SolidMechanicsModel & model = this->contact->getModel();
   UInt dim = model.getSpatialDimension();
 
   // get contact arrays
   const SynchronizedArray<bool> & is_in_contact = this->contact->getIsInContact();
 
   Array<Real> & traction = const_cast< Array<Real> & >(this->friction_traction.getArray());
   Array<Real>::iterator< Vector<Real> > it_fric_trac = traction.begin(dim);
 
   this->is_sticking.clear(); // set to not sticking
 
   UInt nb_contact_nodes = this->contact->getNbContactNodes();
   for (UInt n=0; n<nb_contact_nodes; ++n) {
     // node pair is in contact
     if (is_in_contact(n)) {
       Vector<Real> fric_trac = it_fric_trac[n];
       // check if it is larger than frictional strength
       Real abs_fric = fric_trac.norm();
       if (abs_fric != 0.) {
 	Real alpha = this->frictional_strength(n) / abs_fric;
 
 	// larger -> sliding
 	if (alpha < 1.) {
 	  fric_trac *= alpha;
 	}
 	else
 	  this->is_sticking(n) = true;
       }
       else {
 	// frictional traction is already zero
 	this->is_sticking(n) = true;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::computeStickTraction() {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel & model = this->contact->getModel();
   UInt dim = model.getSpatialDimension();
   Real delta_t = model.getTimeStep();
 
   UInt nb_contact_nodes = this->contact->getNbContactNodes();
 
   // get contact arrays
   const SynchronizedArray<Real> & impedance = this->contact->getImpedance();
   const SynchronizedArray<bool> & is_in_contact = this->contact->getIsInContact();
 
   // pre-compute the acceleration
   // (not increment acceleration, because residual is still Kf)
   Array<Real> acceleration(model.getFEEngine().getMesh().getNbNodes(), dim, 0.);
   model.solveLumped(acceleration,
 		    model.getMass(),
 		    model.getResidual(),
 		    model.getBlockedDOFs(),
 		    model.getF_M2A());
 
   // compute relative normal fields of velocity and acceleration
   Array<Real> r_velo(0,dim);
   Array<Real> r_acce(0,dim);
   Array<Real> r_old_acce(0,dim);
   this->contact->computeRelativeTangentialField(model.getVelocity(),     r_velo);
   this->contact->computeRelativeTangentialField(acceleration,            r_acce);
   this->contact->computeRelativeTangentialField(model.getAcceleration(), r_old_acce);
 
   AKANTU_DEBUG_ASSERT(r_velo.getSize() == nb_contact_nodes,
 		      "computeRelativeNormalField does not give back arrays "
 		      << "size == nb_contact_nodes. nb_contact_nodes = " << nb_contact_nodes
 		      << " | array size = " << r_velo.getSize());
 
   // compute tangential gap_dot array for all nodes
   Array<Real> gap_dot(nb_contact_nodes, dim);
   Real * gap_dot_p = gap_dot.storage();
   Real * r_velo_p = r_velo.storage();
   Real * r_acce_p = r_acce.storage();
   Real * r_old_acce_p = r_old_acce.storage();
   for (UInt i=0; i<nb_contact_nodes*dim; ++i) {
     *gap_dot_p = *r_velo_p + delta_t * *r_acce_p - 0.5 * delta_t * *r_old_acce_p;
     // increment pointers
     gap_dot_p++;
     r_velo_p++;
     r_acce_p++;
     r_old_acce_p++;
   }
 
   // compute friction traction to stop sliding
   Array<Real> & traction = const_cast< Array<Real> & >(this->friction_traction.getArray());
-  Array<Real>::vector_iterator it_fric_trac = traction.begin(dim);
+  auto it_fric_trac = traction.begin(dim);
   for (UInt n=0; n<nb_contact_nodes; ++n) {
     Vector<Real> fric_trac = it_fric_trac[n];
     // node pair is NOT in contact
     if (!is_in_contact(n)) {
       fric_trac.clear(); // set to zero
     }
 
     // node pair is in contact
     else {
       // compute friction traction
       for (UInt d=0; d<dim; ++d)
 	fric_trac(d) = impedance(n) * gap_dot(n,d) / 2.;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::applyFrictionTraction() {
   AKANTU_DEBUG_IN();
 
   SolidMechanicsModel & model = this->contact->getModel();
   Array<Real> & residual = model.getResidual();
   UInt dim = model.getSpatialDimension();
 
   const SynchronizedArray<UInt> & slaves = this->contact->getSlaves();
   const SynchronizedArray<Real> & lumped_boundary_slaves = this->contact->getLumpedBoundarySlaves();
 
   UInt nb_contact_nodes = this->contact->getNbContactNodes();
   for (UInt n=0; n<nb_contact_nodes; ++n) {
     UInt slave = slaves(n);
 
     for (UInt d=0; d<dim; ++d) {
       residual(slave, d) -= lumped_boundary_slaves(n)  * this->friction_traction(n,d);
     }
   }
 
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::registerSynchronizedArray(SynchronizedArrayBase & array) {
   AKANTU_DEBUG_IN();
 
   this->frictional_strength.registerDependingArray(array);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::dumpRestart(const std::string & file_name) const {
   AKANTU_DEBUG_IN();
 
   this->is_sticking.dumpRestartFile(file_name);
   this->frictional_strength.dumpRestartFile(file_name);
   this->friction_traction.dumpRestartFile(file_name);
   this->slip.dumpRestartFile(file_name);
   this->cumulative_slip.dumpRestartFile(file_name);
   this->slip_velocity.dumpRestartFile(file_name);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::readRestart(const std::string & file_name) {
   AKANTU_DEBUG_IN();
 
   this->is_sticking.readRestartFile(file_name);
   this->frictional_strength.readRestartFile(file_name);
   this->friction_traction.readRestartFile(file_name);
   this->cumulative_slip.readRestartFile(file_name);
   this->slip_velocity.readRestartFile(file_name);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::setParam(const std::string & name, UInt node, Real value) {
   AKANTU_DEBUG_IN();
 
   SynchronizedArray<Real> & array = this->get< SynchronizedArray<Real> >(name);
   Int index = this->contact->getNodeIndex(node);
   if (index < 0) {
     AKANTU_DEBUG_WARNING("Node " << node << " is not a contact node. "
 			 << "Therefore, cannot set interface parameter!!");
   }
   else {
     array(index) = value; // put value
   }
 
   AKANTU_DEBUG_OUT();
 };
 
 /* -------------------------------------------------------------------------- */
 UInt NTNBaseFriction::getNbStickingNodes() const {
   AKANTU_DEBUG_IN();
 
   UInt nb_stick = 0;
 
   UInt nb_nodes = this->contact->getNbContactNodes();
   const SynchronizedArray<UInt> & nodes = this->contact->getSlaves();
   const SynchronizedArray<bool> & is_in_contact = this->contact->getIsInContact();
 
   const Mesh & mesh = this->contact->getModel().getMesh();
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     bool is_local_node = mesh.isLocalOrMasterNode(nodes(n));
     bool is_pbc_slave_node = this->contact->getModel().isPBCSlaveNode(nodes(n));
     if (is_local_node
 	&& !is_pbc_slave_node
 	&& is_in_contact(n)
 	&& this->is_sticking(n)) {
       nb_stick++;
     }
   }
 
   StaticCommunicator::getStaticCommunicator().allReduce(&nb_stick, 1, _so_sum);
 
   AKANTU_DEBUG_OUT();
   return nb_stick;
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::printself(std::ostream & stream, int indent) const {
   AKANTU_DEBUG_IN();
   std::string space;
   for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
 
   stream << space << "NTNBaseFriction [" << std::endl;
   Parsable::printself(stream, indent);
   stream << space << "]" << std::endl;
 
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNBaseFriction::addDumpFieldToDumper(const std::string & dumper_name,
 				       const std::string & field_id) {
   AKANTU_DEBUG_IN();
 
 #ifdef AKANTU_USE_IOHELPER
   //  const SynchronizedArray<UInt> * nodal_filter = &(this->contact->getSlaves());
 
   if(field_id == "is_sticking") {
     this->internalAddDumpFieldToDumper(dumper_name,
 			       field_id,
 			       new dumper::NodalField<bool>(this->is_sticking.getArray()));
   }
   else if(field_id == "frictional_strength") {
     this->internalAddDumpFieldToDumper(dumper_name,
 			       field_id,
 			       new dumper::NodalField<Real>(this->frictional_strength.getArray()));
   }
   else if(field_id == "friction_traction") {
     this->internalAddDumpFieldToDumper(dumper_name,
 			       field_id,
 			       new dumper::NodalField<Real>(this->friction_traction.getArray()));
   }
   else if(field_id == "slip") {
     this->internalAddDumpFieldToDumper(dumper_name,
 			       field_id,
 			       new dumper::NodalField<Real>(this->slip.getArray()));
   }
   else if(field_id == "cumulative_slip") {
     this->internalAddDumpFieldToDumper(dumper_name,
 			       field_id,
 			       new dumper::NodalField<Real>(this->cumulative_slip.getArray()));
   }
   else if(field_id == "slip_velocity") {
     this->internalAddDumpFieldToDumper(dumper_name,
 			       field_id,
 			       new dumper::NodalField<Real>(this->slip_velocity.getArray()));
   }
   else {
     this->contact->addDumpFieldToDumper(dumper_name, field_id);
   }
 
 #endif
 
   AKANTU_DEBUG_OUT();
 }
 
 
 
 } // namespace akantu
diff --git a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc
index 157f31290..935b7f5fe 100644
--- a/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc
+++ b/extra_packages/traction-at-split-node-contact/src/ntn_contact/ntn_contact.cc
@@ -1,564 +1,564 @@
 /**
  * @file   ntn_contact.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  *
  * @brief  implementation of ntn_contact
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 // simtools
 #include "ntn_contact.hh"
 #include "dumper_text.hh"
 #include "dumper_nodal_field.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NTNContact::NTNContact(SolidMechanicsModel & model,
 		       const ContactID & id,
 		       const MemoryID & memory_id) :
   NTNBaseContact(model,id,memory_id),
   masters(0,1,0,id+":masters",std::numeric_limits<UInt>::quiet_NaN(),"masters"),
   lumped_boundary_masters(0,1,0,id+":lumped_boundary_masters",
 			  std::numeric_limits<Real>::quiet_NaN(),"lumped_boundary_masters"),
   master_elements("master_elements", id, memory_id)
 {
   AKANTU_DEBUG_IN();
 
   const Mesh & mesh = this->model.getMesh();
   UInt spatial_dimension = this->model.getSpatialDimension();
 
   mesh.initElementTypeMapArray(this->master_elements,
 			       1,
 			       spatial_dimension - 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::pairInterfaceNodes(const ElementGroup & slave_boundary,
 				    const ElementGroup & master_boundary,
 				    UInt surface_normal_dir,
 				    const Mesh & mesh,
 				    Array<UInt> & pairs) {
   AKANTU_DEBUG_IN();
 
   pairs.resize(0);
   AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2,
 		      "Array of node pairs should have nb_component = 2," <<
 		      " but has nb_component = " << pairs.getNbComponent());
 
   UInt dim = mesh.getSpatialDimension();
   AKANTU_DEBUG_ASSERT(surface_normal_dir < dim, "Mesh is of " << dim << " dimensions"
 		      << " and cannot have direction " << surface_normal_dir
 		      << " for surface normal");
 
   // offset for projection computation
   UInt offset[dim-1];
   for (UInt i=0, j=0; i<dim; ++i) {
     if (surface_normal_dir != i) {
       offset[j] = i;
       ++j;
     }
   }
 
   // find projected node coordinates
   const Array<Real> & coordinates = mesh.getNodes();
 
   // find slave nodes
   Array<Real> proj_slave_coord(slave_boundary.getNbNodes(),dim-1,0.);
   Array<UInt> slave_nodes(slave_boundary.getNbNodes());
   UInt n(0);
   for(ElementGroup::const_node_iterator nodes_it(slave_boundary.node_begin()); nodes_it!= slave_boundary.node_end(); ++nodes_it) {
     for (UInt d=0; d<dim-1; ++d) {
       proj_slave_coord(n,d) = coordinates(*nodes_it,offset[d]);
       slave_nodes(n)=*nodes_it;
     }
     ++n;
   }
 
   // find master nodes
   Array<Real> proj_master_coord(master_boundary.getNbNodes(),dim-1,0.);
   Array<UInt> master_nodes(master_boundary.getNbNodes());
   n=0;
   for(ElementGroup::const_node_iterator nodes_it(master_boundary.node_begin()); nodes_it!= master_boundary.node_end(); ++nodes_it) {
     for (UInt d=0; d<dim-1; ++d) {
       proj_master_coord(n,d) = coordinates(*nodes_it,offset[d]);
       master_nodes(n)=*nodes_it;
     }
     ++n;
   }
 
   // find minimum distance between slave nodes to define tolerance
   Real min_dist = std::numeric_limits<Real>::max();
   for (UInt i=0; i<proj_slave_coord.getSize(); ++i) {
     for (UInt j=i+1; j<proj_slave_coord.getSize(); ++j) {
       Real dist = 0.;
       for (UInt d=0; d<dim-1; ++d) {
 	dist += (proj_slave_coord(i,d) - proj_slave_coord(j,d))
 	      * (proj_slave_coord(i,d) - proj_slave_coord(j,d));
       }
       if (dist < min_dist) {
 	min_dist = dist;
       }
     }
   }
   min_dist = std::sqrt(min_dist);
   Real local_tol = 0.1*min_dist;
 
   // find master slave node pairs
   for (UInt i=0; i<proj_slave_coord.getSize(); ++i) {
     for (UInt j=0; j<proj_master_coord.getSize(); ++j) {
       Real dist = 0.;
       for (UInt d=0; d<dim-1; ++d) {
 	dist += (proj_slave_coord(i,d) - proj_master_coord(j,d))
 	      * (proj_slave_coord(i,d) - proj_master_coord(j,d));
       }
       dist = std::sqrt(dist);
       if (dist < local_tol) { // it is a pair
 	UInt pair[2];
 	pair[0] = slave_nodes(i);
 	pair[1] = master_nodes(j);
 	pairs.push_back(pair);
 	continue; // found master do not need to search further for this slave
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::addSurfacePair(const Surface & slave,
 				const Surface & master,
 				UInt surface_normal_dir) {
   AKANTU_DEBUG_IN();
 
   const Mesh & mesh = this->model.getMesh();
 
   const ElementGroup & slave_boundary  = mesh.getElementGroup(slave);
   const ElementGroup & master_boundary = mesh.getElementGroup(master);
 
   this->contact_surfaces.insert(&slave_boundary);
   this->contact_surfaces.insert(&master_boundary);
 
   Array<UInt> pairs(0,2);
   NTNContact::pairInterfaceNodes(slave_boundary,
 				 master_boundary,
 				 surface_normal_dir,
 				 this->model.getMesh(),
 				 pairs);
 
   // eliminate pairs which contain a pbc slave node
   Array<UInt> pairs_no_PBC_slaves(0,2);
   Array<UInt>::const_vector_iterator it  = pairs.begin(2);
   Array<UInt>::const_vector_iterator end = pairs.end(2);
   for (; it!=end; ++it) {
     const Vector<UInt> & pair = *it;
     if (!this->model.isPBCSlaveNode(pair(0)) && !this->model.isPBCSlaveNode(pair(1))) {
       pairs_no_PBC_slaves.push_back(pair);
     }
   }
 
   this->addNodePairs(pairs_no_PBC_slaves);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::addNodePairs(const Array<UInt> & pairs) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2,
 		      "Array of node pairs should have nb_component = 2," <<
 		      " but has nb_component = " << pairs.getNbComponent());
   UInt nb_pairs = pairs.getSize();
   for (UInt n=0; n<nb_pairs; ++n) {
     this->addSplitNode(pairs(n,0), pairs(n,1));
   }
 
   // synchronize with depending nodes
   findBoundaryElements(this->slaves.getArray(),  this->slave_elements);
   findBoundaryElements(this->masters.getArray(), this->master_elements);
   updateInternalData();
   syncArrays(_added);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::getNodePairs(Array<UInt> & pairs) const {
   AKANTU_DEBUG_IN();
 
   pairs.resize(0);
   AKANTU_DEBUG_ASSERT(pairs.getNbComponent() == 2,
 		      "Array of node pairs should have nb_component = 2," <<
 		      " but has nb_component = " << pairs.getNbComponent());
   UInt nb_pairs = this->getNbContactNodes();
   for (UInt n=0; n<nb_pairs; ++n) {
     UInt pair[2];
     pair[0] = this->slaves(n);
     pair[1] = this->masters(n);
     pairs.push_back(pair);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::addSplitNode(UInt slave, UInt master) {
   AKANTU_DEBUG_IN();
 
   NTNBaseContact::addSplitNode(slave);
 
   this->masters.push_back(master);
   this->lumped_boundary_masters.push_back(std::numeric_limits<Real>::quiet_NaN());
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /*
   This function only works for surface elements with one quad point. For
   surface elements with more quad points, it computes still, but the result
   might not be what you are looking for.
  */
 void NTNContact::updateNormals() {
   AKANTU_DEBUG_IN();
 
   // set normals to zero
   this->normals.clear();
 
   // contact information
   UInt dim = this->model.getSpatialDimension();
   UInt nb_contact_nodes = this->getNbContactNodes();
 
   this->synch_registry->synchronize(_gst_cf_nodal); // synchronize current pos
   const Array<Real> & cur_pos = this->model.getCurrentPosition();
 
   FEEngine & boundary_fem = this->model.getFEEngineBoundary();
   const Mesh & mesh = this->model.getMesh();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end();
        ++gt) {
     Mesh::type_iterator it   = mesh.firstType(dim-1, *gt);
     Mesh::type_iterator last = mesh.lastType(dim-1, *gt);
 
     for (; it != last; ++it) {
       // compute the normals
       Array<Real> quad_normals(0,dim);
       boundary_fem.computeNormalsOnIntegrationPoints(cur_pos, quad_normals, *it, *gt);
 
       UInt nb_quad_points = boundary_fem.getNbIntegrationPoints(*it, *gt);
 
       // new version: compute normals only based on master elements (and not all boundary elements)
       // -------------------------------------------------------------------------------------
 
       UInt nb_nodes_per_element        = mesh.getNbNodesPerElement(*it);
       const Array<UInt> & connectivity = mesh.getConnectivity(*it, *gt);
 
       Array<UInt>::const_iterator<UInt> elem_it     = (this->master_elements)(*it, *gt).begin();
       Array<UInt>::const_iterator<UInt> elem_it_end = (this->master_elements)(*it, *gt).end();
       // loop over contact nodes
       for (; elem_it != elem_it_end; ++elem_it) {
         for (UInt q=0; q<nb_nodes_per_element; ++q) {
           UInt node = connectivity(*elem_it,q);
           UInt node_index = this->masters.find(node);
           AKANTU_DEBUG_ASSERT(node_index != UInt(-1), 
 			      "Could not find node " << node 
 			      << " in the array!");
 	  
 	  for (UInt q=0; q<nb_quad_points; ++q) {
 	    // add quad normal to master normal
 	    for (UInt d=0; d<dim; ++d) {
 	      this->normals(node_index,d) += quad_normals((*elem_it)*nb_quad_points + q, d);
 	    }
 	  }
         }
       }
       // -------------------------------------------------------------------------------------
       
       /*
       // get elements connected to each node
       CSR<UInt> node_to_element;
       MeshUtils::buildNode2ElementsElementTypeMap(mesh, node_to_element, *it, *gt);
 
       // add up normals to all master nodes
       for (UInt n=0; n<nb_contact_nodes; ++n) {
 	UInt master = this->masters(n);
 	CSR<UInt>::iterator elem = node_to_element.begin(master);
 	// loop over all elements connected to this master node
 	for (; elem != node_to_element.end(master); ++elem) {
 	  UInt e = *elem;
 	  // loop over all quad points of this element
 	  for (UInt q=0; q<nb_quad_points; ++q) {
 	    // add quad normal to master normal
 	    for (UInt d=0; d<dim; ++d) {
 	      this->normals(n,d) += quad_normals(e*nb_quad_points + q, d);
 	    }
 	  }
 	}
       }
       */
     }
   }
 
   Real * master_normals = this->normals.storage();
   for (UInt n=0; n<nb_contact_nodes; ++n) {
     if (dim==2)
       Math::normalize2(&(master_normals[n*dim]));
     else if (dim==3)
       Math::normalize3(&(master_normals[n*dim]));
   }
 
   // // normalize normals
-  // Array<Real>::iterator<Real> nit  = this->normals.begin();
-  // Array<Real>::iterator<Real> nend = this->normals.end();
+  // auto nit  = this->normals.begin();
+  // auto nend = this->normals.end();
   // for (; nit != nend; ++nit) {
   //   nit->normalize();
   // }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::dumpRestart(const std::string & file_name) const {
   AKANTU_DEBUG_IN();
 
   NTNBaseContact::dumpRestart(file_name);
   this->masters.dumpRestartFile(file_name);
   this->lumped_boundary_masters.dumpRestartFile(file_name);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::readRestart(const std::string & file_name) {
   AKANTU_DEBUG_IN();
 
   NTNBaseContact::readRestart(file_name);
   this->masters.readRestartFile(file_name);
   this->lumped_boundary_masters.readRestartFile(file_name);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::updateImpedance() {
   AKANTU_DEBUG_IN();
 
   UInt nb_contact_nodes = getNbContactNodes();
   Real delta_t = this->model.getTimeStep();
   AKANTU_DEBUG_ASSERT(delta_t != NAN, "Time step is NAN. Have you set it already?");
 
   const Array<Real> & mass = this->model.getMass();
 
   for (UInt n=0; n<nb_contact_nodes; ++n) {
     UInt master = this->masters(n);
     UInt slave = this->slaves(n);
 
     Real imp = (this->lumped_boundary_masters(n) / mass(master))
 	     + (this->lumped_boundary_slaves(n) / mass(slave));
     imp = 2 / delta_t / imp;
     this->impedance(n) = imp;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::updateLumpedBoundary() {
   AKANTU_DEBUG_IN();
 
   internalUpdateLumpedBoundary(this->slaves.getArray(),
 			       this->slave_elements,
 			       this->lumped_boundary_slaves);
 
   internalUpdateLumpedBoundary(this->masters.getArray(),
 			       this->master_elements,
 			       this->lumped_boundary_masters);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::applyContactPressure() {
   AKANTU_DEBUG_IN();
 
   UInt nb_ntn_pairs = getNbContactNodes();
   UInt dim = this->model.getSpatialDimension();
 
   Array<Real> & residual = this->model.getResidual();
 
   for (UInt n=0; n<nb_ntn_pairs; ++n) {
     UInt master = this->masters(n);
     UInt slave = this->slaves(n);
 
     for (UInt d=0; d<dim; ++d) {
       residual(master,d) += this->lumped_boundary_masters(n) * this->contact_pressure(n,d);
       residual(slave, d) -= this->lumped_boundary_slaves(n)  * this->contact_pressure(n,d);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::computeRelativeTangentialField(const Array<Real> & field,
 						Array<Real> & rel_tang_field) const {
   AKANTU_DEBUG_IN();
 
   // resize arrays to zero
   rel_tang_field.resize(0);
 
   UInt dim = this->model.getSpatialDimension();
 
-  Array<Real>::const_vector_iterator it_field  = field.begin(dim);
-  Array<Real>::const_vector_iterator it_normal = this->normals.getArray().begin(dim);
+  auto it_field  = field.begin(dim);
+  auto it_normal = this->normals.getArray().begin(dim);
 
   Vector<Real> rfv(dim);
   Vector<Real> np_rfv(dim);
 
   UInt nb_contact_nodes = this->slaves.getSize();
   for (UInt n=0; n<nb_contact_nodes; ++n) {
     // nodes
     UInt slave  = this->slaves(n);
     UInt master = this->masters(n);
 
     // relative field vector (slave - master)
     rfv = Vector<Real>(it_field[slave]);
     rfv -= Vector<Real>(it_field[master]);
 
     // normal projection of relative field
     const Vector<Real> normal_v = it_normal[n];
     np_rfv = normal_v;
     np_rfv *= rfv.dot(normal_v);
 
     // subract normal projection from relative field to get the tangential projection
     rfv -= np_rfv;
     rel_tang_field.push_back(rfv);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::computeRelativeNormalField(const Array<Real> & field,
 					    Array<Real> & rel_normal_field) const {
   AKANTU_DEBUG_IN();
 
   // resize arrays to zero
   rel_normal_field.resize(0);
 
   UInt dim = this->model.getSpatialDimension();
   //  Real * field_p = field.storage();
   //  Real * normals_p = this->normals.storage();
 
   Array<Real>::const_iterator< Vector<Real> > it_field  = field.begin(dim);
   Array<Real>::const_iterator< Vector<Real> > it_normal = this->normals.getArray().begin(dim);
 
   Vector<Real> rfv(dim);
 
   UInt nb_contact_nodes = this->getNbContactNodes();
   for (UInt n=0; n<nb_contact_nodes; ++n) {
     // nodes
     UInt slave  = this->slaves(n);
     UInt master = this->masters(n);
 
     // relative field vector (slave - master)
     rfv = Vector<Real>(it_field[slave]);
     rfv -= Vector<Real>(it_field[master]);
 
     // length of normal projection of relative field
     const Vector<Real> normal_v = it_normal[n];
     rel_normal_field.push_back(rfv.dot(normal_v));
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Int NTNContact::getNodeIndex(UInt node) const {
   AKANTU_DEBUG_IN();
 
   Int slave_i  = NTNBaseContact::getNodeIndex(node);
   Int master_i = this->masters.find(node);
 
   AKANTU_DEBUG_OUT();
   return std::max(slave_i,master_i);
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::printself(std::ostream & stream, int indent) const {
   AKANTU_DEBUG_IN();
   std::string space;
   for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
 
   stream << space << "NTNContact [" << std::endl;
   NTNBaseContact::printself(stream, indent);
   stream << space << " + masters       : " << std::endl;
   this->masters.printself(stream, indent + 2);
   stream << space << " + lumped_boundary_mastres : " << std::endl;
   this->lumped_boundary_masters.printself(stream, indent + 2);
 
   stream << space << "]" << std::endl;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::syncArrays(SyncChoice sync_choice) {
   AKANTU_DEBUG_IN();
 
   NTNBaseContact::syncArrays(sync_choice);
 
   this->masters.syncElements(sync_choice);
   this->lumped_boundary_masters.syncElements(sync_choice);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NTNContact::addDumpFieldToDumper(const std::string & dumper_name,
 				      const std::string & field_id) {
   AKANTU_DEBUG_IN();
 
   /*
 #ifdef AKANTU_USE_IOHELPER
   const Array<UInt> & nodal_filter = this->slaves.getArray();
 
 #define ADD_FIELD(field_id, field, type)				\
   internalAddDumpFieldToDumper(dumper_name,				\
 			       field_id,				\
 			       new DumperIOHelper::NodalField< type, true, \
 							       Array<type>, \
 							       Array<UInt> >(field, 0, 0, &nodal_filter))
   */
 
   if(field_id == "lumped_boundary_master") {
     internalAddDumpFieldToDumper(dumper_name,
 				 field_id,
 				 new dumper::NodalField<Real>(this->lumped_boundary_masters.getArray()));
   }
   else {
     NTNBaseContact::addDumpFieldToDumper(dumper_name, field_id);
   }
 
   /*
 #undef ADD_FIELD
 #endif
   */
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/fe_engine/integrator_gauss_inline_impl.cc b/src/fe_engine/integrator_gauss_inline_impl.cc
index d3884d56b..adadb20ae 100644
--- a/src/fe_engine/integrator_gauss_inline_impl.cc
+++ b/src/fe_engine/integrator_gauss_inline_impl.cc
@@ -1,713 +1,706 @@
 /**
  * @file   integrator_gauss_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Feb 15 2011
  * @date last modification: Thu Nov 19 2015
  *
  * @brief  inline function of gauss integrator
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "fe_engine.hh"
 #include "mesh_iterators.hh"
 #if defined(AKANTU_DEBUG_TOOLS)
 #include "aka_debug_tools.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 namespace debug {
 struct IntegratorGaussException : public Exception {};
 }
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::integrateOnElement(
     const Array<Real> & f, Real * intf, UInt nb_degree_of_freedom,
     const UInt elem, const GhostType & ghost_type) const {
   Array<Real> & jac_loc = jacobians(type, ghost_type);
 
   UInt nb_quadrature_points = ElementClass<type>::getNbQuadraturePoints();
   AKANTU_DEBUG_ASSERT(f.getNbComponent() == nb_degree_of_freedom,
 		      "The vector f do not have the good number of component.");
 
   Real * f_val = f.storage() + elem * f.getNbComponent();
   Real * jac_val = jac_loc.storage() + elem * nb_quadrature_points;
 
   integrate(f_val, jac_val, intf, nb_degree_of_freedom, nb_quadrature_points);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Vector<Real> & in_f, UInt index, const GhostType & ghost_type) const {
   const Array<Real> & jac_loc = jacobians(type, ghost_type);
 
   UInt nb_quadrature_points =
       GaussIntegrationElement<type>::getNbQuadraturePoints();
   AKANTU_DEBUG_ASSERT(in_f.size() == nb_quadrature_points,
 		      "The vector f do not have nb_quadrature_points entries.");
 
   Real * jac_val = jac_loc.storage() + index * nb_quadrature_points;
   Real intf;
 
   integrate(in_f.storage(), jac_val, &intf, 1, nb_quadrature_points);
 
   return intf;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     Real * f, Real * jac, Real * inte, UInt nb_degree_of_freedom,
     UInt nb_quadrature_points) const {
   memset(inte, 0, nb_degree_of_freedom * sizeof(Real));
 
   Real * cjac = jac;
   for (UInt q = 0; q < nb_quadrature_points; ++q) {
     for (UInt dof = 0; dof < nb_degree_of_freedom; ++dof) {
       inte[dof] += *f * *cjac;
       ++f;
     }
     ++cjac;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline const Matrix<Real> &
 IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationPoints(
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_ASSERT(
       quadrature_points.exists(type, ghost_type),
       "Quadrature points for type "
 	  << quadrature_points.printType(type, ghost_type)
 	  << " have not been initialized."
 	  << " Did you use 'computeQuadraturePoints' function ?");
   return quadrature_points(type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline UInt
 IntegratorGauss<kind, IntegrationOrderFunctor>::getNbIntegrationPoints(
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_ASSERT(
       quadrature_points.exists(type, ghost_type),
       "Quadrature points for type "
 	  << quadrature_points.printType(type, ghost_type)
 	  << " have not been initialized."
 	  << " Did you use 'computeQuadraturePoints' function ?");
   return quadrature_points(type, ghost_type).cols();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 inline Matrix<Real>
 IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationPoints() const {
   return GaussIntegrationElement<type,
 				 polynomial_degree>::getQuadraturePoints();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 inline Vector<Real>
 IntegratorGauss<kind, IntegrationOrderFunctor>::getIntegrationWeights() const {
   return GaussIntegrationElement<type, polynomial_degree>::getWeights();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void
 IntegratorGauss<kind, IntegrationOrderFunctor>::computeQuadraturePoints(
     const GhostType & ghost_type) {
   Matrix<Real> & quads = quadrature_points(type, ghost_type);
   const UInt polynomial_degree =
       IntegrationOrderFunctor::template getOrder<type>();
   quads =
       GaussIntegrationElement<type, polynomial_degree>::getQuadraturePoints();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::
     computeJacobianOnQuadPointsByElement(const Matrix<Real> & node_coords,
 					 const Matrix<Real> & quad,
 					 Vector<Real> & jacobians) const {
   // jacobian
   ElementClass<type>::computeJacobian(quad, node_coords, jacobians);
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 IntegratorGauss<kind, IntegrationOrderFunctor>::IntegratorGauss(
     const Mesh & mesh, const ID & id, const MemoryID & memory_id)
     : Integrator(mesh, id, memory_id) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::checkJacobians(
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = this->quadrature_points(type, ghost_type).cols();
 
   UInt nb_element = mesh.getConnectivity(type, ghost_type).size();
 
   Real * jacobians_val = jacobians(type, ghost_type).storage();
 
   for (UInt i = 0; i < nb_element * nb_quadrature_points;
        ++i, ++jacobians_val) {
     if (*jacobians_val < 0)
       AKANTU_CUSTOM_EXCEPTION_INFO(debug::IntegratorGaussException{},
 	  "Negative jacobian computed,"
 	  << " possible problem in the element node ordering (Quadrature Point "
 	  << i % nb_quadrature_points << ":" << i / nb_quadrature_points << ":"
 	  << type << ":" << ghost_type << ")");
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
 	const Array<Real> & nodes, const Matrix<Real> & quad_points,
 	Array<Real> & jacobians, const GhostType & ghost_type,
 	const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = quad_points.cols();
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   jacobians.resize(nb_element * nb_quadrature_points);
 
   auto jacobians_it =
       jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
   auto jacobians_begin = jacobians_it;
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
 				       filter_elements);
 
   auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   nb_element = x_el.size();
 
   //  Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
   for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
     const Matrix<Real> & x = *x_it;
     Vector<Real> & J = *jacobians_it;
     computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
 
     if (filter_elements == empty_filter) {
       ++jacobians_it;
     } else {
       jacobians_it = jacobians_begin + filter_elements(elem);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 template <>
 template <ElementType type>
 void IntegratorGauss<_ek_structural, DefaultIntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
 	const Array<Real> & nodes, const Matrix<Real> & quad_points,
 	Array<Real> & jacobians, const GhostType & ghost_type,
 	const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   const UInt spatial_dimension = mesh.getSpatialDimension();
   const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   const UInt nb_quadrature_points = quad_points.cols();
   const UInt nb_dofs = ElementClass<type>::getNbDegreeOfFreedom();
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
   jacobians.resize(nb_element * nb_quadrature_points);
 
   auto jacobians_it =
       jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
   auto jacobians_begin = jacobians_it;
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
 				       filter_elements);
 
   auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   nb_element = x_el.size();
 
   const bool has_extra_normal =
       mesh.hasData<Real>("extra_normal", type, ghost_type);
   Array<Real>::const_vector_iterator extra_normal, extra_normal_begin;
   if (has_extra_normal) {
     extra_normal = mesh.getData<Real>("extra_normal", type, ghost_type)
 		       .begin(spatial_dimension);
     extra_normal_begin = extra_normal;
   }
 
   //  Matrix<Real> local_coord(spatial_dimension, nb_nodes_per_element);
   for (UInt elem = 0; elem < nb_element; ++elem, ++x_it) {
     const Matrix<Real> & X = *x_it;
     Vector<Real> & J = *jacobians_it;
     Matrix<Real> R(nb_dofs, nb_dofs);
 
     if (has_extra_normal)
       ElementClass<type>::computeRotationMatrix(R, X, *extra_normal);
     else
       ElementClass<type>::computeRotationMatrix(R, X, Vector<Real>(X.rows()));
     // Extracting relevant lines
     auto x = (R.block(0, 0, spatial_dimension, spatial_dimension) * X)
 		 .block(0, 0, ElementClass<type>::getNaturalSpaceDimension(),
 			ElementClass<type>::getNbNodesPerElement());
 
     computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
 
     if (filter_elements == empty_filter) {
       ++jacobians_it;
       ++extra_normal;
     } else {
       jacobians_it = jacobians_begin + filter_elements(elem);
       extra_normal = extra_normal_begin + filter_elements(elem);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_COHESIVE_ELEMENT)
 template <>
 template <ElementType type>
 void IntegratorGauss<_ek_cohesive, DefaultIntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
 	const Array<Real> & nodes, const Matrix<Real> & quad_points,
 	Array<Real> & jacobians, const GhostType & ghost_type,
 	const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = quad_points.cols();
 
   UInt nb_element = mesh.getNbElement(type, ghost_type);
 
   jacobians.resize(nb_element * nb_quadrature_points);
 
   auto jacobians_it =
       jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
   auto jacobians_begin = jacobians_it;
 
   Vector<Real> weights = GaussIntegrationElement<type>::getWeights();
 
   Array<Real> x_el(0, spatial_dimension * nb_nodes_per_element);
   FEEngine::extractNodalToElementField(mesh, nodes, x_el, type, ghost_type,
 				       filter_elements);
 
   auto x_it = x_el.begin(spatial_dimension, nb_nodes_per_element);
 
   UInt nb_nodes_per_subelement = nb_nodes_per_element / 2;
   Matrix<Real> x(spatial_dimension, nb_nodes_per_subelement);
 
   nb_element = x_el.size();
 
   auto compute = [&](const auto & el) {
     Vector<Real> J(jacobians_begin[el]);
 
     for (UInt s = 0; s < spatial_dimension; ++s)
       for (UInt n = 0; n < nb_nodes_per_subelement; ++n)
 	x(s, n) =
 	    ((*x_it)(s, n) + (*x_it)(s, n + nb_nodes_per_subelement)) * .5;
 
     if (type == _cohesive_1d_2)
       J(0) = 1;
     else
       this->computeJacobianOnQuadPointsByElement<type>(x, quad_points, J);
   };
 
-  for_each_element(nb_element, filter_elements, compute);
-
-
-  AKANTU_DEBUG_OUT();
+  for_each_element(nb_element, filter_elements, compute);AKANTU_DEBUG_OUT();
 }
 #endif
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     precomputeJacobiansOnQuadraturePoints(const Array<Real> & nodes,
-					  const GhostType & ghost_type) {
+                                          const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & jacobians_tmp = jacobians.alloc(0, 1, type, ghost_type);
 
   this->computeJacobiansOnIntegrationPoints<type>(
       nodes, quadrature_points(type, ghost_type), jacobians_tmp, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::multiplyJacobiansByWeights(
     Array<Real> & jacobians) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points =
       GaussIntegrationElement<type, polynomial_degree>::getNbQuadraturePoints();
   UInt nb_element = jacobians.size() / nb_quadrature_points;
 
   Vector<Real> weights =
       GaussIntegrationElement<type, polynomial_degree>::getWeights();
 
-  Array<Real>::vector_iterator jacobians_it =
+  auto jacobians_it =
       jacobians.begin_reinterpret(nb_quadrature_points, nb_element);
-  Array<Real>::vector_iterator jacobians_end =
+  auto jacobians_end =
       jacobians.end_reinterpret(nb_quadrature_points, nb_element);
 
   for (; jacobians_it != jacobians_end; ++jacobians_it) {
     Vector<Real> & J = *jacobians_it;
     J *= weights;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
     const Array<Real> & jacobians, UInt nb_element) const {
   AKANTU_DEBUG_IN();
 
   intf.resize(nb_element);
   if (nb_element == 0)
     return;
 
   UInt nb_points = jacobians.size() / nb_element;
 
   Array<Real>::const_matrix_iterator J_it;
   Array<Real>::matrix_iterator inte_it;
   Array<Real>::const_matrix_iterator f_it;
 
   f_it = in_f.begin_reinterpret(nb_degree_of_freedom, nb_points, nb_element);
   inte_it = intf.begin_reinterpret(nb_degree_of_freedom, 1, nb_element);
   J_it = jacobians.begin_reinterpret(nb_points, 1, nb_element);
 
   for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
     const Matrix<Real> & f = *f_it;
     const Matrix<Real> & J = *J_it;
     Matrix<Real> & inte_f = *inte_it;
 
     inte_f.mul<false, false>(f, J);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
     const GhostType & ghost_type, const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
-		      "No jacobians for the type "
-			  << jacobians.printType(type, ghost_type));
+                      "No jacobians for the type "
+                          << jacobians.printType(type, ghost_type));
 
   const Array<Real> & jac_loc = jacobians(type, ghost_type);
   if (filter_elements != empty_filter) {
     UInt nb_element = filter_elements.size();
     Array<Real> * filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
     FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
-				  filter_elements);
+                                  filter_elements);
     this->integrate(in_f, intf, nb_degree_of_freedom, *filtered_J, nb_element);
     delete filtered_J;
   } else {
     UInt nb_element = mesh.getNbElement(type, ghost_type);
     this->integrate(in_f, intf, nb_degree_of_freedom, jac_loc, nb_element);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, Array<Real> & intf, UInt nb_degree_of_freedom,
     const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   Matrix<Real> quads = this->getIntegrationPoints<type, polynomial_degree>();
 
   Array<Real> jacobians;
   this->computeJacobiansOnIntegrationPoints<type>(mesh.getNodes(), quads,
-						  jacobians, ghost_type);
+                                                  jacobians, ghost_type);
   this->multiplyJacobiansByWeights<type, polynomial_degree>(jacobians);
 
   this->integrate(in_f, intf, nb_degree_of_freedom, jacobians,
-		  mesh.getNbElement(type, ghost_type));
+                  mesh.getNbElement(type, ghost_type));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type, UInt polynomial_degree>
 Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, const GhostType & ghost_type) const {
   AKANTU_DEBUG_IN();
 
   Array<Real> intfv(0, 1);
   integrate<type, polynomial_degree>(in_f, intfv, 1, ghost_type);
 
   Real res = Math::reduce(intfv);
 
   AKANTU_DEBUG_OUT();
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 Real IntegratorGauss<kind, IntegrationOrderFunctor>::integrate(
     const Array<Real> & in_f, const GhostType & ghost_type,
     const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
-		      "No jacobians for the type "
-			  << jacobians.printType(type, ghost_type));
+                      "No jacobians for the type "
+                          << jacobians.printType(type, ghost_type));
 
   Array<Real> intfv(0, 1);
   integrate<type>(in_f, intfv, 1, ghost_type, filter_elements);
 
   Real res = Math::reduce(intfv);
 
   AKANTU_DEBUG_OUT();
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     integrateOnIntegrationPoints(const Array<Real> & in_f, Array<Real> & intf,
-				 UInt nb_degree_of_freedom,
-				 const Array<Real> & jacobians,
-				 UInt nb_element) const {
+                                 UInt nb_degree_of_freedom,
+                                 const Array<Real> & jacobians,
+                                 UInt nb_element) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_points = jacobians.size() / nb_element;
 
-  Array<Real>::const_scalar_iterator J_it;
-  Array<Real>::vector_iterator inte_it;
-  Array<Real>::const_vector_iterator f_it;
-
   intf.resize(nb_element * nb_points);
 
-  J_it = jacobians.begin();
-  f_it = in_f.begin(nb_degree_of_freedom);
-  inte_it = intf.begin(nb_degree_of_freedom);
+  auto J_it = jacobians.begin();
+  auto f_it = in_f.begin(nb_degree_of_freedom);
+  auto inte_it = intf.begin(nb_degree_of_freedom);
 
   for (UInt el = 0; el < nb_element; ++el, ++J_it, ++f_it, ++inte_it) {
     const Real & J = *J_it;
     const Vector<Real> & f = *f_it;
     Vector<Real> & inte_f = *inte_it;
 
     inte_f = f;
     inte_f *= J;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     integrateOnIntegrationPoints(const Array<Real> & in_f, Array<Real> & intf,
-				 UInt nb_degree_of_freedom,
-				 const GhostType & ghost_type,
-				 const Array<UInt> & filter_elements) const {
+                                 UInt nb_degree_of_freedom,
+                                 const GhostType & ghost_type,
+                                 const Array<UInt> & filter_elements) const {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(jacobians.exists(type, ghost_type),
-		      "No jacobians for the type "
-			  << jacobians.printType(type, ghost_type));
+                      "No jacobians for the type "
+                          << jacobians.printType(type, ghost_type));
 
   const Array<Real> & jac_loc = this->jacobians(type, ghost_type);
 
   if (filter_elements != empty_filter) {
 
     UInt nb_element = filter_elements.size();
     Array<Real> * filtered_J = new Array<Real>(0, jac_loc.getNbComponent());
     FEEngine::filterElementalData(mesh, jac_loc, *filtered_J, type, ghost_type,
-				  filter_elements);
+                                  filter_elements);
 
     this->integrateOnIntegrationPoints(in_f, intf, nb_degree_of_freedom,
-				       *filtered_J, nb_element);
+                                       *filtered_J, nb_element);
   } else {
     UInt nb_element = mesh.getNbElement(type, ghost_type);
     this->integrateOnIntegrationPoints(in_f, intf, nb_degree_of_freedom,
-				       jac_loc, nb_element);
+                                       jac_loc, nb_element);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::onElementsAdded(
     const Array<Element> & new_elements) {
 
   const auto & nodes = mesh.getNodes();
 
   for (auto elements_range : MeshElementsByTypes(new_elements)) {
     auto type = elements_range.getType();
     auto ghost_type = elements_range.getGhostType();
 
     if (mesh.getKind(type) != kind)
       continue;
 
     auto & elements = elements_range.getElements();
 
     if (not jacobians.exists(type, ghost_type))
       jacobians.alloc(0, 1, type, ghost_type);
 
     this->computeJacobiansOnIntegrationPoints(
-	nodes, quadrature_points(type, ghost_type), jacobians(type, ghost_type),
-	type, ghost_type, elements);
+        nodes, quadrature_points(type, ghost_type), jacobians(type, ghost_type),
+        type, ghost_type, elements);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementKind kind, class IntegrationOrderFunctor>
 template <ElementType type>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::initIntegrator(
     const Array<Real> & nodes, const GhostType & ghost_type) {
   computeQuadraturePoints<type>(ghost_type);
   precomputeJacobiansOnQuadraturePoints<type>(nodes, ghost_type);
   checkJacobians<type>(ghost_type);
   constexpr UInt polynomial_degree =
       IntegrationOrderFunctor::template getOrder<type>();
   multiplyJacobiansByWeights<type, polynomial_degree>(
       this->jacobians(type, ghost_type));
 }
 
 namespace integrator {
   namespace details {
     template <ElementKind kind> struct GaussIntegratorInitHelper {};
 
 #define INIT_INTEGRATOR(type)                                                  \
   _int.template initIntegrator<type>(nodes, ghost_type)
 
 #define AKANTU_GAUSS_INTERGRATOR_INIT_HELPER(kind)                             \
   template <> struct GaussIntegratorInitHelper<kind> {                         \
     template <ElementKind k, class IOF>                                        \
     static void call(IntegratorGauss<k, IOF> & _int,                           \
-		     const Array<Real> & nodes, const ElementType & type,      \
-		     const GhostType & ghost_type) {                           \
+                     const Array<Real> & nodes, const ElementType & type,      \
+                     const GhostType & ghost_type) {                           \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(INIT_INTEGRATOR, kind);                 \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_GAUSS_INTERGRATOR_INIT_HELPER)
 
 #undef AKANTU_GAUSS_INTERGRATOR_INIT_HELPER
 #undef INIT_INTEGRATOR
   } // namespace details
 } // namespace integrator
 
 template <ElementKind kind, class IntegrationOrderFunctor>
 inline void IntegratorGauss<kind, IntegrationOrderFunctor>::initIntegrator(
     const Array<Real> & nodes, const ElementType & type,
     const GhostType & ghost_type) {
   integrator::details::GaussIntegratorInitHelper<kind>::call(*this, nodes, type,
-							     ghost_type);
+                                                             ghost_type);
 }
 
 namespace integrator {
   namespace details {
     template <ElementKind kind> struct GaussIntegratorComputeJacobiansHelper {};
 
 #define AKANTU_COMPUTE_JACOBIANS(type)                                         \
   _int.template computeJacobiansOnIntegrationPoints<type>(                     \
       nodes, quad_points, jacobians, ghost_type, filter_elements);
 
 #define AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS(kind)                       \
   template <> struct GaussIntegratorComputeJacobiansHelper<kind> {             \
     template <ElementKind k, class IOF>                                        \
     static void                                                                \
     call(const IntegratorGauss<k, IOF> & _int, const Array<Real> & nodes,      \
-	 const Matrix<Real> & quad_points, Array<Real> & jacobians,            \
-	 const ElementType & type, const GhostType & ghost_type,               \
-	 const Array<UInt> & filter_elements) {                                \
+         const Matrix<Real> & quad_points, Array<Real> & jacobians,            \
+         const ElementType & type, const GhostType & ghost_type,               \
+         const Array<UInt> & filter_elements) {                                \
       AKANTU_BOOST_KIND_ELEMENT_SWITCH(AKANTU_COMPUTE_JACOBIANS, kind);        \
     }                                                                          \
   };
 
     AKANTU_BOOST_ALL_KIND(AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS)
 
 #undef AKANTU_GAUSS_INTERGRATOR_COMPUTE_JACOBIANS
 #undef AKANTU_COMPUTE_JACOBIANS
   } // namespace details
 } // namespace integrator
 
 template <ElementKind kind, class IntegrationOrderFunctor>
 void IntegratorGauss<kind, IntegrationOrderFunctor>::
     computeJacobiansOnIntegrationPoints(
-	const Array<Real> & nodes, const Matrix<Real> & quad_points,
-	Array<Real> & jacobians, const ElementType & type,
-	const GhostType & ghost_type,
-	const Array<UInt> & filter_elements) const {
+        const Array<Real> & nodes, const Matrix<Real> & quad_points,
+        Array<Real> & jacobians, const ElementType & type,
+        const GhostType & ghost_type,
+        const Array<UInt> & filter_elements) const {
   integrator::details::GaussIntegratorComputeJacobiansHelper<kind>::call(
       *this, nodes, quad_points, jacobians, type, ghost_type, filter_elements);
 }
 
 } // namespace akantu
diff --git a/src/geometry/mesh_sphere_intersector_tmpl.hh b/src/geometry/mesh_sphere_intersector_tmpl.hh
index d95d86710..f02b004c6 100644
--- a/src/geometry/mesh_sphere_intersector_tmpl.hh
+++ b/src/geometry/mesh_sphere_intersector_tmpl.hh
@@ -1,195 +1,195 @@
 /**
  * @file   mesh_sphere_intersector_tmpl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Jun 23 2015
  * @date last modification: Thu Jan 14 2016
  *
  * @brief  Computation of mesh intersection with spheres
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
 #define __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
 
 #include "aka_common.hh"
 #include "mesh_geom_common.hh"
 #include "tree_type_helper.hh"
 #include "mesh_sphere_intersector.hh"
 
 namespace akantu {
 
 template<UInt dim, ElementType type>
 MeshSphereIntersector<dim, type>::MeshSphereIntersector(Mesh & mesh):
   parent_type(mesh),
   tol_intersection_on_node(1e-10)
 {
 #if defined(AKANTU_IGFEM)
   if( (type == _triangle_3) || (type == _igfem_triangle_4) || (type == _igfem_triangle_5) ){
     const_cast<UInt &>(this->nb_seg_by_el) = 3;
   } else {
     AKANTU_ERROR("Not ready for mesh type " << type);
   }
 #else
   if( (type != _triangle_3) )
     AKANTU_ERROR("Not ready for mesh type " << type);
 #endif
 
   // initialize the intersection pointsss array with the spatial dimension
   this->intersection_points = new Array<Real>(0,dim);
   //  A maximum is set to the number of intersection nodes per element to limit the size of new_node_per_elem: 2 in 2D and 4 in 3D
   this->new_node_per_elem = new Array<UInt>(0, 1 + 4 * (dim-1));
 }
 
 template<UInt dim, ElementType type>
 MeshSphereIntersector<dim, type>::~MeshSphereIntersector() {
   delete this->new_node_per_elem;
   delete this->intersection_points;
 }
 
 template<UInt dim, ElementType type>
 void MeshSphereIntersector<dim, type>::constructData(GhostType ghost_type) {
 
   this->new_node_per_elem->resize(this->mesh.getNbElement(type, ghost_type));
   this->new_node_per_elem->clear();
 
   MeshGeomIntersector<dim, type, Line_arc<SK>, SK::Sphere_3, SK>::constructData(ghost_type);
 }
 
 template<UInt dim, ElementType type>
 void MeshSphereIntersector<dim, type>:: computeMeshQueryIntersectionPoint(const SK::Sphere_3 & query,
 									  UInt nb_old_nodes) {
   /// function to replace computeIntersectionQuery in a more generic geometry module version
   // The newNodeEvent is not send from this method who only compute the intersection points
   AKANTU_DEBUG_IN();
 
   Array<Real> & nodes = this->mesh.getNodes();
   UInt nb_node = nodes.size() + this->intersection_points->size();
 
   // Tolerance for proximity checks should be defined by user
   Real global_tolerance = Math::getTolerance();
   Math::setTolerance(tol_intersection_on_node);
   typedef boost::variant<pair_type> sk_inter_res;
 
   TreeTypeHelper<Line_arc<cgal::Spherical>, cgal::Spherical>::const_iterator
     it = this->factory.getPrimitiveList().begin(),
     end= this->factory.getPrimitiveList().end();
 
   for (; it != end ; ++it) { // loop on the primitives (segments)
     std::list<sk_inter_res> s_results;
     CGAL::intersection(*it, query, std::back_inserter(s_results));
 
     if (s_results.size() == 1) { // just one point
       if (pair_type * pair = boost::get<pair_type>(&s_results.front())) {
         if (pair->second == 1) { // not a point tangent to the sphere
           // the intersection point written as a vector
           Vector<Real> new_node(dim, 0.0);
           cgal::Cartesian::Point_3 point(CGAL::to_double(pair->first.x()),
                                    CGAL::to_double(pair->first.y()),
                                    CGAL::to_double(pair->first.z()));
           for (UInt i = 0 ; i < dim ; i++) {
             new_node(i) = point[i];
           }
 
 	  /// boolean to decide wheter intersection point is on a standard node of the mesh or not
           bool is_on_mesh = false;
 	  /// boolean to decide if this intersection point has been already computed for a neighbor element
 	  bool is_new = true;
         
 	  /// check if intersection point has already been computed
 	  UInt n = nb_old_nodes;
 
           // check if we already compute this intersection and add it as a node for a neighboor element of another type
-	  Array<Real>::vector_iterator existing_node = nodes.begin(dim);
+	  auto existing_node = nodes.begin(dim);
 
 	  for (; n < nodes.size() ; ++n) {// loop on the nodes from nb_old_nodes
 	    if (Math::are_vector_equal(dim, new_node.storage(), existing_node[n].storage())) {
 	      is_new = false;
 	      break;
 	    }
 	  }
 	  if(is_new){
-	    Array<Real>::vector_iterator intersection_points_it = this->intersection_points->begin(dim);
-	    Array<Real>::vector_iterator intersection_points_end = this->intersection_points->end(dim);
+	    auto intersection_points_it = this->intersection_points->begin(dim);
+	    auto intersection_points_end = this->intersection_points->end(dim);
 	    for (; intersection_points_it != intersection_points_end ; ++intersection_points_it, ++n) {
 	      if (Math::are_vector_equal(dim, new_node.storage(), intersection_points_it->storage())) {
 		is_new = false;
 		break;
 	      }
 	    }
 	  }
 	  
 	  // get the initial and final points of the primitive (segment) and write them as vectors
 	  cgal::Cartesian::Point_3 source_cgal(CGAL::to_double(it->source().x()),
 					 CGAL::to_double(it->source().y()),
 					 CGAL::to_double(it->source().z()));
 	  cgal::Cartesian::Point_3 target_cgal(CGAL::to_double(it->target().x()),
 					 CGAL::to_double(it->target().y()),
 					 CGAL::to_double(it->target().z()));
 	  Vector<Real> source(dim), target(dim);
 	  for (UInt i = 0 ; i < dim ; i++) {
 	    source(i) = source_cgal[i];
 	    target(i) = target_cgal[i];
 	  }
 
 	  // Check if we are close from a node of the primitive (segment)
 	  if (Math::are_vector_equal(dim, source.storage(), new_node.storage()) ||
 	      Math::are_vector_equal(dim, target.storage(), new_node.storage())) {
 	    is_on_mesh = true;
 	    is_new = false;
 	  }
 
 	  if (is_new) {// if the intersection point is a new one add it to the list
 	    this->intersection_points->push_back(new_node);
 	    nb_node++;
 	  }
 
 	  // deduce the element id
 	  UInt element_id = it->id();
 
 	  // fill the new_node_per_elem array
 	  if (!is_on_mesh) { // if the node is not on a mesh node
 	    UInt & nb_new_nodes_per_el = (*this->new_node_per_elem)(element_id, 0);
 	    nb_new_nodes_per_el += 1;
 	    AKANTU_DEBUG_ASSERT(2 * nb_new_nodes_per_el < this->new_node_per_elem->getNbComponent(),
 				"You might have to interface crossing the same material");
 	    (*this->new_node_per_elem)(element_id, (2 * nb_new_nodes_per_el) - 1) = n;
 	    (*this->new_node_per_elem)(element_id, 2 * nb_new_nodes_per_el) = it->segId();
 	  } 
 	}
       }
     }
   }
 
   Math::setTolerance(global_tolerance);
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
 
 #endif // __AKANTU_MESH_SPHERE_INTERSECTOR_TMPL_HH__
diff --git a/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc b/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
index c50f985ac..1721808e0 100644
--- a/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
+++ b/src/mesh_utils/mesh_partition/mesh_partition_scotch.cc
@@ -1,481 +1,481 @@
 /**
  * @file   mesh_partition_scotch.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Jan 22 2016
  *
  * @brief  implementation of the MeshPartitionScotch class
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "mesh_partition_scotch.hh"
 #include "aka_common.hh"
 #include "aka_random_generator.hh"
 #include "aka_static_if.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <cstdio>
 #include <fstream>
 /* -------------------------------------------------------------------------- */
 
 #if !defined(AKANTU_USE_PTSCOTCH)
 #ifndef AKANTU_SCOTCH_NO_EXTERN
 extern "C" {
 #endif // AKANTU_SCOTCH_NO_EXTERN
 #include <scotch.h>
 #ifndef AKANTU_SCOTCH_NO_EXTERN
 }
 #endif // AKANTU_SCOTCH_NO_EXTERN
 #else  // AKANTU_USE_PTSCOTCH
 #include <ptscotch.h>
 #endif // AKANTU_USE_PTSCOTCH
 
 namespace akantu {
 
 namespace {
   constexpr int scotch_version = int(SCOTCH_VERSION);
 }
 
 /* -------------------------------------------------------------------------- */
 MeshPartitionScotch::MeshPartitionScotch(const Mesh & mesh,
                                          UInt spatial_dimension, const ID & id,
                                          const MemoryID & memory_id)
     : MeshPartition(mesh, spatial_dimension, id, memory_id) {
   AKANTU_DEBUG_IN();
 
   // check if the akantu types and Scotch one are consistent
   static_assert(
       sizeof(Int) == sizeof(SCOTCH_Num),
       "The integer type of Akantu does not match the one from Scotch");
 
   static_if(aka::bool_constant_v<scotch_version >= 6>)
       .then([](auto && y) { SCOTCH_randomSeed(y); })
       .else_([](auto && y) {
         srandom(y);
       })(std::forward<UInt>(RandomGenerator<UInt>::seed()));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 static SCOTCH_Mesh * createMesh(const Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt nb_nodes = mesh.getNbNodes();
 
   UInt total_nb_element = 0;
   UInt nb_edge = 0;
 
   Mesh::type_iterator it = mesh.firstType(spatial_dimension);
   Mesh::type_iterator end = mesh.lastType(spatial_dimension);
   for (; it != end; ++it) {
     ElementType type = *it;
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     total_nb_element += nb_element;
     nb_edge += nb_element * nb_nodes_per_element;
   }
 
   SCOTCH_Num vnodbas = 0;
   SCOTCH_Num vnodnbr = nb_nodes;
 
   SCOTCH_Num velmbas = vnodnbr;
   SCOTCH_Num velmnbr = total_nb_element;
 
   auto * verttab = new SCOTCH_Num[vnodnbr + velmnbr + 1];
   SCOTCH_Num * vendtab = verttab + 1;
 
   SCOTCH_Num * velotab = nullptr;
   SCOTCH_Num * vnlotab = nullptr;
   SCOTCH_Num * vlbltab = nullptr;
 
   memset(verttab, 0, (vnodnbr + velmnbr + 1) * sizeof(SCOTCH_Num));
 
   it = mesh.firstType(spatial_dimension);
   for (; it != end; ++it) {
     ElementType type = *it;
     if (Mesh::getSpatialDimension(type) != spatial_dimension)
       continue;
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     /// count number of occurrence of each node
     for (UInt el = 0; el < nb_element; ++el) {
       UInt * conn_val = connectivity.storage() + el * nb_nodes_per_element;
       for (UInt n = 0; n < nb_nodes_per_element; ++n) {
         verttab[*(conn_val++)]++;
       }
     }
   }
 
   /// convert the occurrence array in a csr one
   for (UInt i = 1; i < nb_nodes; ++i)
     verttab[i] += verttab[i - 1];
   for (UInt i = nb_nodes; i > 0; --i)
     verttab[i] = verttab[i - 1];
   verttab[0] = 0;
 
   /// rearrange element to get the node-element list
   SCOTCH_Num edgenbr = verttab[vnodnbr] + nb_edge;
   auto * edgetab = new SCOTCH_Num[edgenbr];
 
   UInt linearized_el = 0;
 
   it = mesh.firstType(spatial_dimension);
   for (; it != end; ++it) {
     ElementType type = *it;
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     for (UInt el = 0; el < nb_element; ++el, ++linearized_el) {
       UInt * conn_val = connectivity.storage() + el * nb_nodes_per_element;
       for (UInt n = 0; n < nb_nodes_per_element; ++n)
         edgetab[verttab[*(conn_val++)]++] = linearized_el + velmbas;
     }
   }
 
   for (UInt i = nb_nodes; i > 0; --i)
     verttab[i] = verttab[i - 1];
   verttab[0] = 0;
 
   SCOTCH_Num * verttab_tmp = verttab + vnodnbr + 1;
   SCOTCH_Num * edgetab_tmp = edgetab + verttab[vnodnbr];
 
   it = mesh.firstType(spatial_dimension);
   for (; it != end; ++it) {
     ElementType type = *it;
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     for (UInt el = 0; el < nb_element; ++el) {
       *verttab_tmp = *(verttab_tmp - 1) + nb_nodes_per_element;
       verttab_tmp++;
       UInt * conn = connectivity.storage() + el * nb_nodes_per_element;
       for (UInt i = 0; i < nb_nodes_per_element; ++i) {
         *(edgetab_tmp++) = *(conn++) + vnodbas;
       }
     }
   }
 
   auto * meshptr = new SCOTCH_Mesh;
 
   SCOTCH_meshInit(meshptr);
 
   SCOTCH_meshBuild(meshptr, velmbas, vnodbas, velmnbr, vnodnbr, verttab,
                    vendtab, velotab, vnlotab, vlbltab, edgenbr, edgetab);
 
   /// Check the mesh
   AKANTU_DEBUG_ASSERT(SCOTCH_meshCheck(meshptr) == 0,
                       "Scotch mesh is not consistent");
 
 #ifndef AKANTU_NDEBUG
   if (AKANTU_DEBUG_TEST(dblDump)) {
     /// save initial graph
     FILE * fmesh = fopen("ScotchMesh.msh", "w");
     SCOTCH_meshSave(meshptr, fmesh);
     fclose(fmesh);
 
     /// write geometry file
     std::ofstream fgeominit;
     fgeominit.open("ScotchMesh.xyz");
     fgeominit << spatial_dimension << std::endl << nb_nodes << std::endl;
 
     const Array<Real> & nodes = mesh.getNodes();
     Real * nodes_val = nodes.storage();
     for (UInt i = 0; i < nb_nodes; ++i) {
       fgeominit << i << " ";
       for (UInt s = 0; s < spatial_dimension; ++s)
         fgeominit << *(nodes_val++) << " ";
       fgeominit << std::endl;
       ;
     }
     fgeominit.close();
   }
 #endif
 
   AKANTU_DEBUG_OUT();
   return meshptr;
 }
 
 /* -------------------------------------------------------------------------- */
 static void destroyMesh(SCOTCH_Mesh * meshptr) {
   AKANTU_DEBUG_IN();
 
   SCOTCH_Num velmbas, vnodbas, vnodnbr, velmnbr, *verttab, *vendtab, *velotab,
       *vnlotab, *vlbltab, edgenbr, *edgetab, degrptr;
 
   SCOTCH_meshData(meshptr, &velmbas, &vnodbas, &velmnbr, &vnodnbr, &verttab,
                   &vendtab, &velotab, &vnlotab, &vlbltab, &edgenbr, &edgetab,
                   &degrptr);
 
   delete[] verttab;
   delete[] edgetab;
 
   SCOTCH_meshExit(meshptr);
 
   delete meshptr;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartitionScotch::partitionate(UInt nb_part,
                                        const EdgeLoadFunctor & edge_load_func,
                                        const Array<UInt> & pairs) {
   AKANTU_DEBUG_IN();
 
   nb_partitions = nb_part;
 
   tweakConnectivity(pairs);
 
   AKANTU_DEBUG_INFO("Partitioning the mesh " << mesh.getID() << " in "
                                              << nb_part << " parts.");
 
   Array<Int> dxadj;
   Array<Int> dadjncy;
   Array<Int> edge_loads;
   buildDualGraph(dxadj, dadjncy, edge_loads, edge_load_func);
 
   /// variables that will hold our structures in scotch format
   SCOTCH_Graph scotch_graph;
   SCOTCH_Strat scotch_strat;
 
   /// description number and arrays for struct mesh for scotch
   SCOTCH_Num baseval = 0; // base numbering for element and
   // nodes (0 -> C , 1 -> fortran)
   SCOTCH_Num vertnbr = dxadj.size() - 1; // number of vertexes
   SCOTCH_Num * parttab;                  // array of partitions
   SCOTCH_Num edgenbr = dxadj(vertnbr);   // twice  the number  of "edges"
   //(an "edge" bounds two nodes)
   SCOTCH_Num * verttab = dxadj.storage(); // array of start indices in edgetab
   SCOTCH_Num * vendtab = nullptr; // array of after-last indices in edgetab
   SCOTCH_Num * velotab = nullptr; // integer  load  associated with
   // every vertex ( optional )
   SCOTCH_Num * edlotab = edge_loads.storage(); // integer  load  associated with
   // every edge ( optional )
   SCOTCH_Num * edgetab = dadjncy.storage(); // adjacency array of every vertex
   SCOTCH_Num * vlbltab = nullptr;           // vertex label array (optional)
 
   /// Allocate space for Scotch arrays
   parttab = new SCOTCH_Num[vertnbr];
 
   /// Initialize the strategy structure
   SCOTCH_stratInit(&scotch_strat);
 
   /// Initialize the graph structure
   SCOTCH_graphInit(&scotch_graph);
 
   /// Build the graph from the adjacency arrays
   SCOTCH_graphBuild(&scotch_graph, baseval, vertnbr, verttab, vendtab, velotab,
                     vlbltab, edgenbr, edgetab, edlotab);
 
 #ifndef AKANTU_NDEBUG
   if (AKANTU_DEBUG_TEST(dblDump)) {
     /// save initial graph
     FILE * fgraphinit = fopen("GraphIniFile.grf", "w");
     SCOTCH_graphSave(&scotch_graph, fgraphinit);
     fclose(fgraphinit);
 
     /// write geometry file
     std::ofstream fgeominit;
     fgeominit.open("GeomIniFile.xyz");
     fgeominit << spatial_dimension << std::endl << vertnbr << std::endl;
 
     const Array<Real> & nodes = mesh.getNodes();
 
     Mesh::type_iterator f_it =
         mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
     Mesh::type_iterator f_end =
         mesh.lastType(spatial_dimension, _not_ghost, _ek_not_defined);
-    Array<Real>::const_vector_iterator nodes_it =
+    auto nodes_it =
         nodes.begin(spatial_dimension);
 
     UInt out_linerized_el = 0;
     for (; f_it != f_end; ++f_it) {
       ElementType type = *f_it;
 
       UInt nb_element = mesh.getNbElement(*f_it);
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
       const Array<UInt> & connectivity = mesh.getConnectivity(type);
 
       Vector<Real> mid(spatial_dimension);
       for (UInt el = 0; el < nb_element; ++el) {
         mid.set(0.);
         for (UInt n = 0; n < nb_nodes_per_element; ++n) {
           UInt node = connectivity.storage()[nb_nodes_per_element * el + n];
           mid += Vector<Real>(nodes_it[node]);
         }
         mid /= nb_nodes_per_element;
 
         fgeominit << out_linerized_el++ << " ";
         for (UInt s = 0; s < spatial_dimension; ++s)
           fgeominit << mid[s] << " ";
 
         fgeominit << std::endl;
         ;
       }
     }
     fgeominit.close();
   }
 #endif
   /// Check the graph
   AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
                       "Graph to partition is not consistent");
 
   /// Partition the mesh
   SCOTCH_graphPart(&scotch_graph, nb_part, &scotch_strat, parttab);
 
   /// Check the graph
   AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
                       "Partitioned graph is not consistent");
 
 #ifndef AKANTU_NDEBUG
   if (AKANTU_DEBUG_TEST(dblDump)) {
     /// save the partitioned graph
     FILE * fgraph = fopen("GraphFile.grf", "w");
     SCOTCH_graphSave(&scotch_graph, fgraph);
     fclose(fgraph);
 
     /// save the partition map
     std::ofstream fmap;
     fmap.open("MapFile.map");
     fmap << vertnbr << std::endl;
     for (Int i = 0; i < vertnbr; i++)
       fmap << i << "    " << parttab[i] << std::endl;
     fmap.close();
   }
 #endif
 
   /// free the scotch data structures
   SCOTCH_stratExit(&scotch_strat);
   SCOTCH_graphFree(&scotch_graph);
   SCOTCH_graphExit(&scotch_graph);
 
   fillPartitionInformation(mesh, parttab);
 
   delete[] parttab;
 
   restoreConnectivity();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartitionScotch::reorder() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Reordering the mesh " << mesh.getID());
   SCOTCH_Mesh * scotch_mesh = createMesh(mesh);
 
   UInt nb_nodes = mesh.getNbNodes();
 
   SCOTCH_Strat scotch_strat;
   // SCOTCH_Ordering scotch_order;
 
   auto * permtab = new SCOTCH_Num[nb_nodes];
   SCOTCH_Num * peritab = nullptr;
   SCOTCH_Num cblknbr = 0;
   SCOTCH_Num * rangtab = nullptr;
   SCOTCH_Num * treetab = nullptr;
 
   /// Initialize the strategy structure
   SCOTCH_stratInit(&scotch_strat);
 
   SCOTCH_Graph scotch_graph;
 
   SCOTCH_graphInit(&scotch_graph);
   SCOTCH_meshGraph(scotch_mesh, &scotch_graph);
 
 #ifndef AKANTU_NDEBUG
   if (AKANTU_DEBUG_TEST(dblDump)) {
     FILE * fgraphinit = fopen("ScotchMesh.grf", "w");
     SCOTCH_graphSave(&scotch_graph, fgraphinit);
     fclose(fgraphinit);
   }
 #endif
 
   /// Check the graph
   // AKANTU_DEBUG_ASSERT(SCOTCH_graphCheck(&scotch_graph) == 0,
   //		      "Mesh to Graph is not consistent");
 
   SCOTCH_graphOrder(&scotch_graph, &scotch_strat, permtab, peritab, &cblknbr,
                     rangtab, treetab);
 
   SCOTCH_graphExit(&scotch_graph);
   SCOTCH_stratExit(&scotch_strat);
   destroyMesh(scotch_mesh);
 
   /// Renumbering
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     auto gt = (GhostType)g;
 
     Mesh::type_iterator it = mesh.firstType(_all_dimensions, gt);
     Mesh::type_iterator end = mesh.lastType(_all_dimensions, gt);
 
     for (; it != end; ++it) {
       ElementType type = *it;
 
       UInt nb_element = mesh.getNbElement(type, gt);
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
       const Array<UInt> & connectivity = mesh.getConnectivity(type, gt);
 
       UInt * conn = connectivity.storage();
       for (UInt el = 0; el < nb_element * nb_nodes_per_element; ++el, ++conn) {
         *conn = permtab[*conn];
       }
     }
   }
 
   /// \todo think of a in-place way to do it
   auto * new_coordinates = new Real[spatial_dimension * nb_nodes];
   Real * old_coordinates = mesh.getNodes().storage();
   for (UInt i = 0; i < nb_nodes; ++i) {
     memcpy(new_coordinates + permtab[i] * spatial_dimension,
            old_coordinates + i * spatial_dimension,
            spatial_dimension * sizeof(Real));
   }
   memcpy(old_coordinates, new_coordinates,
          nb_nodes * spatial_dimension * sizeof(Real));
   delete[] new_coordinates;
 
   delete[] permtab;
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/mesh_utils.cc b/src/mesh_utils/mesh_utils.cc
index 93f8e8090..7cd39ff8a 100644
--- a/src/mesh_utils/mesh_utils.cc
+++ b/src/mesh_utils/mesh_utils.cc
@@ -1,2173 +1,2173 @@
 /**
  * @file   mesh_utils.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Aug 20 2010
  * @date last modification: Fri Jan 22 2016
  *
  * @brief  All mesh utils necessary for various tasks
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "mesh_utils.hh"
 #include "element_synchronizer.hh"
 #include "fe_engine.hh"
 #include "mesh_accessor.hh"
 /* -------------------------------------------------------------------------- */
 #include <limits>
 #include <numeric>
 #include <queue>
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildNode2Elements(const Mesh & mesh,
                                    CSR<Element> & node_to_elem,
                                    UInt spatial_dimension) {
   AKANTU_DEBUG_IN();
   if (spatial_dimension == _all_dimensions)
     spatial_dimension = mesh.getSpatialDimension();
 
   /// count number of occurrence of each node
   UInt nb_nodes = mesh.getNbNodes();
 
   /// array for the node-element list
   node_to_elem.resizeRows(nb_nodes);
   node_to_elem.clearRows();
 
   AKANTU_DEBUG_ASSERT(
       mesh.firstType(spatial_dimension) != mesh.lastType(spatial_dimension),
       "Some elements must be found in right dimension to compute facets!");
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     Mesh::type_iterator first =
         mesh.firstType(spatial_dimension, *gt, _ek_not_defined);
     Mesh::type_iterator last =
         mesh.lastType(spatial_dimension, *gt, _ek_not_defined);
 
     for (; first != last; ++first) {
       ElementType type = *first;
       UInt nb_element = mesh.getNbElement(type, *gt);
       Array<UInt>::const_iterator<Vector<UInt>> conn_it =
           mesh.getConnectivity(type, *gt).begin(
               Mesh::getNbNodesPerElement(type));
 
       for (UInt el = 0; el < nb_element; ++el, ++conn_it)
         for (UInt n = 0; n < conn_it->size(); ++n)
           ++node_to_elem.rowOffset((*conn_it)(n));
     }
   }
 
   node_to_elem.countToCSR();
   node_to_elem.resizeCols();
 
   /// rearrange element to get the node-element list
   Element e;
   node_to_elem.beginInsertions();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     Mesh::type_iterator first =
         mesh.firstType(spatial_dimension, *gt, _ek_not_defined);
     Mesh::type_iterator last =
         mesh.lastType(spatial_dimension, *gt, _ek_not_defined);
     e.ghost_type = *gt;
     for (; first != last; ++first) {
       ElementType type = *first;
       e.type = type;
       UInt nb_element = mesh.getNbElement(type, *gt);
       Array<UInt>::const_iterator<Vector<UInt>> conn_it =
           mesh.getConnectivity(type, *gt).begin(
               Mesh::getNbNodesPerElement(type));
 
       for (UInt el = 0; el < nb_element; ++el, ++conn_it) {
         e.element = el;
         for (UInt n = 0; n < conn_it->size(); ++n)
           node_to_elem.insertInRow((*conn_it)(n), e);
       }
     }
   }
 
   node_to_elem.endInsertions();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * This function should disappear in the future (used in mesh partitioning)
  */
 // void MeshUtils::buildNode2Elements(const Mesh & mesh, CSR<UInt> &
 // node_to_elem,
 //                                    UInt spatial_dimension) {
 //   AKANTU_DEBUG_IN();
 //   if (spatial_dimension == _all_dimensions)
 //     spatial_dimension = mesh.getSpatialDimension();
 //   UInt nb_nodes = mesh.getNbNodes();
 
 //   const Mesh::ConnectivityTypeList & type_list =
 //   mesh.getConnectivityTypeList(); Mesh::ConnectivityTypeList::const_iterator
 //   it;
 
 //   UInt nb_types = type_list.size();
 //   UInt nb_good_types = 0;
 
 //   Vector<UInt> nb_nodes_per_element(nb_types);
 //   UInt ** conn_val = new UInt *[nb_types];
 //   Vector<UInt> nb_element(nb_types);
 
 //   for (it = type_list.begin(); it != type_list.end(); ++it) {
 //     ElementType type = *it;
 //     if (Mesh::getSpatialDimension(type) != spatial_dimension)
 //       continue;
 
 //     nb_nodes_per_element[nb_good_types] = Mesh::getNbNodesPerElement(type);
 //     conn_val[nb_good_types] = mesh.getConnectivity(type,
 //     _not_ghost).storage(); nb_element[nb_good_types] =
 //         mesh.getConnectivity(type, _not_ghost).size();
 //     nb_good_types++;
 //   }
 
 //   AKANTU_DEBUG_ASSERT(
 //       nb_good_types != 0,
 //       "Some elements must be found in right dimension to compute facets!");
 
 //   /// array for the node-element list
 //   node_to_elem.resizeRows(nb_nodes);
 //   node_to_elem.clearRows();
 
 //   /// count number of occurrence of each node
 //   for (UInt t = 0; t < nb_good_types; ++t) {
 //     for (UInt el = 0; el < nb_element[t]; ++el) {
 //       UInt el_offset = el * nb_nodes_per_element[t];
 //       for (UInt n = 0; n < nb_nodes_per_element[t]; ++n) {
 //         ++node_to_elem.rowOffset(conn_val[t][el_offset + n]);
 //       }
 //     }
 //   }
 
 //   node_to_elem.countToCSR();
 //   node_to_elem.resizeCols();
 //   node_to_elem.beginInsertions();
 
 //   /// rearrange element to get the node-element list
 //   for (UInt t = 0, linearized_el = 0; t < nb_good_types; ++t)
 //     for (UInt el = 0; el < nb_element[t]; ++el, ++linearized_el) {
 //       UInt el_offset = el * nb_nodes_per_element[t];
 //       for (UInt n = 0; n < nb_nodes_per_element[t]; ++n)
 //         node_to_elem.insertInRow(conn_val[t][el_offset + n], linearized_el);
 //     }
 
 //   node_to_elem.endInsertions();
 //   delete[] conn_val;
 //   AKANTU_DEBUG_OUT();
 // }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildNode2ElementsElementTypeMap(const Mesh & mesh,
                                                  CSR<UInt> & node_to_elem,
                                                  const ElementType & type,
                                                  const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
   UInt nb_nodes = mesh.getNbNodes();
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_elements = mesh.getConnectivity(type, ghost_type).size();
 
   UInt * conn_val = mesh.getConnectivity(type, ghost_type).storage();
 
   /// array for the node-element list
   node_to_elem.resizeRows(nb_nodes);
   node_to_elem.clearRows();
 
   /// count number of occurrence of each node
   for (UInt el = 0; el < nb_elements; ++el) {
     UInt el_offset = el * nb_nodes_per_element;
     for (UInt n = 0; n < nb_nodes_per_element; ++n)
       ++node_to_elem.rowOffset(conn_val[el_offset + n]);
   }
 
   /// convert the occurrence array in a csr one
   node_to_elem.countToCSR();
 
   node_to_elem.resizeCols();
   node_to_elem.beginInsertions();
 
   /// save the element index in the node-element list
   for (UInt el = 0; el < nb_elements; ++el) {
     UInt el_offset = el * nb_nodes_per_element;
     for (UInt n = 0; n < nb_nodes_per_element; ++n) {
       node_to_elem.insertInRow(conn_val[el_offset + n], el);
     }
   }
 
   node_to_elem.endInsertions();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildFacets(Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType gt_facet = *gt;
     Mesh::type_iterator it = mesh.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end = mesh.lastType(spatial_dimension - 1, gt_facet);
     for (; it != end; ++it) {
       mesh.getConnectivity(*it, *gt).resize(0);
       // \todo inform the mesh event handler
     }
   }
 
   buildFacetsDimension(mesh, mesh, true, spatial_dimension);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
                                UInt to_dimension) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   buildAllFacets(mesh, mesh_facets, spatial_dimension, to_dimension);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
                                UInt from_dimension, UInt to_dimension) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(
       mesh_facets.isMeshFacets(),
       "The mesh_facets should be initialized with initMeshFacets");
 
   /// generate facets
   buildFacetsDimension(mesh, mesh_facets, false, from_dimension);
 
   /// copy nodes type
   MeshAccessor mesh_accessor_facets(mesh_facets);
   mesh_accessor_facets.getNodesType().copy(mesh.getNodesType());
 
   /// sort facets and generate sub-facets
   for (UInt i = from_dimension - 1; i > to_dimension; --i) {
     buildFacetsDimension(mesh_facets, mesh_facets, false, i);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildFacetsDimension(const Mesh & mesh, Mesh & mesh_facets,
                                      bool boundary_only, UInt dimension) {
   AKANTU_DEBUG_IN();
 
   // save the current parent of mesh_facets and set it temporarly to mesh since
   // mesh is the one containing the elements for which mesh_facets has the
   // sub-elements
   // example: if the function is called with mesh = mesh_facets
   const Mesh * mesh_facets_parent = nullptr;
   try {
     mesh_facets_parent = &mesh_facets.getMeshParent();
   } catch (...) {
   }
 
   mesh_facets.defineMeshParent(mesh);
   MeshAccessor mesh_accessor(mesh_facets);
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   const Array<Real> & mesh_facets_nodes = mesh_facets.getNodes();
-  const Array<Real>::const_vector_iterator mesh_facets_nodes_it =
+  const auto mesh_facets_nodes_it =
       mesh_facets_nodes.begin(spatial_dimension);
 
   CSR<Element> node_to_elem;
   buildNode2Elements(mesh, node_to_elem, dimension);
 
   Array<UInt> counter;
   std::vector<Element> connected_elements;
 
   // init the SubelementToElement data to improve performance
   for (auto && ghost_type : ghost_types) {
     for (auto && type : mesh.elementTypes(dimension, ghost_type)) {
       mesh_accessor.getSubelementToElement(type, ghost_type);
 
       auto facet_types = mesh.getAllFacetTypes(type);
 
       for (auto && ft : arange(facet_types.size())) {
         auto facet_type = facet_types(ft);
         mesh_accessor.getElementToSubelement(facet_type, ghost_type);
         mesh_accessor.getConnectivity(facet_type, ghost_type);
       }
     }
   }
 
   const ElementSynchronizer * synchronizer = nullptr;
   if (mesh.isDistributed()) {
     synchronizer = &(mesh.getElementSynchronizer());
   }
 
   Element current_element;
   for (auto && ghost_type : ghost_types) {
     GhostType facet_ghost_type = ghost_type;
     current_element.ghost_type = ghost_type;
 
     for (auto && type : mesh.elementTypes(dimension, ghost_type)) {
       auto facet_types = mesh.getAllFacetTypes(type);
       current_element.type = type;
 
       for (auto && ft : arange(facet_types.size())) {
         auto facet_type = facet_types(ft);
         auto nb_element = mesh.getNbElement(type, ghost_type);
 
         auto element_to_subelement =
             &mesh_facets.getElementToSubelement(facet_type, ghost_type);
         auto connectivity_facets =
             &mesh_facets.getConnectivity(facet_type, ghost_type);
 
         auto nb_facet_per_element = mesh.getNbFacetsPerElement(type, ft);
         const auto & element_connectivity =
             mesh.getConnectivity(type, ghost_type);
         Matrix<const UInt> facet_local_connectivity(
             mesh.getFacetLocalConnectivity(type, ft));
 
         auto nb_nodes_per_facet = connectivity_facets->getNbComponent();
         Vector<UInt> facet(nb_nodes_per_facet);
 
         for (UInt el = 0; el < nb_element; ++el) {
           current_element.element = el;
 
           for (UInt f = 0; f < nb_facet_per_element; ++f) {
             for (UInt n = 0; n < nb_nodes_per_facet; ++n)
               facet(n) =
                   element_connectivity(el, facet_local_connectivity(f, n));
 
             UInt first_node_nb_elements = node_to_elem.getNbCols(facet(0));
             counter.resize(first_node_nb_elements);
             counter.clear();
 
             // loop over the other nodes to search intersecting elements,
             // which are the elements that share another node with the
             // starting element after first_node
             UInt local_el = 0;
             auto first_node_elements = node_to_elem.begin(facet(0));
             auto first_node_elements_end = node_to_elem.end(facet(0));
             for (; first_node_elements != first_node_elements_end;
                  ++first_node_elements, ++local_el) {
               for (UInt n = 1; n < nb_nodes_per_facet; ++n) {
                 auto node_elements_begin = node_to_elem.begin(facet(n));
                 auto node_elements_end = node_to_elem.end(facet(n));
                 counter(local_el) +=
                     std::count(node_elements_begin, node_elements_end,
                                *first_node_elements);
               }
             }
 
             // counting the number of elements connected to the facets and
             // taking the minimum element number, because the facet should
             // be inserted just once
             UInt nb_element_connected_to_facet = 0;
             Element minimum_el = ElementNull;
             connected_elements.clear();
             for (UInt el_f = 0; el_f < first_node_nb_elements; el_f++) {
               Element real_el = node_to_elem(facet(0), el_f);
               if (not(counter(el_f) == nb_nodes_per_facet - 1))
                 continue;
 
               ++nb_element_connected_to_facet;
               minimum_el = std::min(minimum_el, real_el);
               connected_elements.push_back(real_el);
             }
 
             if (minimum_el != current_element)
               continue;
 
             bool full_ghost_facet = false;
 
             UInt n = 0;
             while (n < nb_nodes_per_facet && mesh.isPureGhostNode(facet(n)))
               ++n;
             if (n == nb_nodes_per_facet)
               full_ghost_facet = true;
 
             if (full_ghost_facet)
               continue;
 
             if (boundary_only and nb_element_connected_to_facet != 1)
               continue;
 
             std::vector<Element> elements;
 
             // build elements_on_facets: linearized_el must come first
             // in order to store the facet in the correct direction
             // and avoid to invert the sign in the normal computation
             elements.push_back(current_element);
 
             if (nb_element_connected_to_facet == 1) { /// boundary facet
               elements.push_back(ElementNull);
             } else if (nb_element_connected_to_facet == 2) { /// internal facet
               elements.push_back(connected_elements[1]);
 
               /// check if facet is in between ghost and normal
               /// elements: if it's the case, the facet is either
               /// ghost or not ghost. The criterion to decide this
               /// is arbitrary. It was chosen to check the processor
               /// id (prank) of the two neighboring elements. If
               /// prank of the ghost element is lower than prank of
               /// the normal one, the facet is not ghost, otherwise
               /// it's ghost
               GhostType gt[2] = {_not_ghost, _not_ghost};
               for (UInt el = 0; el < connected_elements.size(); ++el)
                 gt[el] = connected_elements[el].ghost_type;
 
               if (gt[0] != gt[1] and
                   (gt[0] == _not_ghost or gt[1] == _not_ghost)) {
                 UInt prank[2];
                 for (UInt el = 0; el < 2; ++el) {
                   prank[el] = synchronizer->getRank(connected_elements[el]);
                 }
 
                 // ugly trick from Marco detected :P
                 bool ghost_one = (gt[0] != _ghost);
                 if (prank[ghost_one] > prank[!ghost_one])
                   facet_ghost_type = _not_ghost;
                 else
                   facet_ghost_type = _ghost;
 
                 connectivity_facets =
                     &mesh_facets.getConnectivity(facet_type, facet_ghost_type);
                 element_to_subelement = &mesh_facets.getElementToSubelement(
                     facet_type, facet_ghost_type);
               }
             } else { /// facet of facet
               for (UInt i = 1; i < nb_element_connected_to_facet; ++i) {
                 elements.push_back(connected_elements[i]);
               }
             }
 
             element_to_subelement->push_back(elements);
             connectivity_facets->push_back(facet);
 
             /// current facet index
             UInt current_facet = connectivity_facets->size() - 1;
 
             /// loop on every element connected to current facet and
             /// insert current facet in the first free spot of the
             /// subelement_to_element vector
             for (UInt elem = 0; elem < elements.size(); ++elem) {
               Element loc_el = elements[elem];
 
               if (loc_el.type == _not_defined)
                 continue;
 
               Array<Element> & subelement_to_element =
                   mesh_facets.getSubelementToElement(loc_el.type,
                                                      loc_el.ghost_type);
 
               UInt nb_facet_per_loc_element =
                   subelement_to_element.getNbComponent();
 
               for (UInt f_in = 0; f_in < nb_facet_per_loc_element; ++f_in) {
                 auto & el = subelement_to_element(loc_el.element, f_in);
                 if (el.type != _not_defined)
                   continue;
 
                 el.type = facet_type;
                 el.element = current_facet;
                 el.ghost_type = facet_ghost_type;
                 break;
               }
             }
 
             /// reset connectivity in case a facet was found in
             /// between ghost and normal elements
             if (facet_ghost_type != ghost_type) {
               facet_ghost_type = ghost_type;
               connectivity_facets =
                   &mesh_accessor.getConnectivity(facet_type, facet_ghost_type);
               element_to_subelement = &mesh_accessor.getElementToSubelement(
                   facet_type, facet_ghost_type);
             }
           }
         }
       }
     }
   }
 
   // restore the parent of mesh_facet
   if (mesh_facets_parent)
     mesh_facets.defineMeshParent(*mesh_facets_parent);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::renumberMeshNodes(Mesh & mesh,
                                   Array<UInt> & local_connectivities,
                                   UInt nb_local_element, UInt nb_ghost_element,
                                   ElementType type,
                                   Array<UInt> & old_nodes_numbers) {
   AKANTU_DEBUG_IN();
 
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
   std::map<UInt, UInt> renumbering_map;
   for (UInt i = 0; i < old_nodes_numbers.size(); ++i) {
     renumbering_map[old_nodes_numbers(i)] = i;
   }
 
   /// renumber the nodes
   renumberNodesInConnectivity(local_connectivities,
                               (nb_local_element + nb_ghost_element) *
                                   nb_nodes_per_element,
                               renumbering_map);
 
   old_nodes_numbers.resize(renumbering_map.size());
   for (auto & renumber_pair : renumbering_map) {
     old_nodes_numbers(renumber_pair.second) = renumber_pair.first;
   }
   renumbering_map.clear();
 
   MeshAccessor mesh_accessor(mesh);
 
   /// copy the renumbered connectivity to the right place
   auto & local_conn = mesh_accessor.getConnectivity(type);
   local_conn.resize(nb_local_element);
   memcpy(local_conn.storage(), local_connectivities.storage(),
          nb_local_element * nb_nodes_per_element * sizeof(UInt));
 
   auto & ghost_conn = mesh_accessor.getConnectivity(type, _ghost);
   ghost_conn.resize(nb_ghost_element);
   std::memcpy(ghost_conn.storage(),
               local_connectivities.storage() +
                   nb_local_element * nb_nodes_per_element,
               nb_ghost_element * nb_nodes_per_element * sizeof(UInt));
 
   auto & ghost_counter = mesh_accessor.getGhostsCounters(type, _ghost);
   ghost_counter.resize(nb_ghost_element, 1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::renumberNodesInConnectivity(
     Array<UInt> & list_nodes, UInt nb_nodes,
     std::map<UInt, UInt> & renumbering_map) {
   AKANTU_DEBUG_IN();
 
   UInt * connectivity = list_nodes.storage();
   UInt new_node_num = renumbering_map.size();
   for (UInt n = 0; n < nb_nodes; ++n, ++connectivity) {
     UInt & node = *connectivity;
     auto it = renumbering_map.find(node);
     if (it == renumbering_map.end()) {
       UInt old_node = node;
       renumbering_map[old_node] = new_node_num;
       node = new_node_num;
       ++new_node_num;
     } else {
       node = it->second;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::purifyMesh(Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   std::map<UInt, UInt> renumbering_map;
 
   RemovedNodesEvent remove_nodes(mesh);
   Array<UInt> & nodes_removed = remove_nodes.getList();
 
   for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
     auto ghost_type = (GhostType)gt;
 
     Mesh::type_iterator it =
         mesh.firstType(_all_dimensions, ghost_type, _ek_not_defined);
     Mesh::type_iterator end =
         mesh.lastType(_all_dimensions, ghost_type, _ek_not_defined);
     for (; it != end; ++it) {
 
       ElementType type(*it);
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
       Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
       UInt nb_element(connectivity.size());
 
       renumberNodesInConnectivity(
           connectivity, nb_element * nb_nodes_per_element, renumbering_map);
     }
   }
 
   Array<UInt> & new_numbering = remove_nodes.getNewNumbering();
   std::fill(new_numbering.begin(), new_numbering.end(), UInt(-1));
 
   auto it = renumbering_map.begin();
   auto end = renumbering_map.end();
   for (; it != end; ++it) {
     new_numbering(it->first) = it->second;
   }
 
   for (UInt i = 0; i < new_numbering.size(); ++i) {
     if (new_numbering(i) == UInt(-1))
       nodes_removed.push_back(i);
   }
 
   mesh.sendEvent(remove_nodes);
 
   AKANTU_DEBUG_OUT();
 }
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
 /* -------------------------------------------------------------------------- */
 UInt MeshUtils::insertCohesiveElements(
     Mesh & mesh, Mesh & mesh_facets,
     const ElementTypeMapArray<bool> & facet_insertion,
     Array<UInt> & doubled_nodes, Array<Element> & new_elements,
     bool only_double_facets) {
   UInt spatial_dimension = mesh.getSpatialDimension();
   UInt elements_to_insert = updateFacetToDouble(mesh_facets, facet_insertion);
 
   if (elements_to_insert > 0) {
 
     if (spatial_dimension == 1) {
       doublePointFacet(mesh, mesh_facets, doubled_nodes);
     } else {
       doubleFacet(mesh, mesh_facets, spatial_dimension - 1, doubled_nodes,
                   true);
       findSubfacetToDouble<false>(mesh, mesh_facets);
 
       if (spatial_dimension == 2) {
         doubleSubfacet<2>(mesh, mesh_facets, doubled_nodes);
       } else if (spatial_dimension == 3) {
         doubleFacet(mesh, mesh_facets, 1, doubled_nodes, false);
         findSubfacetToDouble<true>(mesh, mesh_facets);
         doubleSubfacet<3>(mesh, mesh_facets, doubled_nodes);
       }
     }
 
     if (!only_double_facets)
       updateCohesiveData(mesh, mesh_facets, new_elements);
   }
 
   return elements_to_insert;
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::doubleNodes(Mesh & mesh, const std::vector<UInt> & old_nodes,
                             Array<UInt> & doubled_nodes) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & position = mesh.getNodes();
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   UInt old_nb_nodes = position.size();
   UInt new_nb_nodes = old_nb_nodes + old_nodes.size();
 
   UInt old_nb_doubled_nodes = doubled_nodes.size();
   UInt new_nb_doubled_nodes = old_nb_doubled_nodes + old_nodes.size();
 
   position.resize(new_nb_nodes);
   doubled_nodes.resize(new_nb_doubled_nodes);
 
   Array<Real>::iterator<Vector<Real>> position_begin =
       position.begin(spatial_dimension);
 
   for (UInt n = 0; n < old_nodes.size(); ++n) {
     UInt new_node = old_nb_nodes + n;
 
     /// store doubled nodes
     doubled_nodes(old_nb_doubled_nodes + n, 0) = old_nodes[n];
     doubled_nodes(old_nb_doubled_nodes + n, 1) = new_node;
 
     /// update position
     std::copy(position_begin + old_nodes[n], position_begin + old_nodes[n] + 1,
               position_begin + new_node);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::doubleFacet(Mesh & mesh, Mesh & mesh_facets,
                             UInt facet_dimension, Array<UInt> & doubled_nodes,
                             bool facet_mode) {
   AKANTU_DEBUG_IN();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it = mesh_facets.firstType(facet_dimension, gt_facet);
     Mesh::type_iterator end = mesh_facets.lastType(facet_dimension, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
       UInt nb_facet_to_double = f_to_double.size();
 
       if (nb_facet_to_double == 0)
         continue;
 
       ElementType type_subfacet = Mesh::getFacetType(type_facet);
       const UInt nb_subfacet_per_facet =
           Mesh::getNbFacetsPerElement(type_facet);
       GhostType gt_subfacet = _casper;
       Array<std::vector<Element>> * f_to_subfacet = nullptr;
 
       Array<Element> & subfacet_to_facet =
           mesh_facets.getSubelementToElement(type_facet, gt_facet);
 
       Array<UInt> & conn_facet =
           mesh_facets.getConnectivity(type_facet, gt_facet);
       UInt nb_nodes_per_facet = conn_facet.getNbComponent();
 
       UInt old_nb_facet = conn_facet.size();
       UInt new_nb_facet = old_nb_facet + nb_facet_to_double;
 
       conn_facet.resize(new_nb_facet);
       subfacet_to_facet.resize(new_nb_facet);
 
       UInt new_facet = old_nb_facet - 1;
       Element new_facet_el{type_facet, 0, gt_facet};
 
       Array<Element>::iterator<Vector<Element>> subfacet_to_facet_begin =
           subfacet_to_facet.begin(nb_subfacet_per_facet);
       Array<UInt>::iterator<Vector<UInt>> conn_facet_begin =
           conn_facet.begin(nb_nodes_per_facet);
 
       for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
         UInt old_facet = f_to_double(facet);
         ++new_facet;
 
         /// adding a new facet by copying original one
 
         /// copy connectivity in new facet
         std::copy(conn_facet_begin + old_facet,
                   conn_facet_begin + old_facet + 1,
                   conn_facet_begin + new_facet);
 
         /// update subfacet_to_facet
         std::copy(subfacet_to_facet_begin + old_facet,
                   subfacet_to_facet_begin + old_facet + 1,
                   subfacet_to_facet_begin + new_facet);
 
         new_facet_el.element = new_facet;
 
         /// loop on every subfacet
         for (UInt sf = 0; sf < nb_subfacet_per_facet; ++sf) {
           Element & subfacet = subfacet_to_facet(old_facet, sf);
           if (subfacet == ElementNull)
             continue;
 
           if (gt_subfacet != subfacet.ghost_type) {
             gt_subfacet = subfacet.ghost_type;
             f_to_subfacet = &mesh_facets.getElementToSubelement(
                 type_subfacet, subfacet.ghost_type);
           }
 
           /// update facet_to_subfacet array
           (*f_to_subfacet)(subfacet.element).push_back(new_facet_el);
         }
       }
 
       /// update facet_to_subfacet and _segment_3 facets if any
       if (!facet_mode) {
         updateSubfacetToFacet(mesh_facets, type_facet, gt_facet, true);
         updateFacetToSubfacet(mesh_facets, type_facet, gt_facet, true);
         updateQuadraticSegments<true>(mesh, mesh_facets, type_facet, gt_facet,
                                       doubled_nodes);
       } else
         updateQuadraticSegments<false>(mesh, mesh_facets, type_facet, gt_facet,
                                        doubled_nodes);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt MeshUtils::updateFacetToDouble(
     Mesh & mesh_facets, const ElementTypeMapArray<bool> & facet_insertion) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh_facets.getSpatialDimension();
   UInt nb_facets_to_double = 0.;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       const Array<bool> & f_insertion = facet_insertion(type_facet, gt_facet);
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
 
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       ElementType el_type = _not_defined;
       GhostType el_gt = _casper;
       UInt nb_facet_per_element = 0;
       Element old_facet_el{type_facet, 0, gt_facet};
 
       Array<Element> * facet_to_element = nullptr;
 
       for (UInt f = 0; f < f_insertion.size(); ++f) {
 
         if (f_insertion(f) == false)
           continue;
 
         ++nb_facets_to_double;
 
         if (element_to_facet(f)[1].type == _not_defined
 #if defined(AKANTU_COHESIVE_ELEMENT)
             || element_to_facet(f)[1].kind() == _ek_cohesive
 #endif
         ) {
           AKANTU_DEBUG_WARNING("attempt to double a facet on the boundary");
           continue;
         }
 
         f_to_double.push_back(f);
 
         UInt new_facet = mesh_facets.getNbElement(type_facet, gt_facet) +
                          f_to_double.size() - 1;
         old_facet_el.element = f;
 
         /// update facet_to_element vector
         Element & elem_to_update = element_to_facet(f)[1];
         UInt el = elem_to_update.element;
 
         if (elem_to_update.ghost_type != el_gt ||
             elem_to_update.type != el_type) {
           el_type = elem_to_update.type;
           el_gt = elem_to_update.ghost_type;
           facet_to_element =
               &mesh_facets.getSubelementToElement(el_type, el_gt);
           nb_facet_per_element = facet_to_element->getNbComponent();
         }
 
         Element * f_update =
             std::find(facet_to_element->storage() + el * nb_facet_per_element,
                       facet_to_element->storage() + el * nb_facet_per_element +
                           nb_facet_per_element,
                       old_facet_el);
 
         AKANTU_DEBUG_ASSERT(
             facet_to_element->storage() + el * nb_facet_per_element !=
                 facet_to_element->storage() + el * nb_facet_per_element +
                     nb_facet_per_element,
             "Facet not found");
 
         f_update->element = new_facet;
 
         /// update elements connected to facet
         std::vector<Element> first_facet_list = element_to_facet(f);
         element_to_facet.push_back(first_facet_list);
 
         /// set new and original facets as boundary facets
         element_to_facet(new_facet)[0] = element_to_facet(new_facet)[1];
 
         element_to_facet(f)[1] = ElementNull;
         element_to_facet(new_facet)[1] = ElementNull;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
   return nb_facets_to_double;
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::resetFacetToDouble(Mesh & mesh_facets) {
   AKANTU_DEBUG_IN();
 
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     auto gt = (GhostType)g;
 
     Mesh::type_iterator it = mesh_facets.firstType(_all_dimensions, gt);
     Mesh::type_iterator end = mesh_facets.lastType(_all_dimensions, gt);
     for (; it != end; ++it) {
       ElementType type = *it;
       mesh_facets.getDataPointer<UInt>("facet_to_double", type, gt, 1, false);
 
       mesh_facets.getDataPointer<std::vector<Element>>(
           "facets_to_subfacet_double", type, gt, 1, false);
 
       mesh_facets.getDataPointer<std::vector<Element>>(
           "elements_to_subfacet_double", type, gt, 1, false);
 
       mesh_facets.getDataPointer<std::vector<Element>>(
           "subfacets_to_subsubfacet_double", type, gt, 1, false);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool subsubfacet_mode>
 void MeshUtils::findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh_facets.getSpatialDimension();
   if (spatial_dimension == 1)
     return;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
       UInt nb_facet_to_double = f_to_double.size();
       if (nb_facet_to_double == 0)
         continue;
 
       ElementType type_subfacet = Mesh::getFacetType(type_facet);
       GhostType gt_subfacet = _casper;
 
       ElementType type_subsubfacet = Mesh::getFacetType(type_subfacet);
       GhostType gt_subsubfacet = _casper;
 
       Array<UInt> * conn_subfacet = nullptr;
       Array<UInt> * sf_to_double = nullptr;
       Array<std::vector<Element>> * sf_to_subfacet_double = nullptr;
       Array<std::vector<Element>> * f_to_subfacet_double = nullptr;
       Array<std::vector<Element>> * el_to_subfacet_double = nullptr;
 
       UInt nb_subfacet = Mesh::getNbFacetsPerElement(type_facet);
 
       UInt nb_subsubfacet;
       UInt nb_nodes_per_sf_el;
 
       if (subsubfacet_mode) {
         nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subsubfacet);
         nb_subsubfacet = Mesh::getNbFacetsPerElement(type_subfacet);
       } else
         nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subfacet);
 
       Array<Element> & subfacet_to_facet =
           mesh_facets.getSubelementToElement(type_facet, gt_facet);
 
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       Array<Element> * subsubfacet_to_subfacet = nullptr;
 
       UInt old_nb_facet = subfacet_to_facet.size() - nb_facet_to_double;
 
       Element current_facet{type_facet, 0, gt_facet};
       std::vector<Element> element_list;
       std::vector<Element> facet_list;
       std::vector<Element> * subfacet_list;
       if (subsubfacet_mode)
         subfacet_list = new std::vector<Element>;
 
       /// map to filter subfacets
       Array<std::vector<Element>> * facet_to_subfacet = nullptr;
 
       /// this is used to make sure that both new and old facets are
       /// checked
       UInt facets[2];
 
       /// loop on every facet
       for (UInt f_index = 0; f_index < 2; ++f_index) {
         for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
           facets[bool(f_index)] = f_to_double(facet);
           facets[!bool(f_index)] = old_nb_facet + facet;
 
           UInt old_facet = facets[0];
           UInt new_facet = facets[1];
 
           Element & starting_element = element_to_facet(new_facet)[0];
           current_facet.element = old_facet;
 
           /// loop on every subfacet
           for (UInt sf = 0; sf < nb_subfacet; ++sf) {
 
             Element & subfacet = subfacet_to_facet(old_facet, sf);
             if (subfacet == ElementNull)
               continue;
 
             if (gt_subfacet != subfacet.ghost_type) {
               gt_subfacet = subfacet.ghost_type;
 
               if (subsubfacet_mode) {
                 subsubfacet_to_subfacet = &mesh_facets.getSubelementToElement(
                     type_subfacet, gt_subfacet);
               } else {
                 conn_subfacet =
                     &mesh_facets.getConnectivity(type_subfacet, gt_subfacet);
                 sf_to_double = &mesh_facets.getData<UInt>(
                     "facet_to_double", type_subfacet, gt_subfacet);
 
                 f_to_subfacet_double =
                     &mesh_facets.getData<std::vector<Element>>(
                         "facets_to_subfacet_double", type_subfacet,
                         gt_subfacet);
 
                 el_to_subfacet_double =
                     &mesh_facets.getData<std::vector<Element>>(
                         "elements_to_subfacet_double", type_subfacet,
                         gt_subfacet);
 
                 facet_to_subfacet = &mesh_facets.getElementToSubelement(
                     type_subfacet, gt_subfacet);
               }
             }
 
             if (subsubfacet_mode) {
               /// loop on every subsubfacet
               for (UInt ssf = 0; ssf < nb_subsubfacet; ++ssf) {
                 Element & subsubfacet =
                     (*subsubfacet_to_subfacet)(subfacet.element, ssf);
 
                 if (subsubfacet == ElementNull)
                   continue;
 
                 if (gt_subsubfacet != subsubfacet.ghost_type) {
                   gt_subsubfacet = subsubfacet.ghost_type;
                   conn_subfacet = &mesh_facets.getConnectivity(type_subsubfacet,
                                                                gt_subsubfacet);
                   sf_to_double = &mesh_facets.getData<UInt>(
                       "facet_to_double", type_subsubfacet, gt_subsubfacet);
 
                   sf_to_subfacet_double =
                       &mesh_facets.getData<std::vector<Element>>(
                           "subfacets_to_subsubfacet_double", type_subsubfacet,
                           gt_subsubfacet);
 
                   f_to_subfacet_double =
                       &mesh_facets.getData<std::vector<Element>>(
                           "facets_to_subfacet_double", type_subsubfacet,
                           gt_subsubfacet);
 
                   el_to_subfacet_double =
                       &mesh_facets.getData<std::vector<Element>>(
                           "elements_to_subfacet_double", type_subsubfacet,
                           gt_subsubfacet);
 
                   facet_to_subfacet = &mesh_facets.getElementToSubelement(
                       type_subsubfacet, gt_subsubfacet);
                 }
 
                 UInt global_ssf = subsubfacet.element;
 
                 Vector<UInt> subsubfacet_connectivity(
                     conn_subfacet->storage() + global_ssf * nb_nodes_per_sf_el,
                     nb_nodes_per_sf_el);
 
                 /// check if subsubfacet is to be doubled
                 if (findElementsAroundSubfacet<true>(
                         mesh, mesh_facets, starting_element, current_facet,
                         subsubfacet_connectivity, element_list, facet_list,
                         subfacet_list) == false &&
                     removeElementsInVector(*subfacet_list,
                                            (*facet_to_subfacet)(global_ssf)) ==
                         false) {
 
                   sf_to_double->push_back(global_ssf);
                   sf_to_subfacet_double->push_back(*subfacet_list);
                   f_to_subfacet_double->push_back(facet_list);
                   el_to_subfacet_double->push_back(element_list);
                 }
               }
             } else {
               const UInt global_sf = subfacet.element;
 
               Vector<UInt> subfacet_connectivity(
                   conn_subfacet->storage() + global_sf * nb_nodes_per_sf_el,
                   nb_nodes_per_sf_el);
 
               /// check if subfacet is to be doubled
               if (findElementsAroundSubfacet<false>(
                       mesh, mesh_facets, starting_element, current_facet,
                       subfacet_connectivity, element_list,
                       facet_list) == false &&
                   removeElementsInVector(
                       facet_list, (*facet_to_subfacet)(global_sf)) == false) {
 
                 sf_to_double->push_back(global_sf);
                 f_to_subfacet_double->push_back(facet_list);
                 el_to_subfacet_double->push_back(element_list);
               }
             }
           }
         }
       }
 
       if (subsubfacet_mode)
         delete subfacet_list;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_COHESIVE_ELEMENT)
 void MeshUtils::updateCohesiveData(Mesh & mesh, Mesh & mesh_facets,
                                    Array<Element> & new_elements) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   bool third_dimension = spatial_dimension == 3;
 
   MeshAccessor mesh_facets_accessor(mesh_facets);
 
   for (auto gt_facet : ghost_types) {
     for (auto type_facet :
          mesh_facets.elementTypes(spatial_dimension - 1, gt_facet)) {
 
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
 
       UInt nb_facet_to_double = f_to_double.size();
       if (nb_facet_to_double == 0)
         continue;
 
       ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
 
       auto & facet_to_coh_element =
           mesh_facets_accessor.getSubelementToElement(type_cohesive, gt_facet);
 
       auto & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
       auto & conn_cohesive = mesh.getConnectivity(type_cohesive, gt_facet);
       UInt nb_nodes_per_facet = Mesh::getNbNodesPerElement(type_facet);
 
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       UInt old_nb_cohesive_elements = conn_cohesive.size();
       UInt new_nb_cohesive_elements = conn_cohesive.size() + nb_facet_to_double;
 
       UInt old_nb_facet = element_to_facet.size() - nb_facet_to_double;
       facet_to_coh_element.resize(new_nb_cohesive_elements);
       conn_cohesive.resize(new_nb_cohesive_elements);
 
       UInt new_elements_old_size = new_elements.size();
       new_elements.resize(new_elements_old_size + nb_facet_to_double);
 
       Element c_element{type_cohesive, 0, gt_facet};
       Element f_element{type_facet, 0, gt_facet};
 
       UInt facets[2];
 
       for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
 
         /// (in 3D cohesive elements connectivity is inverted)
         facets[third_dimension] = f_to_double(facet);
         facets[!third_dimension] = old_nb_facet + facet;
 
         UInt cohesive_element = old_nb_cohesive_elements + facet;
 
         /// store doubled facets
         f_element.element = facets[0];
         facet_to_coh_element(cohesive_element, 0) = f_element;
         f_element.element = facets[1];
         facet_to_coh_element(cohesive_element, 1) = f_element;
 
         /// modify cohesive elements' connectivity
         for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
           conn_cohesive(cohesive_element, n) = conn_facet(facets[0], n);
           conn_cohesive(cohesive_element, n + nb_nodes_per_facet) =
               conn_facet(facets[1], n);
         }
 
         /// update element_to_facet vectors
         c_element.element = cohesive_element;
         element_to_facet(facets[0])[1] = c_element;
         element_to_facet(facets[1])[1] = c_element;
 
         /// add cohesive element to the element event list
         new_elements(new_elements_old_size + facet) = c_element;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::doublePointFacet(Mesh & mesh, Mesh & mesh_facets,
                                  Array<UInt> & doubled_nodes) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   if (spatial_dimension != 1)
     return;
 
   Array<Real> & position = mesh.getNodes();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       Array<UInt> & conn_facet =
           mesh_facets.getConnectivity(type_facet, gt_facet);
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       const Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
 
       UInt nb_facet_to_double = f_to_double.size();
 
       UInt old_nb_facet = element_to_facet.size() - nb_facet_to_double;
       UInt new_nb_facet = element_to_facet.size();
 
       UInt old_nb_nodes = position.size();
       UInt new_nb_nodes = old_nb_nodes + nb_facet_to_double;
 
       position.resize(new_nb_nodes);
       conn_facet.resize(new_nb_facet);
 
       UInt old_nb_doubled_nodes = doubled_nodes.size();
       doubled_nodes.resize(old_nb_doubled_nodes + nb_facet_to_double);
 
       for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
         UInt old_facet = f_to_double(facet);
         UInt new_facet = old_nb_facet + facet;
 
         ElementType type = element_to_facet(new_facet)[0].type;
         UInt el = element_to_facet(new_facet)[0].element;
         GhostType gt = element_to_facet(new_facet)[0].ghost_type;
 
         UInt old_node = conn_facet(old_facet);
         UInt new_node = old_nb_nodes + facet;
 
         /// update position
         position(new_node) = position(old_node);
 
         conn_facet(new_facet) = new_node;
         Array<UInt> & conn_segment = mesh.getConnectivity(type, gt);
         UInt nb_nodes_per_segment = conn_segment.getNbComponent();
 
         /// update facet connectivity
         UInt i;
         for (i = 0;
              conn_segment(el, i) != old_node && i <= nb_nodes_per_segment; ++i)
           ;
         conn_segment(el, i) = new_node;
 
         doubled_nodes(old_nb_doubled_nodes + facet, 0) = old_node;
         doubled_nodes(old_nb_doubled_nodes + facet, 1) = new_node;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool third_dim_segments>
 void MeshUtils::updateQuadraticSegments(Mesh & mesh, Mesh & mesh_facets,
                                         ElementType type_facet,
                                         GhostType gt_facet,
                                         Array<UInt> & doubled_nodes) {
   AKANTU_DEBUG_IN();
 
   if (type_facet != _segment_3)
     return;
 
   Array<UInt> & f_to_double =
       mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
   UInt nb_facet_to_double = f_to_double.size();
 
   UInt old_nb_facet =
       mesh_facets.getNbElement(type_facet, gt_facet) - nb_facet_to_double;
 
   Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
 
   Array<std::vector<Element>> & element_to_facet =
       mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
   /// this ones matter only for segments in 3D
   Array<std::vector<Element>> * el_to_subfacet_double = nullptr;
   Array<std::vector<Element>> * f_to_subfacet_double = nullptr;
 
   if (third_dim_segments) {
     el_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
         "elements_to_subfacet_double", type_facet, gt_facet);
 
     f_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
         "facets_to_subfacet_double", type_facet, gt_facet);
   }
 
   std::vector<UInt> middle_nodes;
 
   for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
     UInt old_facet = f_to_double(facet);
     UInt node = conn_facet(old_facet, 2);
     if (!mesh.isPureGhostNode(node))
       middle_nodes.push_back(node);
   }
 
   UInt n = doubled_nodes.size();
 
   doubleNodes(mesh, middle_nodes, doubled_nodes);
 
   for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
     UInt old_facet = f_to_double(facet);
     UInt old_node = conn_facet(old_facet, 2);
     if (mesh.isPureGhostNode(old_node))
       continue;
 
     UInt new_node = doubled_nodes(n, 1);
     UInt new_facet = old_nb_facet + facet;
 
     conn_facet(new_facet, 2) = new_node;
 
     if (third_dim_segments) {
       updateElementalConnectivity(mesh_facets, old_node, new_node,
                                   element_to_facet(new_facet));
 
       updateElementalConnectivity(mesh, old_node, new_node,
                                   (*el_to_subfacet_double)(facet),
                                   &(*f_to_subfacet_double)(facet));
     } else {
       updateElementalConnectivity(mesh, old_node, new_node,
                                   element_to_facet(new_facet));
     }
     ++n;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::updateSubfacetToFacet(Mesh & mesh_facets,
                                       ElementType type_subfacet,
                                       GhostType gt_subfacet, bool facet_mode) {
   AKANTU_DEBUG_IN();
 
   Array<UInt> & sf_to_double =
       mesh_facets.getData<UInt>("facet_to_double", type_subfacet, gt_subfacet);
   UInt nb_subfacet_to_double = sf_to_double.size();
 
   /// update subfacet_to_facet vector
   ElementType type_facet = _not_defined;
   GhostType gt_facet = _casper;
   Array<Element> * subfacet_to_facet = nullptr;
   UInt nb_subfacet_per_facet = 0;
   UInt old_nb_subfacet = mesh_facets.getNbElement(type_subfacet, gt_subfacet) -
                          nb_subfacet_to_double;
 
   Array<std::vector<Element>> * facet_list = nullptr;
   if (facet_mode)
     facet_list = &mesh_facets.getData<std::vector<Element>>(
         "facets_to_subfacet_double", type_subfacet, gt_subfacet);
   else
     facet_list = &mesh_facets.getData<std::vector<Element>>(
         "subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
 
   Element old_subfacet_el{type_subfacet, 0, gt_subfacet};
   Element new_subfacet_el{type_subfacet, 0, gt_subfacet};
 
   for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
     old_subfacet_el.element = sf_to_double(sf);
     new_subfacet_el.element = old_nb_subfacet + sf;
 
     for (UInt f = 0; f < (*facet_list)(sf).size(); ++f) {
       Element & facet = (*facet_list)(sf)[f];
 
       if (facet.type != type_facet || facet.ghost_type != gt_facet) {
         type_facet = facet.type;
         gt_facet = facet.ghost_type;
 
         subfacet_to_facet =
             &mesh_facets.getSubelementToElement(type_facet, gt_facet);
         nb_subfacet_per_facet = subfacet_to_facet->getNbComponent();
       }
 
       Element * sf_update = std::find(
           subfacet_to_facet->storage() + facet.element * nb_subfacet_per_facet,
           subfacet_to_facet->storage() + facet.element * nb_subfacet_per_facet +
               nb_subfacet_per_facet,
           old_subfacet_el);
 
       AKANTU_DEBUG_ASSERT(subfacet_to_facet->storage() +
                                   facet.element * nb_subfacet_per_facet !=
                               subfacet_to_facet->storage() +
                                   facet.element * nb_subfacet_per_facet +
                                   nb_subfacet_per_facet,
                           "Subfacet not found");
 
       *sf_update = new_subfacet_el;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::updateFacetToSubfacet(Mesh & mesh_facets,
                                       ElementType type_subfacet,
                                       GhostType gt_subfacet, bool facet_mode) {
   AKANTU_DEBUG_IN();
 
   Array<UInt> & sf_to_double =
       mesh_facets.getData<UInt>("facet_to_double", type_subfacet, gt_subfacet);
   UInt nb_subfacet_to_double = sf_to_double.size();
 
   Array<std::vector<Element>> & facet_to_subfacet =
       mesh_facets.getElementToSubelement(type_subfacet, gt_subfacet);
 
   Array<std::vector<Element>> * facet_to_subfacet_double = nullptr;
 
   if (facet_mode) {
     facet_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
         "facets_to_subfacet_double", type_subfacet, gt_subfacet);
   } else {
     facet_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
         "subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
   }
 
   UInt old_nb_subfacet = facet_to_subfacet.size();
   facet_to_subfacet.resize(old_nb_subfacet + nb_subfacet_to_double);
 
   for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf)
     facet_to_subfacet(old_nb_subfacet + sf) = (*facet_to_subfacet_double)(sf);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MeshUtils::doubleSubfacet(Mesh & mesh, Mesh & mesh_facets,
                                Array<UInt> & doubled_nodes) {
   AKANTU_DEBUG_IN();
 
   if (spatial_dimension == 1)
     return;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_subfacet = *gt;
 
     Mesh::type_iterator it = mesh_facets.firstType(0, gt_subfacet);
     Mesh::type_iterator end = mesh_facets.lastType(0, gt_subfacet);
 
     for (; it != end; ++it) {
 
       ElementType type_subfacet = *it;
 
       Array<UInt> & sf_to_double = mesh_facets.getData<UInt>(
           "facet_to_double", type_subfacet, gt_subfacet);
       UInt nb_subfacet_to_double = sf_to_double.size();
 
       if (nb_subfacet_to_double == 0)
         continue;
 
       AKANTU_DEBUG_ASSERT(
           type_subfacet == _point_1,
           "Only _point_1 subfacet doubling is supported at the moment");
 
       Array<UInt> & conn_subfacet =
           mesh_facets.getConnectivity(type_subfacet, gt_subfacet);
 
       UInt old_nb_subfacet = conn_subfacet.size();
       UInt new_nb_subfacet = old_nb_subfacet + nb_subfacet_to_double;
 
       conn_subfacet.resize(new_nb_subfacet);
 
       std::vector<UInt> nodes_to_double;
       UInt old_nb_doubled_nodes = doubled_nodes.size();
 
       /// double nodes
       for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
         UInt old_subfacet = sf_to_double(sf);
         nodes_to_double.push_back(conn_subfacet(old_subfacet));
       }
 
       doubleNodes(mesh, nodes_to_double, doubled_nodes);
 
       /// add new nodes in connectivity
       for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
         UInt new_subfacet = old_nb_subfacet + sf;
         UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
 
         conn_subfacet(new_subfacet) = new_node;
       }
 
       /// update facet and element connectivity
       Array<std::vector<Element>> & f_to_subfacet_double =
           mesh_facets.getData<std::vector<Element>>("facets_to_subfacet_double",
                                                     type_subfacet, gt_subfacet);
 
       Array<std::vector<Element>> & el_to_subfacet_double =
           mesh_facets.getData<std::vector<Element>>(
               "elements_to_subfacet_double", type_subfacet, gt_subfacet);
 
       Array<std::vector<Element>> * sf_to_subfacet_double = nullptr;
 
       if (spatial_dimension == 3)
         sf_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
             "subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
 
       for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
         UInt old_node = doubled_nodes(old_nb_doubled_nodes + sf, 0);
         UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
 
         updateElementalConnectivity(mesh, old_node, new_node,
                                     el_to_subfacet_double(sf),
                                     &f_to_subfacet_double(sf));
 
         updateElementalConnectivity(mesh_facets, old_node, new_node,
                                     f_to_subfacet_double(sf));
 
         if (spatial_dimension == 3)
           updateElementalConnectivity(mesh_facets, old_node, new_node,
                                       (*sf_to_subfacet_double)(sf));
       }
 
       if (spatial_dimension == 2) {
         updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, true);
         updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, true);
       } else if (spatial_dimension == 3) {
         updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, false);
         updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, false);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::flipFacets(
     Mesh & mesh_facets, const ElementTypeMapArray<UInt> & global_connectivity,
     GhostType gt_facet) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh_facets.getSpatialDimension();
 
   /// get global connectivity for local mesh
   ElementTypeMapArray<UInt> global_connectivity_tmp("global_connectivity_tmp",
                                                     mesh_facets.getID(),
                                                     mesh_facets.getMemoryID());
 
   global_connectivity_tmp.initialize(
       mesh_facets, _spatial_dimension = spatial_dimension - 1,
       _ghost_type = gt_facet,
       _with_nb_nodes_per_element = true, _with_nb_element = true);
 
   mesh_facets.getGlobalConnectivity(global_connectivity_tmp);
 
   /// loop on every facet
   for (auto type_facet :
        mesh_facets.elementTypes(spatial_dimension - 1, gt_facet)) {
 
     auto & connectivity = mesh_facets.getConnectivity(type_facet, gt_facet);
     const auto & g_connectivity = global_connectivity(type_facet, gt_facet);
 
     auto & el_to_f = mesh_facets.getElementToSubelement(type_facet, gt_facet);
     auto & subfacet_to_facet =
         mesh_facets.getSubelementToElement(type_facet, gt_facet);
 
     UInt nb_subfacet_per_facet = subfacet_to_facet.getNbComponent();
     UInt nb_nodes_per_facet = connectivity.getNbComponent();
     UInt nb_facet = connectivity.size();
 
     UInt nb_nodes_per_P1_facet =
         Mesh::getNbNodesPerElement(Mesh::getP1ElementType(type_facet));
 
     auto & global_conn_tmp = global_connectivity_tmp(type_facet, gt_facet);
 
     auto conn_it = connectivity.begin(nb_nodes_per_facet);
     auto gconn_tmp_it = global_conn_tmp.begin(nb_nodes_per_facet);
     auto conn_glob_it = g_connectivity.begin(nb_nodes_per_facet);
     auto subf_to_f = subfacet_to_facet.begin(nb_subfacet_per_facet);
 
     auto * conn_tmp_pointer = new UInt[nb_nodes_per_facet];
     Vector<UInt> conn_tmp(conn_tmp_pointer, nb_nodes_per_facet);
 
     Element el_tmp;
     auto * subf_tmp_pointer = new Element[nb_subfacet_per_facet];
     Vector<Element> subf_tmp(subf_tmp_pointer, nb_subfacet_per_facet);
 
     for (UInt f = 0; f < nb_facet;
          ++f, ++conn_it, ++gconn_tmp_it, ++subf_to_f, ++conn_glob_it) {
 
       Vector<UInt> & gconn_tmp = *gconn_tmp_it;
       const Vector<UInt> & conn_glob = *conn_glob_it;
       Vector<UInt> & conn_local = *conn_it;
 
       /// skip facet if connectivities are the same
       if (gconn_tmp == conn_glob)
         continue;
 
       /// re-arrange connectivity
       conn_tmp = conn_local;
 
       UInt * begin = conn_glob.storage();
       UInt * end = conn_glob.storage() + nb_nodes_per_facet;
 
       for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
 
         UInt * new_node = std::find(begin, end, gconn_tmp(n));
         AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
 
         UInt new_position = new_node - begin;
 
         conn_local(new_position) = conn_tmp(n);
       }
 
       /// if 3D, check if facets are just rotated
       if (spatial_dimension == 3) {
         /// find first node
         UInt * new_node = std::find(begin, end, gconn_tmp(0));
         AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
 
         UInt new_position = new_node - begin;
         UInt n = 1;
 
         /// count how many nodes in the received connectivity follow
         /// the same order of those in the local connectivity
         for (; n < nb_nodes_per_P1_facet &&
                gconn_tmp(n) ==
                    conn_glob((new_position + n) % nb_nodes_per_P1_facet);
              ++n)
           ;
 
         /// skip the facet inversion if facet is just rotated
         if (n == nb_nodes_per_P1_facet)
           continue;
       }
 
       /// update data to invert facet
       el_tmp = el_to_f(f)[0];
       el_to_f(f)[0] = el_to_f(f)[1];
       el_to_f(f)[1] = el_tmp;
 
       subf_tmp = (*subf_to_f);
       (*subf_to_f)(0) = subf_tmp(1);
       (*subf_to_f)(1) = subf_tmp(0);
     }
 
     delete[] subf_tmp_pointer;
     delete[] conn_tmp_pointer;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::fillElementToSubElementsData(Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   if (mesh.getNbElement(mesh.getSpatialDimension() - 1) == 0) {
     AKANTU_DEBUG_INFO("There are not facets, add them in the mesh file or call "
                       "the buildFacet method.");
     return;
   }
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   ElementTypeMapArray<Real> barycenters("barycenter_tmp", mesh.getID(),
                                         mesh.getMemoryID());
   barycenters.initialize(mesh, _nb_component = spatial_dimension,
                          _spatial_dimension = _all_dimensions);
   // mesh.initElementTypeMapArray(barycenters, spatial_dimension,
   // _all_dimensions);
 
   Element element;
   for (auto ghost_type : ghost_types) {
     element.ghost_type = ghost_type;
     for (auto & type : mesh.elementTypes(_all_dimensions, ghost_type)) {
       element.type = type;
 
       UInt nb_element = mesh.getNbElement(type, ghost_type);
       Array<Real> & barycenters_arr = barycenters(type, ghost_type);
       barycenters_arr.resize(nb_element);
       auto bary = barycenters_arr.begin(spatial_dimension);
       auto bary_end = barycenters_arr.end(spatial_dimension);
 
       for (UInt el = 0; bary != bary_end; ++bary, ++el) {
         element.element = el;
         mesh.getBarycenter(element, *bary);
       }
     }
   }
 
   MeshAccessor mesh_accessor(mesh);
   for (Int sp(spatial_dimension); sp >= 1; --sp) {
     if (mesh.getNbElement(sp) == 0)
       continue;
 
     for (auto ghost_type : ghost_types) {
       for (auto & type : mesh.elementTypes(sp, ghost_type)) {
         mesh_accessor.getSubelementToElement(type, ghost_type)
             .resize(mesh.getNbElement(type, ghost_type));
         mesh_accessor.getSubelementToElement(type, ghost_type).clear();
       }
 
       for (auto & type : mesh.elementTypes(sp - 1, ghost_type)) {
         mesh_accessor.getElementToSubelement(type, ghost_type)
             .resize(mesh.getNbElement(type, ghost_type));
         mesh.getElementToSubelement(type, ghost_type).clear();
       }
     }
 
     CSR<Element> nodes_to_elements;
     buildNode2Elements(mesh, nodes_to_elements, sp);
 
     Element facet_element;
 
     for (auto ghost_type : ghost_types) {
       facet_element.ghost_type = ghost_type;
       for (auto & type : mesh.elementTypes(sp - 1, ghost_type)) {
         facet_element.type = type;
 
         auto & element_to_subelement =
             mesh.getElementToSubelement(type, ghost_type);
 
         const auto & connectivity = mesh.getConnectivity(type, ghost_type);
 
         auto fit = connectivity.begin(mesh.getNbNodesPerElement(type));
         auto fend = connectivity.end(mesh.getNbNodesPerElement(type));
 
         UInt fid = 0;
         for (; fit != fend; ++fit, ++fid) {
           const Vector<UInt> & facet = *fit;
           facet_element.element = fid;
           std::map<Element, UInt> element_seen_counter;
           UInt nb_nodes_per_facet =
               mesh.getNbNodesPerElement(Mesh::getP1ElementType(type));
 
           for (UInt n(0); n < nb_nodes_per_facet; ++n) {
 
             auto eit = nodes_to_elements.begin(facet(n));
             auto eend = nodes_to_elements.end(facet(n));
             for (; eit != eend; ++eit) {
               auto & elem = *eit;
               auto cit = element_seen_counter.find(elem);
               if (cit != element_seen_counter.end()) {
                 cit->second++;
               } else {
                 element_seen_counter[elem] = 1;
               }
             }
           }
 
           std::vector<Element> connected_elements;
           auto cit = element_seen_counter.begin();
           auto cend = element_seen_counter.end();
           for (; cit != cend; ++cit) {
             if (cit->second == nb_nodes_per_facet)
               connected_elements.push_back(cit->first);
           }
 
           auto ceit = connected_elements.begin();
           auto ceend = connected_elements.end();
           for (; ceit != ceend; ++ceit)
             element_to_subelement(fid).push_back(*ceit);
 
           for (UInt ce = 0; ce < connected_elements.size(); ++ce) {
             Element & elem = connected_elements[ce];
             Array<Element> & subelement_to_element =
                 mesh_accessor.getSubelementToElement(elem.type,
                                                      elem.ghost_type);
 
             UInt f(0);
             for (; f < mesh.getNbFacetsPerElement(elem.type) &&
                    subelement_to_element(elem.element, f) != ElementNull;
                  ++f)
               ;
 
             AKANTU_DEBUG_ASSERT(
                 f < mesh.getNbFacetsPerElement(elem.type),
                 "The element " << elem << " seems to have too many facets!! ("
                                << f << " < "
                                << mesh.getNbFacetsPerElement(elem.type) << ")");
 
             subelement_to_element(elem.element, f) = facet_element;
           }
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool third_dim_points>
 bool MeshUtils::findElementsAroundSubfacet(
     const Mesh & mesh, const Mesh & mesh_facets,
     const Element & starting_element, const Element & end_facet,
     const Vector<UInt> & subfacet_connectivity,
     std::vector<Element> & elem_list, std::vector<Element> & facet_list,
     std::vector<Element> * subfacet_list) {
   AKANTU_DEBUG_IN();
 
   /// preallocated stuff before starting
   bool facet_matched = false;
 
   elem_list.clear();
   facet_list.clear();
 
   if (third_dim_points)
     subfacet_list->clear();
 
   elem_list.push_back(starting_element);
 
   const Array<UInt> * facet_connectivity = nullptr;
   const Array<UInt> * sf_connectivity = nullptr;
   const Array<Element> * facet_to_element = nullptr;
   const Array<Element> * subfacet_to_facet = nullptr;
 
   ElementType current_type = _not_defined;
   GhostType current_ghost_type = _casper;
 
   ElementType current_facet_type = _not_defined;
   GhostType current_facet_ghost_type = _casper;
 
   ElementType current_subfacet_type = _not_defined;
   GhostType current_subfacet_ghost_type = _casper;
 
   const Array<std::vector<Element>> * element_to_facet = nullptr;
 
   const Element * opposing_el = nullptr;
 
   std::queue<Element> elements_to_check;
   elements_to_check.push(starting_element);
 
   /// keep going until there are elements to check
   while (!elements_to_check.empty()) {
 
     /// check current element
     Element & current_el = elements_to_check.front();
 
     if (current_el.type != current_type ||
         current_el.ghost_type != current_ghost_type) {
 
       current_type = current_el.type;
       current_ghost_type = current_el.ghost_type;
 
       facet_to_element =
           &mesh_facets.getSubelementToElement(current_type, current_ghost_type);
     }
 
     /// loop over each facet of the element
     for (UInt f = 0; f < facet_to_element->getNbComponent(); ++f) {
 
       const Element & current_facet =
           (*facet_to_element)(current_el.element, f);
 
       if (current_facet == ElementNull)
         continue;
 
       if (current_facet_type != current_facet.type ||
           current_facet_ghost_type != current_facet.ghost_type) {
 
         current_facet_type = current_facet.type;
         current_facet_ghost_type = current_facet.ghost_type;
 
         element_to_facet = &mesh_facets.getElementToSubelement(
             current_facet_type, current_facet_ghost_type);
         facet_connectivity = &mesh_facets.getConnectivity(
             current_facet_type, current_facet_ghost_type);
 
         if (third_dim_points)
           subfacet_to_facet = &mesh_facets.getSubelementToElement(
               current_facet_type, current_facet_ghost_type);
       }
 
       /// check if end facet is reached
       if (current_facet == end_facet)
         facet_matched = true;
 
       /// add this facet if not already passed
       if (std::find(facet_list.begin(), facet_list.end(), current_facet) ==
               facet_list.end() &&
           hasElement(*facet_connectivity, current_facet,
                      subfacet_connectivity)) {
         facet_list.push_back(current_facet);
 
         if (third_dim_points) {
           /// check subfacets
           for (UInt sf = 0; sf < subfacet_to_facet->getNbComponent(); ++sf) {
             const Element & current_subfacet =
                 (*subfacet_to_facet)(current_facet.element, sf);
 
             if (current_subfacet == ElementNull)
               continue;
 
             if (current_subfacet_type != current_subfacet.type ||
                 current_subfacet_ghost_type != current_subfacet.ghost_type) {
               current_subfacet_type = current_subfacet.type;
               current_subfacet_ghost_type = current_subfacet.ghost_type;
 
               sf_connectivity = &mesh_facets.getConnectivity(
                   current_subfacet_type, current_subfacet_ghost_type);
             }
 
             if (std::find(subfacet_list->begin(), subfacet_list->end(),
                           current_subfacet) == subfacet_list->end() &&
                 hasElement(*sf_connectivity, current_subfacet,
                            subfacet_connectivity))
               subfacet_list->push_back(current_subfacet);
           }
         }
       } else
         continue;
 
       /// consider opposing element
       if ((*element_to_facet)(current_facet.element)[0] == current_el)
         opposing_el = &(*element_to_facet)(current_facet.element)[1];
       else
         opposing_el = &(*element_to_facet)(current_facet.element)[0];
 
       /// skip null elements since they are on a boundary
       if (*opposing_el == ElementNull)
         continue;
 
       /// skip this element if already added
       if (std::find(elem_list.begin(), elem_list.end(), *opposing_el) !=
           elem_list.end())
         continue;
 
       /// only regular elements have to be checked
       if (opposing_el->kind() == _ek_regular)
         elements_to_check.push(*opposing_el);
 
       elem_list.push_back(*opposing_el);
 
 #ifndef AKANTU_NDEBUG
       const Array<UInt> & conn_elem =
           mesh.getConnectivity(opposing_el->type, opposing_el->ghost_type);
 
       AKANTU_DEBUG_ASSERT(
           hasElement(conn_elem, *opposing_el, subfacet_connectivity),
           "Subfacet doesn't belong to this element");
 #endif
     }
 
     /// erased checked element from the list
     elements_to_check.pop();
   }
 
   AKANTU_DEBUG_OUT();
   return facet_matched;
 }
 
 /* -------------------------------------------------------------------------- */
 UInt MeshUtils::updateLocalMasterGlobalConnectivity(Mesh & mesh,
                                                     UInt local_nb_new_nodes) {
   const auto & comm = mesh.getCommunicator();
   Int rank = comm.whoAmI();
   Int nb_proc = comm.getNbProc();
   if (nb_proc == 1)
     return local_nb_new_nodes;
 
   /// resize global ids array
   Array<UInt> & nodes_global_ids = mesh.getGlobalNodesIds();
   UInt old_nb_nodes = mesh.getNbNodes() - local_nb_new_nodes;
 
   nodes_global_ids.resize(mesh.getNbNodes());
 
   /// compute the number of global nodes based on the number of old nodes
   Vector<UInt> old_local_master_nodes(nb_proc);
   for (UInt n = 0; n < old_nb_nodes; ++n)
     if (mesh.isLocalOrMasterNode(n))
       ++old_local_master_nodes(rank);
   comm.allGather(old_local_master_nodes);
   UInt old_global_nodes =
       std::accumulate(old_local_master_nodes.storage(),
                       old_local_master_nodes.storage() + nb_proc, 0);
 
   /// compute amount of local or master doubled nodes
   Vector<UInt> local_master_nodes(nb_proc);
   for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n)
     if (mesh.isLocalOrMasterNode(n))
       ++local_master_nodes(rank);
 
   comm.allGather(local_master_nodes);
 
   /// update global number of nodes
   UInt total_nb_new_nodes = std::accumulate(
       local_master_nodes.storage(), local_master_nodes.storage() + nb_proc, 0);
 
   if (total_nb_new_nodes == 0)
     return 0;
 
   /// set global ids of local and master nodes
   UInt starting_index =
       std::accumulate(local_master_nodes.storage(),
                       local_master_nodes.storage() + rank, old_global_nodes);
 
   for (UInt n = old_nb_nodes; n < mesh.getNbNodes(); ++n) {
     if (mesh.isLocalOrMasterNode(n)) {
       nodes_global_ids(n) = starting_index;
       ++starting_index;
     }
   }
 
   MeshAccessor mesh_accessor(mesh);
   mesh_accessor.setNbGlobalNodes(old_global_nodes + total_nb_new_nodes);
   return total_nb_new_nodes;
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::updateElementalConnectivity(
     Mesh & mesh, UInt old_node, UInt new_node,
     const std::vector<Element> & element_list,
     __attribute__((unused)) const std::vector<Element> * facet_list) {
   AKANTU_DEBUG_IN();
 
   ElementType el_type = _not_defined;
   GhostType gt_type = _casper;
   Array<UInt> * conn_elem = nullptr;
 #if defined(AKANTU_COHESIVE_ELEMENT)
   const Array<Element> * cohesive_facets = nullptr;
 #endif
   UInt nb_nodes_per_element = 0;
   UInt * n_update = nullptr;
 
   for (UInt el = 0; el < element_list.size(); ++el) {
     const Element & elem = element_list[el];
     if (elem.type == _not_defined)
       continue;
 
     if (elem.type != el_type || elem.ghost_type != gt_type) {
       el_type = elem.type;
       gt_type = elem.ghost_type;
       conn_elem = &mesh.getConnectivity(el_type, gt_type);
       nb_nodes_per_element = conn_elem->getNbComponent();
 #if defined(AKANTU_COHESIVE_ELEMENT)
       if (elem.kind() == _ek_cohesive)
         cohesive_facets =
             &mesh.getMeshFacets().getSubelementToElement(el_type, gt_type);
 #endif
     }
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
     if (elem.kind() == _ek_cohesive) {
 
       AKANTU_DEBUG_ASSERT(
           facet_list != nullptr,
           "Provide a facet list in order to update cohesive elements");
 
       /// loop over cohesive element's facets
       for (UInt f = 0, n = 0; f < 2; ++f, n += nb_nodes_per_element / 2) {
         const Element & facet = (*cohesive_facets)(elem.element, f);
 
         /// skip facets if not present in the list
         if (std::find(facet_list->begin(), facet_list->end(), facet) ==
             facet_list->end())
           continue;
 
         n_update = std::find(
             conn_elem->storage() + elem.element * nb_nodes_per_element + n,
             conn_elem->storage() + elem.element * nb_nodes_per_element + n +
                 nb_nodes_per_element / 2,
             old_node);
 
         AKANTU_DEBUG_ASSERT(n_update !=
                                 conn_elem->storage() +
                                     elem.element * nb_nodes_per_element + n +
                                     nb_nodes_per_element / 2,
                             "Node not found in current element");
 
         /// update connectivity
         *n_update = new_node;
       }
     } else {
 #endif
       n_update =
           std::find(conn_elem->storage() + elem.element * nb_nodes_per_element,
                     conn_elem->storage() + elem.element * nb_nodes_per_element +
                         nb_nodes_per_element,
                     old_node);
 
       AKANTU_DEBUG_ASSERT(n_update != conn_elem->storage() +
                                           elem.element * nb_nodes_per_element +
                                           nb_nodes_per_element,
                           "Node not found in current element");
 
       /// update connectivity
       *n_update = new_node;
 #if defined(AKANTU_COHESIVE_ELEMENT)
     }
 #endif
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/mesh_utils_pbc.cc b/src/mesh_utils/mesh_utils_pbc.cc
index efbe22315..5e011b23d 100644
--- a/src/mesh_utils/mesh_utils_pbc.cc
+++ b/src/mesh_utils/mesh_utils_pbc.cc
@@ -1,298 +1,298 @@
 /**
  * @file   mesh_utils_pbc.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  *
  * @date creation: Wed Feb 09 2011
  * @date last modification: Tue Sep 15 2015
  *
  * @brief  periodic boundary condition connectivity tweak
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 #include "element_group.hh"
 #include "mesh_accessor.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /// class that sorts a set of nodes of same coordinates in 'dir' direction
 class CoordinatesComparison {
 public:
   CoordinatesComparison(const UInt dimension, const UInt dir_1, const UInt dir_2,
                         Real normalization, Real tolerance, const Array<Real> & coords)
     : dim(dimension), dir_1(dir_1), dir_2(dir_2), normalization(normalization),
       tolerance(tolerance), coords_it(coords.begin(dim)) {}
   // answers the question whether n2 is larger or equal to n1
   bool operator()(const UInt n1, const UInt n2) {
     Vector<Real> coords_n1 = coords_it[n1];
     Vector<Real> coords_n2 = coords_it[n2];
     return this->operator()(coords_n1, coords_n2);
   }
 
   bool operator()(const Vector<Real> & coords_n1, const Vector<Real> & coords_n2) {
     Real diff = coords_n1(dir_1) - coords_n2(dir_1);;
     if (dim == 2 || std::abs(diff) / normalization > tolerance)
       return diff > 0. ? false : true;
     else if (dim > 2) {
       diff = coords_n1(dir_2) - coords_n2(dir_2);;
       return diff > 0 ? false : true;
     }
     return true;
   }
 
 private:
   UInt dim;
   UInt dir_1;
   UInt dir_2;
   Real normalization;
   Real tolerance;
   const Array<Real>::const_vector_iterator coords_it;
 };
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::computePBCMap(const Mesh & mesh, const UInt dir,
                               std::map<UInt, UInt> & pbc_pair) {
   Array<UInt> selected_left;
   Array<UInt> selected_right;
 
   const UInt dim = mesh.getSpatialDimension();
-  Array<Real>::const_vector_iterator it = mesh.getNodes().begin(dim);
-  Array<Real>::const_vector_iterator end = mesh.getNodes().end(dim);
+  auto it = mesh.getNodes().begin(dim);
+  auto end = mesh.getNodes().end(dim);
 
   if (dim <= dir)
     return;
 
   const Vector<Real> & lower_bounds = mesh.getLowerBounds();
   const Vector<Real> & upper_bounds = mesh.getUpperBounds();
 
   AKANTU_DEBUG_INFO("min " << lower_bounds(dir));
   AKANTU_DEBUG_INFO("max " << upper_bounds(dir));
 
   for (UInt node = 0; it != end; ++it, ++node) {
     const Vector<Real> & coords = *it;
     AKANTU_DEBUG_TRACE("treating " << coords(dir));
     if (Math::are_float_equal(coords(dir), lower_bounds(dir))) {
       AKANTU_DEBUG_TRACE("pushing node " << node << " on the left side");
       selected_left.push_back(node);
     } else if (Math::are_float_equal(coords(dir), upper_bounds(dir))) {
       selected_right.push_back(node);
       AKANTU_DEBUG_TRACE("pushing node " << node << " on the right side");
     }
   }
 
   AKANTU_DEBUG_INFO(
       "found " << selected_left.size() << " and " << selected_right.size()
                << " nodes at each boundary for direction " << dir);
 
   // match pairs
   MeshUtils::matchPBCPairs(mesh, dir, selected_left, selected_right, pbc_pair);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::computePBCMap(const Mesh & mesh,
                               const std::pair<ID, ID> & surface_pair,
                               std::map<UInt, UInt> & pbc_pair) {
 
   Array<UInt> selected_first;
   Array<UInt> selected_second;
 
   // find nodes on surfaces
   const ElementGroup & first_surf = mesh.getElementGroup(surface_pair.first);
   const ElementGroup & second_surf = mesh.getElementGroup(surface_pair.second);
 
   // if this surface pair is not on this proc
   if (first_surf.getNbNodes() == 0 || second_surf.getNbNodes() == 0) {
     AKANTU_DEBUG_WARNING("computePBCMap has at least one surface without any "
                          "nodes. I will ignore it.");
     return;
   }
 
   // copy nodes from element group
   selected_first.copy(first_surf.getNodeGroup().getNodes());
   selected_second.copy(second_surf.getNodeGroup().getNodes());
 
   // coordinates
   const Array<Real> & coords = mesh.getNodes();
   const UInt dim = mesh.getSpatialDimension();
 
   // variables to find min and max of surfaces
   Real first_max[3], first_min[3];
   Real second_max[3], second_min[3];
   for (UInt i = 0; i < dim; ++i) {
     first_min[i] = std::numeric_limits<Real>::max();
     second_min[i] = std::numeric_limits<Real>::max();
     first_max[i] = -std::numeric_limits<Real>::max();
     second_max[i] = -std::numeric_limits<Real>::max();
   }
 
   // find min and max of surface nodes
-  for (Array<UInt>::scalar_iterator it = selected_first.begin();
+  for (auto it = selected_first.begin();
        it != selected_first.end(); ++it) {
     for (UInt i = 0; i < dim; ++i) {
       if (first_min[i] > coords(*it, i))
         first_min[i] = coords(*it, i);
       if (first_max[i] < coords(*it, i))
         first_max[i] = coords(*it, i);
     }
   }
-  for (Array<UInt>::scalar_iterator it = selected_second.begin();
+  for (auto it = selected_second.begin();
        it != selected_second.end(); ++it) {
     for (UInt i = 0; i < dim; ++i) {
       if (second_min[i] > coords(*it, i))
         second_min[i] = coords(*it, i);
       if (second_max[i] < coords(*it, i))
         second_max[i] = coords(*it, i);
     }
   }
 
   // find direction of pbc
   Int first_dir = -1;
 #ifndef AKANTU_NDEBUG
   Int second_dir = -2;
 #endif
   for (UInt i = 0; i < dim; ++i) {
     if (Math::are_float_equal(first_min[i], first_max[i])) {
       first_dir = i;
     }
 #ifndef AKANTU_NDEBUG
     if (Math::are_float_equal(second_min[i], second_max[i])) {
       second_dir = i;
     }
 #endif
   }
 
   AKANTU_DEBUG_ASSERT(first_dir == second_dir,
                       "Surface pair has not same direction. Surface "
                           << surface_pair.first << " dir=" << first_dir
                           << " ; Surface " << surface_pair.second
                           << " dir=" << second_dir);
   UInt dir = first_dir;
 
   // match pairs
   if (first_min[dir] < second_min[dir])
     MeshUtils::matchPBCPairs(mesh, dir, selected_first, selected_second,
                              pbc_pair);
   else
     MeshUtils::matchPBCPairs(mesh, dir, selected_second, selected_first,
                              pbc_pair);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::matchPBCPairs(const Mesh & mesh, const UInt dir,
                               Array<UInt> & selected_left,
                               Array<UInt> & selected_right,
                               std::map<UInt, UInt> & pbc_pair) {
 
   // tolerance is that large because most meshers generate points coordinates
   // with single precision only (it is the case of GMSH for instance)
   Real tolerance = 1e-7;
   const UInt dim = mesh.getSpatialDimension();
   Real normalization = mesh.getUpperBounds()(dir) - mesh.getLowerBounds()(dir);
 
   AKANTU_DEBUG_ASSERT(std::abs(normalization) > Math::getTolerance(),
                       "In matchPBCPairs: The normalization is zero. "
                           << "Did you compute the bounding box of the mesh?");
 
   auto odir_1 = UInt(-1), odir_2 = UInt(-1);
 
   if (dim == 3) {
     if (dir == _x) {
       odir_1 = _y;
       odir_2 = _z;
     } else if (dir == _y) {
       odir_1 = _x;
       odir_2 = _z;
     } else if (dir == _z) {
       odir_1 = _x;
       odir_2 = _y;
     }
   } else if (dim == 2) {
     if (dir == _x) {
       odir_1 = _y;
     } else if (dir == _y) {
       odir_1 = _x;
     }
   }
 
   CoordinatesComparison compare_nodes(dim, odir_1, odir_2, normalization,
                                       tolerance, mesh.getNodes());
 
   std::sort(selected_left.begin(), selected_left.end(), compare_nodes);
   std::sort(selected_right.begin(), selected_right.end(), compare_nodes);
 
-  Array<UInt>::scalar_iterator it_left = selected_left.begin();
-  Array<UInt>::scalar_iterator end_left = selected_left.end();
+  auto it_left = selected_left.begin();
+  auto end_left = selected_left.end();
 
-  Array<UInt>::scalar_iterator it_right = selected_right.begin();
-  Array<UInt>::scalar_iterator end_right = selected_right.end();
+  auto it_right = selected_right.begin();
+  auto end_right = selected_right.end();
 
-  Array<Real>::const_vector_iterator nit = mesh.getNodes().begin(dim);
+  auto nit = mesh.getNodes().begin(dim);
 
   while ((it_left != end_left) && (it_right != end_right)) {
     UInt i1 = *it_left;
     UInt i2 = *it_right;
 
     Vector<Real> coords1 = nit[i1];
     Vector<Real> coords2 = nit[i2];
 
     AKANTU_DEBUG_TRACE("do I pair? " << i1 << "(" << coords1 << ") with" << i2
                                      << "(" << coords2 << ") in direction "
                                      << dir);
 
     Real dx = 0.0;
     Real dy = 0.0;
     if (dim >= 2)
       dx = coords1(odir_1) - coords2(odir_1);
     if (dim == 3)
       dy = coords1(odir_2) - coords2(odir_2);
 
     if (std::abs(dx * dx + dy * dy) / normalization < tolerance) {
       // then i match these pairs
       if (pbc_pair.count(i2)) {
         i2 = pbc_pair[i2];
       }
       pbc_pair[i1] = i2;
 
       AKANTU_DEBUG_TRACE("pairing "
                          << i1 << "(" << coords1
                          << ") with" << i2 << "(" << coords2
                          << ") in direction " << dir);
       ++it_left;
       ++it_right;
     } else if (compare_nodes(coords1, coords2)) {
       ++it_left;
     } else {
       ++it_right;
     }
   }
   AKANTU_DEBUG_INFO("found " << pbc_pair.size() << " pairs for direction "
                              << dir);
 }
 
 } // akantu
diff --git a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
index 4086bae8e..e5496fd7e 100644
--- a/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
+++ b/src/model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
@@ -1,310 +1,310 @@
 /**
  * @file   neighborhood_max_criterion.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Thu Oct 15 2015
  * @date last modification: Tue Nov 24 2015
  *
  * @brief  Implementation of class NeighborhoodMaxCriterion
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "neighborhood_max_criterion.hh"
 #include "grid_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 NeighborhoodMaxCriterion::NeighborhoodMaxCriterion(
     Model & model, const ElementTypeMapReal & quad_coordinates,
     const ID & criterion_id, const ID & id, const MemoryID & memory_id)
     : NeighborhoodBase(model, quad_coordinates, id, memory_id),
       Parsable(ParserType::_non_local, id), is_highest("is_highest", id, memory_id),
       criterion(criterion_id, id, memory_id) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam("radius", neighborhood_radius, 100.,
                       _pat_parsable | _pat_readable, "Non local radius");
 
   Mesh & mesh = this->model.getMesh();
   /// allocate the element type map arrays for _not_ghosts: One entry per quad
   GhostType ghost_type = _not_ghost;
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
 
   for (; it != last_type; ++it) {
     UInt new_size = this->quad_coordinates(*it, ghost_type).size();
     this->is_highest.alloc(new_size, 1, *it, ghost_type, true);
     this->criterion.alloc(new_size, 1, *it, ghost_type, true);
   }
 
   /// criterion needs allocation also for ghost
   ghost_type = _ghost;
   it = mesh.firstType(spatial_dimension, ghost_type);
   last_type = mesh.lastType(spatial_dimension, ghost_type);
   for (; it != last_type; ++it) {
     UInt new_size = this->quad_coordinates(*it, ghost_type).size();
     this->criterion.alloc(new_size, 1, *it, ghost_type, true);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 NeighborhoodMaxCriterion::~NeighborhoodMaxCriterion() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::initNeighborhood() {
   AKANTU_DEBUG_IN();
 
   /// parse the input parameter
   const Parser & parser = getStaticParser();
   const ParserSection & section_neighborhood =
       *(parser.getSubSections(ParserType::_neighborhood).first);
   this->parseSection(section_neighborhood);
 
   AKANTU_DEBUG_INFO("Creating the grid");
   this->createGrid();
 
   /// insert the non-ghost quads into the grid
   this->insertAllQuads(_not_ghost);
 
   /// store the number of current ghost elements for each type in the mesh
   ElementTypeMap<UInt> nb_ghost_protected;
   Mesh & mesh = this->model.getMesh();
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
   for (; it != last_type; ++it)
     nb_ghost_protected(mesh.getNbElement(*it, _ghost), *it, _ghost);
 
   /// create the grid synchronizer
   this->createGridSynchronizer();
 
   /// insert the ghost quads into the grid
   this->insertAllQuads(_ghost);
 
   /// create the pair lists
   this->updatePairList();
 
   /// remove the unneccessary ghosts
   this->cleanupExtraGhostElements(nb_ghost_protected);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::createGridSynchronizer() {
   this->is_creating_grid = true;
   std::set<SynchronizationTag> tags;
   tags.insert(_gst_nh_criterion);
 
   std::stringstream sstr;
   sstr << getID() << ":grid_synchronizer";
   this->grid_synchronizer = std::make_unique<GridSynchronizer>(
       this->model.getMesh(), *spatial_grid, * this, tags, sstr.str(), 0, false);
   this->is_creating_grid = false;
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::insertAllQuads(const GhostType & ghost_type) {
   IntegrationPoint q;
   q.ghost_type = ghost_type;
   Mesh & mesh = this->model.getMesh();
 
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
   for (; it != last_type; ++it) {
     UInt nb_element = mesh.getNbElement(*it, ghost_type);
     UInt nb_quad =
         this->model.getFEEngine().getNbIntegrationPoints(*it, ghost_type);
 
     const Array<Real> & quads = this->quad_coordinates(*it, ghost_type);
     q.type = *it;
 
-    Array<Real>::const_vector_iterator quad = quads.begin(spatial_dimension);
+    auto quad = quads.begin(spatial_dimension);
 
     for (UInt e = 0; e < nb_element; ++e) {
       q.element = e;
       for (UInt nq = 0; nq < nb_quad; ++nq) {
         q.num_point = nq;
         q.global_num = q.element * nb_quad + nq;
         spatial_grid->insert(q, *quad);
         ++quad;
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::findMaxQuads(
     std::vector<IntegrationPoint> & max_quads) {
   AKANTU_DEBUG_IN();
 
   /// clear the element type maps
   this->is_highest.clear();
   this->criterion.clear();
 
   /// update the values of the criterion
   this->model.updateDataForNonLocalCriterion(criterion);
 
   /// start the exchange the value of the criterion on the ghost elements
   this->model.asynchronousSynchronize(_gst_nh_criterion);
 
   /// compare to not-ghost neighbors
   checkNeighbors(_not_ghost);
 
   /// finish the exchange
   this->model.waitEndSynchronize(_gst_nh_criterion);
 
   /// compare to ghost neighbors
   checkNeighbors(_ghost);
 
   /// extract the quads with highest criterion in their neighborhood
   IntegrationPoint quad;
   quad.ghost_type = _not_ghost;
   Mesh & mesh = this->model.getMesh();
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, _not_ghost);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _not_ghost);
   for (; it != last_type; ++it) {
     quad.type = *it;
     Array<bool>::const_scalar_iterator is_highest_it =
         is_highest(*it, _not_ghost).begin();
     Array<bool>::const_scalar_iterator is_highest_end =
         is_highest(*it, _not_ghost).end();
 
     UInt nb_quadrature_points =
         this->model.getFEEngine().getNbIntegrationPoints(*it, _not_ghost);
     UInt q = 0;
 
     /// loop over is_highest for the current element type
     for (; is_highest_it != is_highest_end; ++is_highest_it, ++q) {
       if (*is_highest_it) {
         /// gauss point has the highest stress in his neighbourhood
         quad.element = q / nb_quadrature_points;
         quad.global_num = q;
         quad.num_point = q % nb_quadrature_points;
         max_quads.push_back(quad);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::checkNeighbors(const GhostType & ghost_type2) {
   AKANTU_DEBUG_IN();
 
   PairList::const_iterator first_pair = pair_list[ghost_type2].begin();
   PairList::const_iterator last_pair = pair_list[ghost_type2].end();
 
   // Compute the weights
   for (; first_pair != last_pair; ++first_pair) {
     const IntegrationPoint & lq1 = first_pair->first;
     const IntegrationPoint & lq2 = first_pair->second;
 
     Array<bool> & has_highest_eq_stress_1 =
         is_highest(lq1.type, lq1.ghost_type);
 
     const Array<Real> & criterion_1 = this->criterion(lq1.type, lq1.ghost_type);
     const Array<Real> & criterion_2 = this->criterion(lq2.type, lq2.ghost_type);
 
     if (criterion_1(lq1.global_num) < criterion_2(lq2.global_num))
       has_highest_eq_stress_1(lq1.global_num) = false;
     else if (ghost_type2 != _ghost) {
       Array<bool> & has_highest_eq_stress_2 =
           is_highest(lq2.type, lq2.ghost_type);
       has_highest_eq_stress_2(lq2.global_num) = false;
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void NeighborhoodMaxCriterion::cleanupExtraGhostElements(
     const ElementTypeMap<UInt> & nb_ghost_protected) {
 
   Mesh & mesh = this->model.getMesh();
   /// create remove elements event
   RemovedElementsEvent remove_elem(mesh);
   /// create set of ghosts to keep
   std::set<Element> relevant_ghost_elements;
   PairList::const_iterator first_pair = pair_list[_ghost].begin();
   PairList::const_iterator last_pair = pair_list[_ghost].end();
   for (; first_pair != last_pair; ++first_pair) {
     const IntegrationPoint & q2 = first_pair->second;
     relevant_ghost_elements.insert(q2);
   }
 
   Array<Element> ghosts_to_erase(0);
   Mesh::type_iterator it = mesh.firstType(spatial_dimension, _ghost);
   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, _ghost);
 
   Element element;
   element.ghost_type = _ghost;
 
   auto end = relevant_ghost_elements.end();
   for (; it != last_type; ++it) {
     element.type = *it;
     UInt nb_ghost_elem = mesh.getNbElement(*it, _ghost);
     UInt nb_ghost_elem_protected = 0;
     try {
       nb_ghost_elem_protected = nb_ghost_protected(*it, _ghost);
     } catch (...) {
     }
 
     if (!remove_elem.getNewNumbering().exists(*it, _ghost))
       remove_elem.getNewNumbering().alloc(nb_ghost_elem, 1, *it, _ghost);
     else
       remove_elem.getNewNumbering(*it, _ghost).resize(nb_ghost_elem);
     Array<UInt> & new_numbering = remove_elem.getNewNumbering(*it, _ghost);
     for (UInt g = 0; g < nb_ghost_elem; ++g) {
       element.element = g;
       if (element.element >= nb_ghost_elem_protected &&
           relevant_ghost_elements.find(element) == end) {
         ghosts_to_erase.push_back(element);
         new_numbering(element.element) = UInt(-1);
       }
     }
     /// renumber remaining ghosts
     UInt ng = 0;
     for (UInt g = 0; g < nb_ghost_elem; ++g) {
       if (new_numbering(g) != UInt(-1)) {
         new_numbering(g) = ng;
         ++ng;
       }
     }
   }
 
   mesh.sendEvent(remove_elem);
   this->onElementsRemoved(ghosts_to_erase, remove_elem.getNewNumbering(),
                           remove_elem);
 }
 
 } // namespace akantu
diff --git a/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
index dbf7f3740..78532e1de 100644
--- a/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
+++ b/src/model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
@@ -1,280 +1,280 @@
 /**
  * @file   non_local_neighborhood_tmpl.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Sep 28 2015
  * @date last modification: Wed Nov 25 2015
  *
  * @brief  Implementation of class non-local neighborhood
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "non_local_manager.hh"
 #include "non_local_neighborhood.hh"
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL_HH__
 #define __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 template <class Func>
 inline void NonLocalNeighborhood<WeightFunction>::foreach_weight(
     const GhostType & ghost_type, Func && func) {
   auto weight_it =
       pair_weight[ghost_type]->begin(pair_weight[ghost_type]->getNbComponent());
 
   for (auto & pair : pair_list[ghost_type]) {
     std::forward<decltype(func)>(func)(pair.first, pair.second, *weight_it);
     ++weight_it;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 template <class Func>
 inline void NonLocalNeighborhood<WeightFunction>::foreach_weight(
     const GhostType & ghost_type, Func && func) const {
   auto weight_it =
       pair_weight[ghost_type]->begin(pair_weight[ghost_type]->getNbComponent());
 
   for (auto & pair : pair_list[ghost_type]) {
     std::forward<decltype(func)>(func)(pair.first, pair.second, *weight_it);
     ++weight_it;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 NonLocalNeighborhood<WeightFunction>::NonLocalNeighborhood(
     NonLocalManager & manager, const ElementTypeMapReal & quad_coordinates,
     const ID & id, const MemoryID & memory_id)
     : NonLocalNeighborhoodBase(manager.getModel(), quad_coordinates, id,
                                memory_id),
       non_local_manager(manager) {
   AKANTU_DEBUG_IN();
 
   this->weight_function = std::make_unique<WeightFunction>(manager);
 
   this->registerSubSection(ParserType::_weight_function, "weight_parameter",
                            *weight_function);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 NonLocalNeighborhood<WeightFunction>::~NonLocalNeighborhood() = default;
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 void NonLocalNeighborhood<WeightFunction>::computeWeights() {
   AKANTU_DEBUG_IN();
 
   this->weight_function->setRadius(this->neighborhood_radius);
   Vector<Real> q1_coord(this->spatial_dimension);
   Vector<Real> q2_coord(this->spatial_dimension);
 
   UInt nb_weights_per_pair = 2; /// w1: q1->q2, w2: q2->q1
 
   /// get the elementtypemap for the neighborhood volume for each quadrature
   /// point
   ElementTypeMapReal & quadrature_points_volumes =
       this->non_local_manager.getVolumes();
 
   /// update the internals of the weight function if applicable (not
   /// all the weight functions have internals and do noting in that
   /// case)
   weight_function->updateInternals();
 
   for (auto ghost_type : ghost_types) {
     /// allocate the array to store the weight, if it doesn't exist already
     if (!(pair_weight[ghost_type])) {
       pair_weight[ghost_type] =
           std::make_unique<Array<Real>>(0, nb_weights_per_pair);
     }
 
     /// resize the array to the correct size
     pair_weight[ghost_type]->resize(pair_list[ghost_type].size());
     /// set entries to zero
     pair_weight[ghost_type]->clear();
 
     /// loop over all pairs in the current pair list array and their
     /// corresponding weights
     auto first_pair = pair_list[ghost_type].begin();
     auto last_pair = pair_list[ghost_type].end();
-    Array<Real>::vector_iterator weight_it =
+    auto weight_it =
         pair_weight[ghost_type]->begin(nb_weights_per_pair);
 
     // Compute the weights
     for (; first_pair != last_pair; ++first_pair, ++weight_it) {
       Vector<Real> & weight = *weight_it;
       const IntegrationPoint & q1 = first_pair->first;
       const IntegrationPoint & q2 = first_pair->second;
 
       /// get the coordinates for the given pair of quads
-      Array<Real>::const_vector_iterator coords_type_1_it =
+      auto coords_type_1_it =
           this->quad_coordinates(q1.type, q1.ghost_type)
               .begin(this->spatial_dimension);
       q1_coord = coords_type_1_it[q1.global_num];
-      Array<Real>::const_vector_iterator coords_type_2_it =
+      auto coords_type_2_it =
           this->quad_coordinates(q2.type, q2.ghost_type)
               .begin(this->spatial_dimension);
       q2_coord = coords_type_2_it[q2.global_num];
 
       Array<Real> & quad_volumes_1 =
           quadrature_points_volumes(q1.type, q1.ghost_type);
       const Array<Real> & jacobians_2 =
           this->non_local_manager.getJacobians(q2.type, q2.ghost_type);
       const Real & q2_wJ = jacobians_2(q2.global_num);
 
       /// compute distance between the two quadrature points
       Real r = q1_coord.distance(q2_coord);
 
       /// compute the weight for averaging on q1 based on the distance
       Real w1 = this->weight_function->operator()(r, q1, q2);
       weight(0) = q2_wJ * w1;
 
       quad_volumes_1(q1.global_num) += weight(0);
 
       if (q2.ghost_type != _ghost && q1.global_num != q2.global_num) {
         const Array<Real> & jacobians_1 =
             this->non_local_manager.getJacobians(q1.type, q1.ghost_type);
         Array<Real> & quad_volumes_2 =
             quadrature_points_volumes(q2.type, q2.ghost_type);
         /// compute the weight for averaging on q2
         const Real & q1_wJ = jacobians_1(q1.global_num);
         Real w2 = this->weight_function->operator()(r, q2, q1);
         weight(1) = q1_wJ * w2;
         quad_volumes_2(q2.global_num) += weight(1);
       } else
         weight(1) = 0.;
     }
   }
 
   ///  normalize the weights
   for (auto ghost_type : ghost_types) {
     foreach_weight(ghost_type, [&](
                                    const auto & q1, const auto & q2,
                                    auto & weight) {
       auto & quad_volumes_1 = quadrature_points_volumes(q1.type, q1.ghost_type);
       auto & quad_volumes_2 = quadrature_points_volumes(q2.type, q2.ghost_type);
 
       Real q1_volume = quad_volumes_1(q1.global_num);
       auto ghost_type2 = q2.ghost_type;
       weight(0) *= 1. / q1_volume;
       if (ghost_type2 != _ghost) {
         Real q2_volume = quad_volumes_2(q2.global_num);
         weight(1) *= 1. / q2_volume;
       }
     });
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 void NonLocalNeighborhood<WeightFunction>::saveWeights(
     const std::string & filename) const {
   std::ofstream pout;
 
   std::stringstream sstr;
 
   const Communicator & comm = model.getMesh().getCommunicator();
 
   Int prank = comm.whoAmI();
   sstr << filename << "." << prank;
 
   pout.open(sstr.str().c_str());
 
   for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
     auto ghost_type = (GhostType)gt;
 
     AKANTU_DEBUG_ASSERT((pair_weight[ghost_type]),
                         "the weights have not been computed yet");
 
     Array<Real> & weights = *(pair_weight[ghost_type]);
-    Array<Real>::const_vector_iterator weights_it = weights.begin(2);
+    auto weights_it = weights.begin(2);
     for (UInt i = 0; i < weights.size(); ++i, ++weights_it)
       pout << "w1: " << (*weights_it)(0) << " w2: " << (*weights_it)(1)
            << std::endl;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 void NonLocalNeighborhood<WeightFunction>::weightedAverageOnNeighbours(
     const ElementTypeMapReal & to_accumulate, ElementTypeMapReal & accumulated,
     UInt nb_degree_of_freedom, const GhostType & ghost_type2) const {
 
   auto it = non_local_variables.find(accumulated.getName());
   // do averaging only for variables registered in the neighborhood
   if (it == non_local_variables.end())
     return;
 
   foreach_weight(
       ghost_type2,
       [ghost_type2, nb_degree_of_freedom, &to_accumulate,
        &accumulated](const auto & q1, const auto & q2, auto & weight) {
         const Vector<Real> to_acc_1 =
             to_accumulate(q1.type, q1.ghost_type)
                 .begin(nb_degree_of_freedom)[q1.global_num];
         const Vector<Real> to_acc_2 =
             to_accumulate(q2.type, q2.ghost_type)
                 .begin(nb_degree_of_freedom)[q2.global_num];
         Vector<Real> acc_1 = accumulated(q1.type, q1.ghost_type)
                                  .begin(nb_degree_of_freedom)[q1.global_num];
         Vector<Real> acc_2 = accumulated(q2.type, q2.ghost_type)
                                  .begin(nb_degree_of_freedom)[q2.global_num];
 
         acc_1 += weight(0) * to_acc_2;
 
         if (ghost_type2 != _ghost) {
           acc_2 += weight(1) * to_acc_1;
         }
       });
 }
 
 /* -------------------------------------------------------------------------- */
 template <class WeightFunction>
 void NonLocalNeighborhood<WeightFunction>::updateWeights() {
   // Update the weights for the non local variable averaging
   if (this->weight_function->getUpdateRate() &&
       (this->non_local_manager.getNbStressCalls() %
            this->weight_function->getUpdateRate() ==
        0)) {
     SynchronizerRegistry::synchronize(_gst_mnl_weight);
     this->computeWeights();
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_NON_LOCAL_NEIGHBORHOOD_TMPL__ */
diff --git a/src/model/model.cc b/src/model/model.cc
index 7b0e963dd..684e072c8 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -1,370 +1,370 @@
 /**
  * @file   model.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Oct 03 2011
  * @date last modification: Thu Nov 19 2015
  *
  * @brief  implementation of model common parts
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "model.hh"
 #include "communicator.hh"
 #include "data_accessor.hh"
 #include "element_group.hh"
 #include "element_synchronizer.hh"
 #include "synchronizer_registry.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 Model::Model(Mesh & mesh, const ModelType & type, UInt dim, const ID & id,
              const MemoryID & memory_id)
     : Memory(id, memory_id), ModelSolver(mesh, type, id, memory_id), mesh(mesh),
       spatial_dimension(dim == _all_dimensions ? mesh.getSpatialDimension()
                                                : dim),
       is_pbc_slave_node(0, 1, "is_pbc_slave_node"), parser(getStaticParser()) {
   AKANTU_DEBUG_IN();
 
   this->mesh.registerEventHandler(*this, _ehp_model);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Model::~Model() = default;
 
 /* -------------------------------------------------------------------------- */
 // void Model::setParser(Parser & parser) { this->parser = &parser; }
 
 /* -------------------------------------------------------------------------- */
 void Model::initFullImpl(const ModelOptions & options) {
   AKANTU_DEBUG_IN();
 
   method = options.analysis_method;
   if (!this->hasDefaultSolver()) {
     this->initNewSolver(this->method);
   }
   initModel();
 
   initFEEngineBoundary();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::initNewSolver(const AnalysisMethod & method) {
   ID solver_name;
   TimeStepSolverType tss_type;
   std::tie(solver_name, tss_type) = this->getDefaultSolverID(method);
 
   if (not this->hasSolver(solver_name)) {
     ModelSolverOptions options = this->getDefaultSolverOptions(tss_type);
     this->getNewSolver(solver_name, tss_type, options.non_linear_solver_type);
 
     for (auto && is_type : options.integration_scheme_type) {
       if (!this->hasIntegrationScheme(solver_name, is_type.first)) {
         this->setIntegrationScheme(solver_name, is_type.first, is_type.second,
                                    options.solution_type[is_type.first]);
       }
     }
   }
 
   this->method = method;
   this->setDefaultSolver(solver_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::initPBC() {
   auto it = pbc_pair.begin();
   auto end = pbc_pair.end();
 
   is_pbc_slave_node.resize(mesh.getNbNodes());
 #ifndef AKANTU_NDEBUG
-  Array<Real>::const_vector_iterator coord_it =
+  auto coord_it =
       mesh.getNodes().begin(this->spatial_dimension);
 #endif
 
   while (it != end) {
     UInt i1 = (*it).first;
 
     is_pbc_slave_node(i1) = true;
 
 #ifndef AKANTU_NDEBUG
     UInt i2 = (*it).second;
     UInt slave = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i1) : i1;
     UInt master = mesh.isDistributed() ? mesh.getGlobalNodesIds()(i2) : i2;
 
     AKANTU_DEBUG_INFO("pairing " << slave << " (" << Vector<Real>(coord_it[i1])
                                  << ") with " << master << " ("
                                  << Vector<Real>(coord_it[i2]) << ")");
 #endif
     ++it;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::initFEEngineBoundary() {
   FEEngine & fem_boundary = getFEEngineBoundary();
   fem_boundary.initShapeFunctions(_not_ghost);
   fem_boundary.initShapeFunctions(_ghost);
 
   fem_boundary.computeNormalsOnIntegrationPoints(_not_ghost);
   fem_boundary.computeNormalsOnIntegrationPoints(_ghost);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::dumpGroup(const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.dump();
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::dumpGroup(const std::string & group_name,
                       const std::string & dumper_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.dump(dumper_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::dumpGroup() {
   auto bit = mesh.element_group_begin();
   auto bend = mesh.element_group_end();
   for (; bit != bend; ++bit) {
     bit->second->dump();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::setGroupDirectory(const std::string & directory) {
   auto bit = mesh.element_group_begin();
   auto bend = mesh.element_group_end();
   for (; bit != bend; ++bit) {
     bit->second->setDirectory(directory);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::setGroupDirectory(const std::string & directory,
                               const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.setDirectory(directory);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::setGroupBaseName(const std::string & basename,
                              const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.setBaseName(basename);
 }
 
 /* -------------------------------------------------------------------------- */
 DumperIOHelper & Model::getGroupDumper(const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   return group.getDumper();
 }
 
 /* -------------------------------------------------------------------------- */
 // DUMPER stuff
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldToDumper(const std::string & field_id,
                                       dumper::Field * field,
                                       DumperIOHelper & dumper) {
 #ifdef AKANTU_USE_IOHELPER
   dumper.registerField(field_id, field);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpField(const std::string & field_id) {
 
   this->addDumpFieldToDumper(mesh.getDefaultDumperName(), field_id);
 }
 /* -------------------------------------------------------------------------- */
 
 void Model::addDumpFieldVector(const std::string & field_id) {
 
   this->addDumpFieldVectorToDumper(mesh.getDefaultDumperName(), field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpFieldTensor(const std::string & field_id) {
 
   this->addDumpFieldTensorToDumper(mesh.getDefaultDumperName(), field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::setBaseName(const std::string & field_id) {
 
   mesh.setBaseName(field_id);
 }
 /* -------------------------------------------------------------------------- */
 
 void Model::setBaseNameToDumper(const std::string & dumper_name,
                                 const std::string & basename) {
   mesh.setBaseNameToDumper(dumper_name, basename);
 }
 /* -------------------------------------------------------------------------- */
 
 void Model::addDumpFieldToDumper(const std::string & dumper_name,
                                  const std::string & field_id) {
 
   this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular,
                                   false);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupField(const std::string & field_id,
                               const std::string & group_name) {
 
   ElementGroup & group = mesh.getElementGroup(group_name);
   this->addDumpGroupFieldToDumper(group.getDefaultDumperName(), field_id,
                                   group_name, _ek_regular, false);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::removeDumpGroupField(const std::string & field_id,
                                  const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   this->removeDumpGroupFieldFromDumper(group.getDefaultDumperName(), field_id,
                                        group_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::removeDumpGroupFieldFromDumper(const std::string & dumper_name,
                                            const std::string & field_id,
                                            const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   group.removeDumpFieldFromDumper(dumper_name, field_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpFieldVectorToDumper(const std::string & dumper_name,
                                        const std::string & field_id) {
   this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular,
                                   true);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldVector(const std::string & field_id,
                                     const std::string & group_name) {
   ElementGroup & group = mesh.getElementGroup(group_name);
   this->addDumpGroupFieldVectorToDumper(group.getDefaultDumperName(), field_id,
                                         group_name);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldVectorToDumper(const std::string & dumper_name,
                                             const std::string & field_id,
                                             const std::string & group_name) {
   this->addDumpGroupFieldToDumper(dumper_name, field_id, group_name,
                                   _ek_regular, true);
 }
 /* -------------------------------------------------------------------------- */
 
 void Model::addDumpFieldTensorToDumper(const std::string & dumper_name,
                                        const std::string & field_id) {
   this->addDumpGroupFieldToDumper(dumper_name, field_id, "all", _ek_regular,
                                   true);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
                                       const std::string & field_id,
                                       const std::string & group_name,
                                       const ElementKind & element_kind,
                                       bool padding_flag) {
   this->addDumpGroupFieldToDumper(dumper_name, field_id, group_name,
                                   this->spatial_dimension, element_kind,
                                   padding_flag);
 }
 
 /* -------------------------------------------------------------------------- */
 void Model::addDumpGroupFieldToDumper(const std::string & dumper_name,
                                       const std::string & field_id,
                                       const std::string & group_name,
                                       UInt spatial_dimension,
                                       const ElementKind & element_kind,
                                       bool padding_flag) {
 
 #ifdef AKANTU_USE_IOHELPER
   dumper::Field * field = nullptr;
 
   if (!field)
     field = this->createNodalFieldReal(field_id, group_name, padding_flag);
   if (!field)
     field = this->createNodalFieldUInt(field_id, group_name, padding_flag);
   if (!field)
     field = this->createNodalFieldBool(field_id, group_name, padding_flag);
   if (!field)
     field = this->createElementalField(field_id, group_name, padding_flag,
                                        spatial_dimension, element_kind);
   if (!field)
     field = this->mesh.createFieldFromAttachedData<UInt>(field_id, group_name,
                                                          element_kind);
   if (!field)
     field = this->mesh.createFieldFromAttachedData<Real>(field_id, group_name,
                                                          element_kind);
 
 #ifndef AKANTU_NDEBUG
   if (!field) {
     AKANTU_DEBUG_WARNING("No field could be found based on name: " << field_id);
   }
 #endif
   if (field) {
     DumperIOHelper & dumper = mesh.getGroupDumper(dumper_name, group_name);
     this->addDumpGroupFieldToDumper(field_id, field, dumper);
   }
 
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::dump() { mesh.dump(); }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::setDirectory(const std::string & directory) {
   mesh.setDirectory(directory);
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::setDirectoryToDumper(const std::string & dumper_name,
                                  const std::string & directory) {
   mesh.setDirectoryToDumper(dumper_name, directory);
 }
 
 /* -------------------------------------------------------------------------- */
 
 void Model::setTextModeToDumper() { mesh.setTextModeToDumper(); }
 
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/material_inline_impl.cc b/src/model/solid_mechanics/material_inline_impl.cc
index 494cda3d8..303d71707 100644
--- a/src/model/solid_mechanics/material_inline_impl.cc
+++ b/src/model/solid_mechanics/material_inline_impl.cc
@@ -1,475 +1,475 @@
 /**
  * @file   material_inline_impl.cc
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Jul 27 2010
  * @date last modification: Wed Nov 25 2015
  *
  * @brief  Implementation of the inline functions of the class material
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_INLINE_IMPL_CC__
 #define __AKANTU_MATERIAL_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::addElement(const ElementType & type, UInt element,
                                  const GhostType & ghost_type) {
   Array<UInt> & el_filter = this->element_filter(type, ghost_type);
   el_filter.push_back(element);
   return el_filter.size() - 1;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::addElement(const Element & element) {
   return this->addElement(element.type, element.element, element.ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::getTangentStiffnessVoigtSize(UInt dim) const {
   return (dim * (dim - 1) / 2 + dim);
 }
 /* -------------------------------------------------------------------------- */
 inline UInt Material::getCauchyStressMatrixSize(UInt dim) const {
   return (dim * dim);
 }
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::gradUToF(const Matrix<Real> & grad_u, Matrix<Real> & F) {
   AKANTU_DEBUG_ASSERT(F.size() >= grad_u.size() && grad_u.size() == dim * dim,
                       "The dimension of the tensor F should be greater or "
                       "equal to the dimension of the tensor grad_u.");
 
   F.eye();
 
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       F(i, j) += grad_u(i, j);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::computeCauchyStressOnQuad(const Matrix<Real> & F,
                                                 const Matrix<Real> & piola,
                                                 Matrix<Real> & sigma,
                                                 const Real & C33) const {
 
   Real J = F.det() * sqrt(C33);
 
   Matrix<Real> F_S(dim, dim);
   F_S.mul<false, false>(F, piola);
   Real constant = J ? 1. / J : 0;
   sigma.mul<false, true>(F_S, F, constant);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::rightCauchy(const Matrix<Real> & F, Matrix<Real> & C) {
   C.mul<true, false>(F, F);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::leftCauchy(const Matrix<Real> & F, Matrix<Real> & B) {
   B.mul<false, true>(F, F);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::gradUToEpsilon(const Matrix<Real> & grad_u,
                                      Matrix<Real> & epsilon) {
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       epsilon(i, j) = 0.5 * (grad_u(i, j) + grad_u(j, i));
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::gradUToGreenStrain(const Matrix<Real> & grad_u,
                                          Matrix<Real> & epsilon) {
   epsilon.mul<true, false>(grad_u, grad_u, .5);
 
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       epsilon(i, j) += 0.5 * (grad_u(i, j) + grad_u(j, i));
 }
 
 /* -------------------------------------------------------------------------- */
 inline Real Material::stressToVonMises(const Matrix<Real> & stress) {
   // compute deviatoric stress
   UInt dim = stress.cols();
   Matrix<Real> deviatoric_stress =
       Matrix<Real>::eye(dim, -1. * stress.trace() / 3.);
 
   for (UInt i = 0; i < dim; ++i)
     for (UInt j = 0; j < dim; ++j)
       deviatoric_stress(i, j) += stress(i, j);
 
   // return Von Mises stress
   return std::sqrt(3. * deviatoric_stress.doubleDot(deviatoric_stress) / 2.);
 }
 
 /* ---------------------------------------------------------------------------*/
 template <UInt dim>
 inline void Material::setCauchyStressArray(const Matrix<Real> & S_t,
                                            Matrix<Real> & sigma_voight) {
   AKANTU_DEBUG_IN();
   sigma_voight.clear();
   // see Finite element formulations for large deformation dynamic analysis,
   // Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau
 
   /*
    * 1d: [ s11 ]'
    * 2d: [ s11 s22 s12 ]'
    * 3d: [ s11 s22 s33 s23 s13 s12 ]
    */
   for (UInt i = 0; i < dim; ++i) // diagonal terms
     sigma_voight(i, 0) = S_t(i, i);
 
   for (UInt i = 1; i < dim; ++i) // term s12 in 2D and terms s23 s13 in 3D
     sigma_voight(dim + i - 1, 0) = S_t(dim - i - 1, dim - 1);
 
   for (UInt i = 2; i < dim; ++i) // term s13 in 3D
     sigma_voight(dim + i, 0) = S_t(0, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt dim>
 inline void Material::setCauchyStressMatrix(const Matrix<Real> & S_t,
                                             Matrix<Real> & sigma) {
   AKANTU_DEBUG_IN();
 
   sigma.clear();
 
   /// see Finite ekement formulations for large deformation dynamic analysis,
   /// Bathe et al. IJNME vol 9, 1975, page 364 ^t\tau
   for (UInt i = 0; i < dim; ++i) {
     for (UInt m = 0; m < dim; ++m) {
       for (UInt n = 0; n < dim; ++n) {
         sigma(i * dim + m, i * dim + n) = S_t(m, n);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline Element
 Material::convertToLocalElement(const Element & global_element) const {
   UInt ge = global_element.element;
 #ifndef AKANTU_NDEBUG
   UInt model_mat_index = this->model.getMaterialByElement(
       global_element.type, global_element.ghost_type)(ge);
 
   UInt mat_index = this->model.getMaterialIndex(this->name);
   AKANTU_DEBUG_ASSERT(model_mat_index == mat_index,
                       "Conversion of a global  element in a local element for "
                       "the wrong material "
                           << this->name << std::endl);
 #endif
   UInt le = this->model.getMaterialLocalNumbering(
       global_element.type, global_element.ghost_type)(ge);
 
   Element tmp_quad{global_element.type, le, global_element.ghost_type};
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Element
 Material::convertToGlobalElement(const Element & local_element) const {
   UInt le = local_element.element;
   UInt ge =
       this->element_filter(local_element.type, local_element.ghost_type)(le);
 
   Element tmp_quad{local_element.type, ge, local_element.ghost_type};
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline IntegrationPoint
 Material::convertToLocalPoint(const IntegrationPoint & global_point) const {
   const FEEngine & fem = this->model.getFEEngine();
   UInt nb_quad = fem.getNbIntegrationPoints(global_point.type);
   Element el =
       this->convertToLocalElement(static_cast<const Element &>(global_point));
   IntegrationPoint tmp_quad(el, global_point.num_point, nb_quad);
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline IntegrationPoint
 Material::convertToGlobalPoint(const IntegrationPoint & local_point) const {
   const FEEngine & fem = this->model.getFEEngine();
   UInt nb_quad = fem.getNbIntegrationPoints(local_point.type);
   Element el =
       this->convertToGlobalElement(static_cast<const Element &>(local_point));
   IntegrationPoint tmp_quad(el, local_point.num_point, nb_quad);
   return tmp_quad;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Material::getNbData(const Array<Element> & elements,
                                 const SynchronizationTag & tag) const {
   if (tag == _gst_smm_stress) {
     return (this->isFiniteDeformation() ? 3 : 1) * spatial_dimension *
            spatial_dimension * sizeof(Real) *
            this->getModel().getNbIntegrationPoints(elements);
   }
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::packData(CommunicationBuffer & buffer,
                                const Array<Element> & elements,
                                const SynchronizationTag & tag) const {
   if (tag == _gst_smm_stress) {
     if (this->isFiniteDeformation()) {
       packElementDataHelper(piola_kirchhoff_2, buffer, elements);
       packElementDataHelper(gradu, buffer, elements);
     }
     packElementDataHelper(stress, buffer, elements);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Material::unpackData(CommunicationBuffer & buffer,
                                  const Array<Element> & elements,
                                  const SynchronizationTag & tag) {
   if (tag == _gst_smm_stress) {
     if (this->isFiniteDeformation()) {
       unpackElementDataHelper(piola_kirchhoff_2, buffer, elements);
       unpackElementDataHelper(gradu, buffer, elements);
     }
     unpackElementDataHelper(stress, buffer, elements);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Parameter & Material::getParam(const ID & param) const {
   try {
     return get(param);
   } catch (...) {
     AKANTU_EXCEPTION("No parameter " << param << " in the material "
                                      << getID());
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::setParam(const ID & param, T value) {
   try {
     set<T>(param, value);
   } catch (...) {
     AKANTU_EXCEPTION("No parameter " << param << " in the material "
                                      << getID());
   }
   updateInternalParameters();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::setParamNoUpdate(const ID & param, T value) {
   try {
     set<T>(param, value);
   } catch (...) {
     AKANTU_EXCEPTION("No parameter " << param << " in the material "
                      << getID());
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::packElementDataHelper(
     const ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
     const Array<Element> & elements, const ID & fem_id) const {
   DataAccessor::packElementalDataHelper<T>(data_to_pack, buffer, elements, true,
                                            model.getFEEngine(fem_id));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Material::unpackElementDataHelper(
     ElementTypeMapArray<T> & data_to_unpack, CommunicationBuffer & buffer,
     const Array<Element> & elements, const ID & fem_id) {
   DataAccessor::unpackElementalDataHelper<T>(data_to_unpack, buffer, elements,
                                              true, model.getFEEngine(fem_id));
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Material::registerInternal<Real>(InternalField<Real> & vect) {
   internal_vectors_real[vect.getID()] = &vect;
 }
 
 template <>
 inline void Material::registerInternal<UInt>(InternalField<UInt> & vect) {
   internal_vectors_uint[vect.getID()] = &vect;
 }
 
 template <>
 inline void Material::registerInternal<bool>(InternalField<bool> & vect) {
   internal_vectors_bool[vect.getID()] = &vect;
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Material::unregisterInternal<Real>(InternalField<Real> & vect) {
   internal_vectors_real.erase(vect.getID());
 }
 
 template <>
 inline void Material::unregisterInternal<UInt>(InternalField<UInt> & vect) {
   internal_vectors_uint.erase(vect.getID());
 }
 
 template <>
 inline void Material::unregisterInternal<bool>(InternalField<bool> & vect) {
   internal_vectors_bool.erase(vect.getID());
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline bool Material::isInternal(__attribute__((unused)) const ID & id,
                                  __attribute__((unused))
                                  const ElementKind & element_kind) const {
   AKANTU_TO_IMPLEMENT();
 }
 
 template <>
 inline bool Material::isInternal<Real>(const ID & id,
                                        const ElementKind & element_kind) const {
   auto internal_array = internal_vectors_real.find(this->getID() + ":" + id);
 
   if (internal_array == internal_vectors_real.end() ||
       internal_array->second->getElementKind() != element_kind)
     return false;
   return true;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline ElementTypeMap<UInt>
 Material::getInternalDataPerElem(const ID & field_id,
                                  const ElementKind & element_kind) const {
 
   if (!this->template isInternal<T>(field_id, element_kind))
     AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
                                                    << this->name);
 
   const InternalField<T> & internal_field =
       this->template getInternal<T>(field_id);
   const FEEngine & fe_engine = internal_field.getFEEngine();
   UInt nb_data_per_quad = internal_field.getNbComponent();
 
   ElementTypeMap<UInt> res;
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     using type_iterator = typename InternalField<T>::type_iterator;
     type_iterator tit = internal_field.firstType(*gt);
     type_iterator tend = internal_field.lastType(*gt);
 
     for (; tit != tend; ++tit) {
       UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(*tit, *gt);
       res(*tit, *gt) = nb_data_per_quad * nb_quadrature_points;
     }
   }
   return res;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void Material::flattenInternal(const std::string & field_id,
                                ElementTypeMapArray<T> & internal_flat,
                                const GhostType ghost_type,
                                ElementKind element_kind) const {
 
   if (!this->template isInternal<T>(field_id, element_kind))
     AKANTU_EXCEPTION("Cannot find internal field " << id << " in material "
                                                    << this->name);
 
   const InternalField<T> & internal_field =
       this->template getInternal<T>(field_id);
 
   const FEEngine & fe_engine = internal_field.getFEEngine();
   const Mesh & mesh = fe_engine.getMesh();
 
   using type_iterator = typename InternalField<T>::filter_type_iterator;
   type_iterator tit = internal_field.filterFirstType(ghost_type);
   type_iterator tend = internal_field.filterLastType(ghost_type);
 
   for (; tit != tend; ++tit) {
     ElementType type = *tit;
 
     const Array<Real> & src_vect = internal_field(type, ghost_type);
     const Array<UInt> & filter = internal_field.getFilter(type, ghost_type);
 
     // total number of elements in the corresponding mesh
     UInt nb_element_dst = mesh.getNbElement(type, ghost_type);
     // number of element in the internal field
     UInt nb_element_src = filter.size();
     // number of quadrature points per elem
     UInt nb_quad_per_elem = fe_engine.getNbIntegrationPoints(type);
     // number of data per quadrature point
     UInt nb_data_per_quad = internal_field.getNbComponent();
 
     if (!internal_flat.exists(type, ghost_type)) {
       internal_flat.alloc(nb_element_dst * nb_quad_per_elem, nb_data_per_quad,
                           type, ghost_type);
     }
 
     if (nb_element_src == 0)
       continue;
 
     // number of data per element
     UInt nb_data = nb_quad_per_elem * nb_data_per_quad;
 
     Array<Real> & dst_vect = internal_flat(type, ghost_type);
     dst_vect.resize(nb_element_dst * nb_quad_per_elem);
 
     Array<UInt>::const_scalar_iterator it = filter.begin();
     Array<UInt>::const_scalar_iterator end = filter.end();
 
-    Array<Real>::const_vector_iterator it_src =
+    auto it_src =
         src_vect.begin_reinterpret(nb_data, nb_element_src);
-    Array<Real>::vector_iterator it_dst =
+    auto it_dst =
         dst_vect.begin_reinterpret(nb_data, nb_element_dst);
 
     for (; it != end; ++it, ++it_src) {
       it_dst[*it] = *it_src;
     }
   }
 }
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_INLINE_IMPL_CC__ */
diff --git a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh
index 09caa4037..242d2f561 100644
--- a/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh
+++ b/src/model/solid_mechanics/materials/material_embedded/material_reinforcement_tmpl.hh
@@ -1,818 +1,818 @@
 /**
  * @file   material_reinforcement_tmpl.hh
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Thu Feb 1 2018
  *
  * @brief  Reinforcement material
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include "aka_common.hh"
 #include "aka_voigthelper.hh"
 #include "material_reinforcement.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 MaterialReinforcement<Mat, dim>::MaterialReinforcement(
     EmbeddedInterfaceModel & model, const ID & id)
     : Mat(model, 1,
           model.getInterfaceMesh(),
           model.getFEEngine("EmbeddedInterfaceFEEngine"), id),
       emodel(model),
       gradu_embedded("gradu_embedded", *this, 1,
                      model.getFEEngine("EmbeddedInterfaceFEEngine"),
                      this->element_filter),
       directing_cosines("directing_cosines", *this, 1,
                         model.getFEEngine("EmbeddedInterfaceFEEngine"),
                         this->element_filter),
       pre_stress("pre_stress", *this, 1,
                  model.getFEEngine("EmbeddedInterfaceFEEngine"),
                  this->element_filter),
       area(1.0), shape_derivatives() {
   AKANTU_DEBUG_IN();
   this->initialize();
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initialize() {
   AKANTU_DEBUG_IN();
 
   this->registerParam("area", area, _pat_parsable | _pat_modifiable,
                       "Reinforcement cross-sectional area");
   this->registerParam("pre_stress", pre_stress, _pat_parsable | _pat_modifiable,
                       "Uniform pre-stress");
 
   // this->unregisterInternal(this->stress);
 
   // Fool the AvgHomogenizingFunctor
   // stress.initialize(dim * dim);
 
   // Reallocate the element filter
   this->element_filter.initialize(this->emodel.getInterfaceMesh(),
                                   _spatial_dimension = 1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 MaterialReinforcement<Mat, dim>::~MaterialReinforcement() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initMaterial() {
   Mat::initMaterial();
 
   gradu_embedded.initialize(dim * dim);
   pre_stress.initialize(1);
 
   /// We initialise the stuff that is not going to change during the simulation
   this->initFilters();
   this->allocBackgroundShapeDerivatives();
   this->initBackgroundShapeDerivatives();
   this->initDirectingCosines();
 }
 
 /* -------------------------------------------------------------------------- */
 
 namespace detail {
   class FilterInitializer : public MeshElementTypeMapArrayInializer {
   public:
     FilterInitializer(EmbeddedInterfaceModel & emodel,
                       const GhostType & ghost_type)
         : MeshElementTypeMapArrayInializer(emodel.getMesh(),
                                            1, emodel.getSpatialDimension(),
                                            ghost_type, _ek_regular) {}
 
     UInt size(const ElementType & /*bgtype*/) const override { return 0; }
   };
 }
 
 /* -------------------------------------------------------------------------- */
 /// Initialize the filter for background elements
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initFilters() {
   for (auto gt : ghost_types) {
     for (auto && type : emodel.getInterfaceMesh().elementTypes(1, gt)) {
       std::string shaped_id = "filter";
       if (gt == _ghost)
         shaped_id += ":ghost";
 
       auto & background =
           background_filter(std::make_unique<ElementTypeMapArray<UInt>>(
                                 "bg_" + shaped_id, this->name),
                             type, gt);
       auto & foreground = foreground_filter(
           std::make_unique<ElementTypeMapArray<UInt>>(shaped_id, this->name),
           type, gt);
       foreground->initialize(detail::FilterInitializer(emodel, gt), 0, true);
       background->initialize(detail::FilterInitializer(emodel, gt), 0, true);
 
       // Computing filters
       for (auto && bg_type : background->elementTypes(dim, gt)) {
         filterInterfaceBackgroundElements(
             (*foreground)(bg_type), (*background)(bg_type), bg_type, type, gt);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /// Construct a filter for a (interface_type, background_type) pair
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::filterInterfaceBackgroundElements(
     Array<UInt> & foreground, Array<UInt> & background,
     const ElementType & type, const ElementType & interface_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   foreground.resize(0);
   background.resize(0);
 
   Array<Element> & elements =
       emodel.getInterfaceAssociatedElements(interface_type, ghost_type);
   Array<UInt> & elem_filter = this->element_filter(interface_type, ghost_type);
 
   for (auto & elem_id : elem_filter) {
     Element & elem = elements(elem_id);
     if (elem.type == type) {
       background.push_back(elem.element);
       foreground.push_back(elem_id);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 namespace detail {
   class BackgroundShapeDInitializer : public ElementTypeMapArrayInializer {
   public:
     BackgroundShapeDInitializer(UInt spatial_dimension,
 				FEEngine & engine,
 				const ElementType & foreground_type,
                                 ElementTypeMapArray<UInt> & filter,
                                 const GhostType & ghost_type)
         : ElementTypeMapArrayInializer(spatial_dimension, 0, ghost_type,
                                        _ek_regular) {
       auto nb_quad = engine.getNbIntegrationPoints(foreground_type);
       // Counting how many background elements are affected by elements of
       // interface_type
       for (auto type : filter.elementTypes(this->spatial_dimension)) {
         // Inserting size
         array_size_per_bg_type(filter(type).size() * nb_quad, type,
                                this->ghost_type);
       }
     }
 
     auto elementTypes() const -> decltype(auto) {
       return array_size_per_bg_type.elementTypes();
     }
 
     UInt size(const ElementType & bgtype) const {
       return array_size_per_bg_type(bgtype, this->ghost_type);
     }
 
     UInt nbComponent(const ElementType & bgtype) const {
       return ShapeFunctions::getShapeDerivativesSize(bgtype);
     }
 
   protected:
     ElementTypeMap<UInt> array_size_per_bg_type;
   };
 }
 
 /**
  * Background shape derivatives need to be stored per background element
  * types but also per embedded element type, which is why they are stored
  * in an ElementTypeMap<ElementTypeMapArray<Real> *>. The outer ElementTypeMap
  * refers to the embedded types, and the inner refers to the background types.
  */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::allocBackgroundShapeDerivatives() {
   AKANTU_DEBUG_IN();
 
   for (auto gt : ghost_types) {
     for (auto && type : emodel.getInterfaceMesh().elementTypes(1, gt)) {
       std::string shaped_id = "embedded_shape_derivatives";
       if (gt == _ghost)
         shaped_id += ":ghost";
 
       auto & shaped_etma = shape_derivatives(
           std::make_unique<ElementTypeMapArray<Real>>(shaped_id, this->name),
           type, gt);
       shaped_etma->initialize(
           detail::BackgroundShapeDInitializer(
               emodel.getSpatialDimension(),
               emodel.getFEEngine("EmbeddedInterfaceFEEngine"), type,
               *background_filter(type, gt), gt),
           0, true);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initBackgroundShapeDerivatives() {
   AKANTU_DEBUG_IN();
 
   for (auto interface_type :
        this->element_filter.elementTypes(this->spatial_dimension)) {
     for (auto type : background_filter(interface_type)->elementTypes(dim)) {
       computeBackgroundShapeDerivatives(interface_type, type, _not_ghost,
                                         this->element_filter(interface_type));
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::computeBackgroundShapeDerivatives(
     const ElementType & interface_type, const ElementType & bg_type,
     GhostType ghost_type, const Array<UInt> & filter) {
   auto & interface_engine = emodel.getFEEngine("EmbeddedInterfaceFEEngine");
   auto & engine = emodel.getFEEngine();
   auto & interface_mesh = emodel.getInterfaceMesh();
 
   const auto nb_nodes_elem_bg = Mesh::getNbNodesPerElement(bg_type);
   // const auto nb_strss = VoigtHelper<dim>::size;
   const auto nb_quads_per_elem =
       interface_engine.getNbIntegrationPoints(interface_type);
 
   Array<Real> quad_pos(0, dim, "interface_quad_pos");
   interface_engine.interpolateOnIntegrationPoints(interface_mesh.getNodes(),
                                                   quad_pos, dim, interface_type,
                                                   ghost_type, filter);
   auto & background_shapesd =
       (*shape_derivatives(interface_type, ghost_type))(bg_type, ghost_type);
   auto & background_elements =
       (*background_filter(interface_type, ghost_type))(bg_type, ghost_type);
   auto & foreground_elements =
       (*foreground_filter(interface_type, ghost_type))(bg_type, ghost_type);
 
   auto shapesd_begin =
     background_shapesd.begin(dim, nb_nodes_elem_bg, nb_quads_per_elem);
   auto quad_begin = quad_pos.begin(dim, nb_quads_per_elem);
 
   for (auto && tuple : zip(background_elements, foreground_elements)) {
     UInt bg = std::get<0>(tuple), fg = std::get<1>(tuple);
     for (UInt i = 0; i < nb_quads_per_elem; ++i) {
       Matrix<Real> shapesd = Tensor3<Real>(shapesd_begin[fg])(i);
       Vector<Real> quads = Matrix<Real>(quad_begin[fg])(i);
 
       engine.computeShapeDerivatives(quads, bg, bg_type, shapesd,
                                      ghost_type);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::initDirectingCosines() {
   AKANTU_DEBUG_IN();
 
   Mesh & mesh = emodel.getInterfaceMesh();
 
   Mesh::type_iterator type_it = mesh.firstType(1, _not_ghost);
   Mesh::type_iterator type_end = mesh.lastType(1, _not_ghost);
 
   const UInt voigt_size = VoigtHelper<dim>::size;
   directing_cosines.initialize(voigt_size);
 
   for (; type_it != type_end; ++type_it) {
     computeDirectingCosines(*type_it, _not_ghost);
     // computeDirectingCosines(*type_it, _ghost);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleStiffnessMatrix(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & interface_mesh = emodel.getInterfaceMesh();
 
   Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
   Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
 
   for (; type_it != type_end; ++type_it) {
     assembleStiffnessMatrix(*type_it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleInternalForces(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & interface_mesh = emodel.getInterfaceMesh();
 
   Mesh::type_iterator type_it = interface_mesh.firstType(1, _not_ghost);
   Mesh::type_iterator type_end = interface_mesh.lastType(1, _not_ghost);
 
   for (; type_it != type_end; ++type_it) {
     this->assembleInternalForces(*type_it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::computeAllStresses(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh::type_iterator it = emodel.getInterfaceMesh().firstType();
   Mesh::type_iterator last_type = emodel.getInterfaceMesh().lastType();
 
   for (; it != last_type; ++it) {
     computeGradU(*it, ghost_type);
     this->computeStress(*it, ghost_type);
     addPrestress(*it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::addPrestress(const ElementType & type,
                                                    GhostType ghost_type) {
   auto & stress = this->stress(type, ghost_type);
   auto & sigma_p = this->pre_stress(type, ghost_type);
 
   for (auto && tuple : zip(stress, sigma_p)) {
     std::get<0>(tuple) += std::get<1>(tuple);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleInternalForces(
     const ElementType & type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & mesh = emodel.getMesh();
 
   Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
   Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
 
   for (; type_it != type_end; ++type_it) {
     assembleInternalForcesInterface(type, *type_it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 /**
  * Computes and assemble the residual. Residual in reinforcement is computed as:
  *
  * \f[
  * \vec{r} = A_s \int_S{\mathbf{B}^T\mathbf{C}^T \vec{\sigma_s}\,\mathrm{d}s}
  * \f]
  */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleInternalForcesInterface(
     const ElementType & interface_type, const ElementType & background_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   UInt voigt_size = VoigtHelper<dim>::size;
 
   FEEngine & interface_engine = emodel.getFEEngine("EmbeddedInterfaceFEEngine");
 
   Array<UInt> & elem_filter = this->element_filter(interface_type, ghost_type);
 
   UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
   UInt nb_quadrature_points =
       interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
   UInt nb_element = elem_filter.size();
 
   UInt back_dof = dim * nodes_per_background_e;
 
   Array<Real> & shapesd = (*shape_derivatives(interface_type, ghost_type))(
       background_type, ghost_type);
 
   Array<Real> integrant(nb_quadrature_points * nb_element, back_dof,
                         "integrant");
 
-  Array<Real>::vector_iterator integrant_it = integrant.begin(back_dof);
-  Array<Real>::vector_iterator integrant_end = integrant.end(back_dof);
+  auto integrant_it = integrant.begin(back_dof);
+  auto integrant_end = integrant.end(back_dof);
 
   Array<Real>::matrix_iterator B_it =
       shapesd.begin(dim, nodes_per_background_e);
-  Array<Real>::vector_iterator C_it =
+  auto C_it =
       directing_cosines(interface_type, ghost_type).begin(voigt_size);
 
   auto sigma_it = this->stress(interface_type, ghost_type).begin();
 
   Matrix<Real> Bvoigt(voigt_size, back_dof);
 
   for (; integrant_it != integrant_end;
        ++integrant_it, ++B_it, ++C_it, ++sigma_it) {
     VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(*B_it, Bvoigt,
                                                        nodes_per_background_e);
     Vector<Real> & C = *C_it;
     Vector<Real> & BtCt_sigma = *integrant_it;
 
     BtCt_sigma.mul<true>(Bvoigt, C);
     BtCt_sigma *= *sigma_it * area;
   }
 
   Array<Real> residual_interface(nb_element, back_dof, "residual_interface");
   interface_engine.integrate(integrant, residual_interface, back_dof,
                              interface_type, ghost_type, elem_filter);
   integrant.resize(0);
 
   Array<UInt> background_filter(nb_element, 1, "background_filter");
 
   auto & filter =
       getBackgroundFilter(interface_type, background_type, ghost_type);
 
   emodel.getDOFManager().assembleElementalArrayLocalArray(
       residual_interface, emodel.getInternalForce(), background_type,
       ghost_type, -1., filter);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::computeDirectingCosines(
     const ElementType & type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & interface_mesh = emodel.getInterfaceMesh();
 
   const UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   const UInt steel_dof = dim * nb_nodes_per_element;
   const UInt voigt_size = VoigtHelper<dim>::size;
   const UInt nb_quad_points = emodel.getFEEngine("EmbeddedInterfaceFEEngine")
                                   .getNbIntegrationPoints(type, ghost_type);
 
   Array<Real> node_coordinates(this->element_filter(type, ghost_type).size(),
                                steel_dof);
 
   this->emodel.getFEEngine().template extractNodalToElementField<Real>(
       interface_mesh, interface_mesh.getNodes(), node_coordinates, type,
       ghost_type, this->element_filter(type, ghost_type));
 
   Array<Real>::matrix_iterator directing_cosines_it =
     directing_cosines(type, ghost_type).begin(1, voigt_size);
 
   Array<Real>::matrix_iterator node_coordinates_it =
       node_coordinates.begin(dim, nb_nodes_per_element);
   Array<Real>::matrix_iterator node_coordinates_end =
       node_coordinates.end(dim, nb_nodes_per_element);
 
   for (; node_coordinates_it != node_coordinates_end; ++node_coordinates_it) {
     for (UInt i = 0; i < nb_quad_points; i++, ++directing_cosines_it) {
       Matrix<Real> & nodes = *node_coordinates_it;
       Matrix<Real> & cosines = *directing_cosines_it;
 
       computeDirectingCosinesOnQuad(nodes, cosines);
     }
   }
 
   // Mauro: the directing_cosines internal is defined on the quadrature points
   // of each element
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleStiffnessMatrix(
     const ElementType & type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Mesh & mesh = emodel.getMesh();
 
   Mesh::type_iterator type_it = mesh.firstType(dim, ghost_type);
   Mesh::type_iterator type_end = mesh.lastType(dim, ghost_type);
 
   for (; type_it != type_end; ++type_it) {
     assembleStiffnessMatrixInterface(type, *type_it, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Computes the reinforcement stiffness matrix (Gomes & Awruch, 2001)
  * \f[
  * \mathbf{K}_e = \sum_{i=1}^R{A_i\int_{S_i}{\mathbf{B}^T
  * \mathbf{C}_i^T \mathbf{D}_{s, i} \mathbf{C}_i \mathbf{B}\,\mathrm{d}s}}
  * \f]
  */
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::assembleStiffnessMatrixInterface(
     const ElementType & interface_type, const ElementType & background_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   UInt voigt_size = VoigtHelper<dim>::size;
 
   FEEngine & interface_engine = emodel.getFEEngine("EmbeddedInterfaceFEEngine");
 
   Array<UInt> & elem_filter = this->element_filter(interface_type, ghost_type);
   Array<Real> & grad_u = gradu_embedded(interface_type, ghost_type);
 
   UInt nb_element = elem_filter.size();
   UInt nodes_per_background_e = Mesh::getNbNodesPerElement(background_type);
   UInt nb_quadrature_points =
       interface_engine.getNbIntegrationPoints(interface_type, ghost_type);
 
   UInt back_dof = dim * nodes_per_background_e;
 
   UInt integrant_size = back_dof;
 
   grad_u.resize(nb_quadrature_points * nb_element);
 
   Array<Real> tangent_moduli(nb_element * nb_quadrature_points, 1,
                              "interface_tangent_moduli");
   this->computeTangentModuli(interface_type, tangent_moduli, ghost_type);
 
   Array<Real> & shapesd = (*shape_derivatives(interface_type, ghost_type))(
       background_type, ghost_type);
 
   Array<Real> integrant(nb_element * nb_quadrature_points,
                         integrant_size * integrant_size, "B^t*C^t*D*C*B");
 
   /// Temporary matrices for integrant product
   Matrix<Real> Bvoigt(voigt_size, back_dof);
   Matrix<Real> DCB(1, back_dof);
   Matrix<Real> CtDCB(voigt_size, back_dof);
 
   Array<Real>::scalar_iterator D_it = tangent_moduli.begin();
   Array<Real>::scalar_iterator D_end = tangent_moduli.end();
 
   Array<Real>::matrix_iterator C_it =
       directing_cosines(interface_type, ghost_type).begin(1, voigt_size);
   Array<Real>::matrix_iterator B_it =
       shapesd.begin(dim, nodes_per_background_e);
   Array<Real>::matrix_iterator integrant_it =
       integrant.begin(integrant_size, integrant_size);
 
   for (; D_it != D_end; ++D_it, ++C_it, ++B_it, ++integrant_it) {
     Real & D = *D_it;
     Matrix<Real> & C = *C_it;
     Matrix<Real> & B = *B_it;
     Matrix<Real> & BtCtDCB = *integrant_it;
 
     VoigtHelper<dim>::transferBMatrixToSymVoigtBMatrix(B, Bvoigt,
                                                        nodes_per_background_e);
 
     DCB.mul<false, false>(C, Bvoigt);
     DCB *= D * area;
     CtDCB.mul<true, false>(C, DCB);
     BtCtDCB.mul<true, false>(Bvoigt, CtDCB);
   }
 
   tangent_moduli.resize(0);
 
   Array<Real> K_interface(nb_element, integrant_size * integrant_size,
                           "K_interface");
   interface_engine.integrate(integrant, K_interface,
                              integrant_size * integrant_size, interface_type,
                              ghost_type, elem_filter);
 
   integrant.resize(0);
 
   // Mauro: Here K_interface contains the local stiffness matrices,
   // directing_cosines contains the information about the orientation
   // of the reinforcements, any rotation of the local stiffness matrix
   // can be done here
 
   auto & filter =
       getBackgroundFilter(interface_type, background_type, ghost_type);
 
   emodel.getDOFManager().assembleElementalMatricesToMatrix(
       "K", "displacement", K_interface, background_type, ghost_type, _symmetric,
       filter);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Mat, UInt dim>
 Real MaterialReinforcement<Mat, dim>::getEnergy(const std::string & id) {
   AKANTU_DEBUG_IN();
   if (id == "potential") {
     Real epot = 0.;
 
     this->computePotentialEnergyByElements();
 
     Mesh::type_iterator it = this->element_filter.firstType(
                             this->spatial_dimension),
                         end = this->element_filter.lastType(
                             this->spatial_dimension);
 
     for (; it != end; ++it) {
       FEEngine & interface_engine =
           emodel.getFEEngine("EmbeddedInterfaceFEEngine");
       epot += interface_engine.integrate(
           this->potential_energy(*it, _not_ghost), *it, _not_ghost,
           this->element_filter(*it, _not_ghost));
       epot *= area;
     }
 
     return epot;
   }
 
   AKANTU_DEBUG_OUT();
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 void MaterialReinforcement<Mat, dim>::computeGradU(
     const ElementType & interface_type, GhostType ghost_type) {
   // Looping over background types
   for (auto && bg_type :
        background_filter(interface_type, ghost_type)->elementTypes(dim)) {
 
     const UInt nodes_per_background_e = Mesh::getNbNodesPerElement(bg_type);
     const UInt voigt_size = VoigtHelper<dim>::size;
 
     auto & bg_shapesd =
         (*shape_derivatives(interface_type, ghost_type))(bg_type, ghost_type);
 
     auto & filter = getBackgroundFilter(interface_type, bg_type, ghost_type);
 
     Array<Real> disp_per_element(0, dim * nodes_per_background_e, "disp_elem");
 
     FEEngine::extractNodalToElementField(
         emodel.getMesh(), emodel.getDisplacement(), disp_per_element, bg_type,
         ghost_type, filter);
 
     Matrix<Real> concrete_du(dim, dim);
     Matrix<Real> epsilon(dim, dim);
     Vector<Real> evoigt(voigt_size);
 
     for (auto && tuple :
          zip(make_view(disp_per_element, dim, nodes_per_background_e),
              make_view(bg_shapesd, dim, nodes_per_background_e),
              this->gradu(interface_type, ghost_type),
              make_view(this->directing_cosines(interface_type, ghost_type),
                        voigt_size))) {
       auto & u = std::get<0>(tuple);
       auto & B = std::get<1>(tuple);
       auto & du = std::get<2>(tuple);
       auto & C = std::get<3>(tuple);
 
       concrete_du.mul<false, true>(u, B);
       auto epsilon = 0.5 * (concrete_du + concrete_du.transpose());
       strainTensorToVoigtVector(epsilon, evoigt);
       du = C.dot(evoigt);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 /**
  * The structure of the directing cosines matrix is :
  * \f{eqnarray*}{
  *  C_{1,\cdot} & = & (l^2, m^2, n^2, mn, ln, lm) \\
  *  C_{i,j} & = & 0
  * \f}
  *
  * with :
  * \f[
  * (l, m, n) = \frac{1}{\|\frac{\mathrm{d}\vec{r}(s)}{\mathrm{d}s}\|} \cdot
  * \frac{\mathrm{d}\vec{r}(s)}{\mathrm{d}s}
  * \f]
  */
 template <class Mat, UInt dim>
 inline void MaterialReinforcement<Mat, dim>::computeDirectingCosinesOnQuad(
     const Matrix<Real> & nodes, Matrix<Real> & cosines) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_ASSERT(nodes.cols() == 2,
                       "Higher order reinforcement elements not implemented");
 
   const Vector<Real> a = nodes(0), b = nodes(1);
   Vector<Real> delta = b - a;
 
   Real sq_length = 0.;
   for (UInt i = 0; i < dim; i++) {
     sq_length += delta(i) * delta(i);
   }
 
   if (dim == 2) {
     cosines(0, 0) = delta(0) * delta(0); // l^2
     cosines(0, 1) = delta(1) * delta(1); // m^2
     cosines(0, 2) = delta(0) * delta(1); // lm
   } else if (dim == 3) {
     cosines(0, 0) = delta(0) * delta(0); // l^2
     cosines(0, 1) = delta(1) * delta(1); // m^2
     cosines(0, 2) = delta(2) * delta(2); // n^2
 
     cosines(0, 3) = delta(1) * delta(2); // mn
     cosines(0, 4) = delta(0) * delta(2); // ln
     cosines(0, 5) = delta(0) * delta(1); // lm
   }
 
   cosines /= sq_length;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 inline void MaterialReinforcement<Mat, dim>::stressTensorToVoigtVector(
     const Matrix<Real> & tensor, Vector<Real> & vector) {
   AKANTU_DEBUG_IN();
 
   for (UInt i = 0; i < dim; i++) {
     vector(i) = tensor(i, i);
   }
 
   if (dim == 2) {
     vector(2) = tensor(0, 1);
   } else if (dim == 3) {
     vector(3) = tensor(1, 2);
     vector(4) = tensor(0, 2);
     vector(5) = tensor(0, 1);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <class Mat, UInt dim>
 inline void MaterialReinforcement<Mat, dim>::strainTensorToVoigtVector(
     const Matrix<Real> & tensor, Vector<Real> & vector) {
   AKANTU_DEBUG_IN();
 
   for (UInt i = 0; i < dim; i++) {
     vector(i) = tensor(i, i);
   }
 
   if (dim == 2) {
     vector(2) = 2 * tensor(0, 1);
   } else if (dim == 3) {
     vector(3) = 2 * tensor(1, 2);
     vector(4) = 2 * tensor(0, 2);
     vector(5) = 2 * tensor(0, 1);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc b/src/model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
index 2ae5024da..8f5d0f5b8 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,326 +1,326 @@
 /**
  * @file   material_standard_linear_solid_deviatoric.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Vladislav Yastrebov <vladislav.yastrebov@epfl.ch>
  *
  * @date creation: Wed May 04 2011
  * @date last modification: Thu Oct 15 2015
  *
  * @brief  Material Visco-elastic
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_standard_linear_solid_deviatoric.hh"
 #include "solid_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialStandardLinearSolidDeviatoric<spatial_dimension>::
     MaterialStandardLinearSolidDeviatoric(SolidMechanicsModel & model,
                                           const ID & id)
     : MaterialElastic<spatial_dimension>(model, id),
       stress_dev("stress_dev", *this),
       history_integral("history_integral", *this),
       dissipated_energy("dissipated_energy", *this) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam("Eta", eta, Real(1.), _pat_parsable | _pat_modifiable,
                       "Viscosity");
   this->registerParam("Ev", Ev, Real(1.), _pat_parsable | _pat_modifiable,
                       "Stiffness of the viscous element");
   this->registerParam("Einf", E_inf, Real(1.), _pat_readable,
                       "Stiffness of the elastic element");
 
   UInt stress_size = spatial_dimension * spatial_dimension;
 
   this->stress_dev.initialize(stress_size);
   this->history_integral.initialize(stress_size);
   this->dissipated_energy.initialize(1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   updateInternalParameters();
   MaterialElastic<spatial_dimension>::initMaterial();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<
     spatial_dimension>::updateInternalParameters() {
   MaterialElastic<spatial_dimension>::updateInternalParameters();
   E_inf = this->E - this->Ev;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::setToSteadyState(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
   Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
 
   Array<Real>::matrix_iterator stress_d =
       stress_dev_vect.begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator history_int =
       history_int_vect.begin(spatial_dimension, spatial_dimension);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & dev_s = *stress_d;
   Matrix<Real> & h = *history_int;
 
   /// Compute the first invariant of strain
   Real Theta = grad_u.trace();
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j) {
       dev_s(i, j) =
           2 * this->mu *
           (.5 * (grad_u(i, j) + grad_u(j, i)) - 1. / 3. * Theta * (i == j));
       h(i, j) = 0.;
     }
 
   /// Save the deviator of stress
   ++stress_d;
   ++history_int;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<spatial_dimension>::computeStress(
     ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real tau = 0.;
   // if(std::abs(Ev) > std::numeric_limits<Real>::epsilon())
   tau = eta / Ev;
 
   Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
   Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
 
   Array<Real>::matrix_iterator stress_d =
       stress_dev_vect.begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator history_int =
       history_int_vect.begin(spatial_dimension, spatial_dimension);
 
   Matrix<Real> s(spatial_dimension, spatial_dimension);
 
   Real dt = this->model.getTimeStep();
   Real exp_dt_tau = exp(-dt / tau);
   Real exp_dt_tau_2 = exp(-.5 * dt / tau);
 
   Matrix<Real> epsilon_d(spatial_dimension, spatial_dimension);
   Matrix<Real> epsilon_v(spatial_dimension, spatial_dimension);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & dev_s = *stress_d;
   Matrix<Real> & h = *history_int;
 
   s.clear();
   sigma.clear();
 
   /// Compute the first invariant of strain
   Real gamma_inf = E_inf / this->E;
   Real gamma_v = Ev / this->E;
 
   this->template gradUToEpsilon<spatial_dimension>(grad_u, epsilon_d);
   Real Theta = epsilon_d.trace();
   epsilon_v.eye(Theta / Real(3.));
   epsilon_d -= epsilon_v;
 
   Matrix<Real> U_rond_prim(spatial_dimension, spatial_dimension);
 
   U_rond_prim.eye(gamma_inf * this->kpa * Theta);
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j) {
       s(i, j) = 2 * this->mu * epsilon_d(i, j);
       h(i, j) = exp_dt_tau * h(i, j) + exp_dt_tau_2 * (s(i, j) - dev_s(i, j));
       dev_s(i, j) = s(i, j);
       sigma(i, j) = U_rond_prim(i, j) + gamma_inf * s(i, j) + gamma_v * h(i, j);
     }
 
   /// Save the deviator of stress
   ++stress_d;
   ++history_int;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   this->updateDissipatedEnergy(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialStandardLinearSolidDeviatoric<
     spatial_dimension>::updateDissipatedEnergy(ElementType el_type,
                                                GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   // if(ghost_type == _ghost) return 0.;
 
   Real tau = 0.;
   tau = eta / Ev;
   Real * dis_energy = dissipated_energy(el_type, ghost_type).storage();
 
   Array<Real> & stress_dev_vect = stress_dev(el_type, ghost_type);
   Array<Real> & history_int_vect = history_integral(el_type, ghost_type);
 
   Array<Real>::matrix_iterator stress_d =
       stress_dev_vect.begin(spatial_dimension, spatial_dimension);
   Array<Real>::matrix_iterator history_int =
       history_int_vect.begin(spatial_dimension, spatial_dimension);
 
   Matrix<Real> q(spatial_dimension, spatial_dimension);
   Matrix<Real> q_rate(spatial_dimension, spatial_dimension);
   Matrix<Real> epsilon_d(spatial_dimension, spatial_dimension);
   Matrix<Real> epsilon_v(spatial_dimension, spatial_dimension);
 
   Real dt = this->model.getTimeStep();
 
   Real gamma_v = Ev / this->E;
   Real alpha = 1. / (2. * this->mu * gamma_v);
 
   /// Loop on all quadrature points
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   Matrix<Real> & dev_s = *stress_d;
   Matrix<Real> & h = *history_int;
 
   /// Compute the first invariant of strain
   this->template gradUToEpsilon<spatial_dimension>(grad_u, epsilon_d);
 
   Real Theta = epsilon_d.trace();
   epsilon_v.eye(Theta / Real(3.));
   epsilon_d -= epsilon_v;
 
   q.copy(dev_s);
   q -= h;
   q *= gamma_v;
 
   q_rate.copy(dev_s);
   q_rate *= gamma_v;
   q_rate -= q;
   q_rate /= tau;
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j)
       *dis_energy += (epsilon_d(i, j) - alpha * q(i, j)) * q_rate(i, j) * dt;
 
   /// Save the deviator of stress
   ++stress_d;
   ++history_int;
   ++dis_energy;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialStandardLinearSolidDeviatoric<
     spatial_dimension>::getDissipatedEnergy() const {
   AKANTU_DEBUG_IN();
 
   Real de = 0.;
 
   /// integrate the dissipated energy for each type of elements
   for (auto & type :
        this->element_filter.elementTypes(spatial_dimension, _not_ghost)) {
     de +=
         this->fem.integrate(dissipated_energy(type, _not_ghost), type,
                             _not_ghost, this->element_filter(type, _not_ghost));
   }
 
   AKANTU_DEBUG_OUT();
   return de;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialStandardLinearSolidDeviatoric<
     spatial_dimension>::getDissipatedEnergy(ElementType type,
                                             UInt index) const {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = this->fem.getNbIntegrationPoints(type);
-  Array<Real>::const_vector_iterator it =
+  auto it =
       this->dissipated_energy(type, _not_ghost).begin(nb_quadrature_points);
   UInt gindex = (this->element_filter(type, _not_ghost))(index);
 
   AKANTU_DEBUG_OUT();
   return this->fem.integrate(it[index], type, gindex);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getEnergy(
     const std::string & type) {
   if (type == "dissipated")
     return getDissipatedEnergy();
   else if (type == "dissipated_sls_deviatoric")
     return getDissipatedEnergy();
   else
     return MaterialElastic<spatial_dimension>::getEnergy(type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 Real MaterialStandardLinearSolidDeviatoric<spatial_dimension>::getEnergy(
     const std::string & energy_id, ElementType type, UInt index) {
   if (energy_id == "dissipated")
     return getDissipatedEnergy(type, index);
   else if (energy_id == "dissipated_sls_deviatoric")
     return getDissipatedEnergy(type, index);
   else
     return MaterialElastic<spatial_dimension>::getEnergy(energy_id, type,
                                                          index);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(sls_deviatoric, MaterialStandardLinearSolidDeviatoric);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc b/src/model/solid_mechanics/materials/weight_functions/stress_based_weight_function.cc
index e8e9108ba..714f57229 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,117 +1,117 @@
 /**
  * @file   stress_based_weight_function.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Aug 24 2015
  * @date last modification: Wed Oct 07 2015
  *
  * @brief  implementation of the stres based weight function classes
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "stress_based_weight_function.hh"
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 StressBasedWeightFunction::StressBasedWeightFunction(NonLocalManager & manager) :
   BaseWeightFunction(manager, "stress_based")
   // stress_diag("stress_diag", material), selected_stress_diag(NULL),
   // stress_base("stress_base", material), selected_stress_base(NULL),
   // characteristic_size("lc", material),  selected_characteristic_size(NULL) 
 {
 
   // this->registerParam("ft", this->ft, 0., _pat_parsable, "Tensile strength");
   // stress_diag.initialize(spatial_dimension);
   // stress_base.initialize(spatial_dimension * spatial_dimension);
   // characteristic_size.initialize(1);
 }
 
 /* -------------------------------------------------------------------------- */
 /// During intialization the characteristic sizes for all quadrature
 /// points are computed
 void StressBasedWeightFunction::init() {
   // const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
   // for (UInt g = _not_ghost; g <= _ghost; ++g) {
   //   GhostType gt = GhostType(g);
   //   Mesh::type_iterator it = mesh.firstType(spatial_dimension, gt);
   //   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, gt);
   //   for(; it != last_type; ++it) {
   //     UInt nb_quadrature_points =
   // 	this->material.getModel().getFEEngine().getNbQuadraturePoints(*it, gt);
   //     const Array<UInt> & element_filter = this->material.getElementFilter(*it, gt);
   //     UInt nb_element = element_filter.size();
 
   //     Array<Real> ones(nb_element*nb_quadrature_points, 1, 1.);
   //     Array<Real> & lc = characteristic_size(*it, gt);
   //     this->material.getModel().getFEEngine().integrateOnQuadraturePoints(ones,
   // 								     lc,
   // 								     1,
   // 								     *it,
   // 								     gt,
   // 								     element_filter);
 
   //     for (UInt q = 0;  q < nb_quadrature_points * nb_element; q++) {
   // 	lc(q) = pow(lc(q), 1./ Real(spatial_dimension));
   //     }
   //   }
   // }
 }
 
 
 /* -------------------------------------------------------------------------- */
 /// computation of principals stresses and principal directions
 void StressBasedWeightFunction::updatePrincipalStress(__attribute__((unused)) GhostType ghost_type) {
 //   AKANTU_DEBUG_IN();
 
 //   const Mesh & mesh = this->material.getModel().getFEEngine().getMesh();
 
 //   Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type);
 //   Mesh::type_iterator last_type = mesh.lastType(spatial_dimension, ghost_type);
 //   for(; it != last_type; ++it) {
 //     Array<Real>::const_matrix_iterator sigma =
 //       this->material.getStress(*it, ghost_type).begin(spatial_dimension, spatial_dimension);
-//     Array<Real>::vector_iterator eigenvalues =
+//     auto eigenvalues =
 //       stress_diag(*it, ghost_type).begin(spatial_dimension);
-//     Array<Real>::vector_iterator eigenvalues_end =
+//     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__
-//     Array<Real>::iterator<Real> cl = characteristic_size(*it, ghost_type).begin();
+//     auto cl = characteristic_size(*it, ghost_type).begin();
 // #endif
 //     UInt q = 0;
 //     for(;eigenvalues != eigenvalues_end; ++sigma, ++eigenvalues, ++eigenvector, ++cl, ++q) {
 //       sigma->eig(*eigenvalues, *eigenvector);
 //       *eigenvalues /= ft;
 // #ifndef __trick__
 //       // specify a lower bound for principal stress based on the size of the element
 //       for (UInt i = 0; i < spatial_dimension; ++i) {
 //         (*eigenvalues)(i) = std::max(*cl / this->R, (*eigenvalues)(i));
 //       }
 // #endif
 //     }
 //   }
 //   AKANTU_DEBUG_OUT();
 }
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model.cc b/src/model/solid_mechanics/solid_mechanics_model.cc
index 189e4a50d..e97927adf 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model.cc
@@ -1,1195 +1,1195 @@
 /**
  * @file   solid_mechanics_model.cc
  *
  * @author Ramin Aghababaei <ramin.aghababaei@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Clement Roux <clement.roux@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue Jul 27 2010
  * @date last modification: Tue Jan 19 2016
  *
  * @brief  Implementation of the SolidMechanicsModel class
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model.hh"
 #include "integrator_gauss.hh"
 #include "shape_lagrange.hh"
 #include "solid_mechanics_model_tmpl.hh"
 
 #include "communicator.hh"
 #include "element_synchronizer.hh"
 #include "sparse_matrix.hh"
 #include "synchronizer_registry.hh"
 
 #include "dumpable_inline_impl.hh"
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_iohelper_paraview.hh"
 #endif
 
 #include "material_non_local.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /**
  * A solid mechanics model need a mesh  and a dimension to be created. the model
  * by it  self can not  do a lot,  the good init  functions should be  called in
  * order to configure the model depending on what we want to do.
  *
  * @param  mesh mesh  representing  the model  we  want to  simulate
  * @param dim spatial  dimension of the problem, if dim =  0 (default value) the
  * dimension of the problem is assumed to be the on of the mesh
  * @param id an id to identify the model
  */
 SolidMechanicsModel::SolidMechanicsModel(Mesh & mesh, UInt dim, const ID & id,
                                          const MemoryID & memory_id, const ModelType model_type)
     : Model(mesh, model_type, dim, id, memory_id),
       BoundaryCondition<SolidMechanicsModel>(), f_m2a(1.0),
       displacement(nullptr), previous_displacement(nullptr),
       displacement_increment(nullptr), mass(nullptr), velocity(nullptr),
       acceleration(nullptr), external_force(nullptr), internal_force(nullptr),
       blocked_dofs(nullptr), current_position(nullptr),
       material_index("material index", id, memory_id),
       material_local_numbering("material local numbering", id, memory_id),
       increment_flag(false),
       are_materials_instantiated(false) {
   AKANTU_DEBUG_IN();
 
   this->registerFEEngineObject<MyFEEngineType>("SolidMechanicsFEEngine", mesh,
                                                Model::spatial_dimension);
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.registerDumper<DumperParaview>("paraview_all", id, true);
   this->mesh.addDumpMesh(mesh, Model::spatial_dimension, _not_ghost,
                          _ek_regular);
 #endif
 
   material_selector = std::make_shared<DefaultMaterialSelector>(material_index),
 
   this->initDOFManager();
 
   this->registerDataAccessor(*this);
 
   if (this->mesh.isDistributed()) {
     auto & synchronizer = this->mesh.getElementSynchronizer();
     this->registerSynchronizer(synchronizer, _gst_material_id);
     this->registerSynchronizer(synchronizer, _gst_smm_mass);
     this->registerSynchronizer(synchronizer, _gst_smm_stress);
     this->registerSynchronizer(synchronizer, _gst_smm_boundary);
     this->registerSynchronizer(synchronizer, _gst_for_dump);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 SolidMechanicsModel::~SolidMechanicsModel() {
   AKANTU_DEBUG_IN();
 
   for (auto & internal : this->registered_internals) {
     delete internal.second;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::setTimeStep(Real time_step, const ID & solver_id) {
   Model::setTimeStep(time_step, solver_id);
 
 #if defined(AKANTU_USE_IOHELPER)
   this->mesh.getDumper().setTimeStep(time_step);
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 /* Initialization                                                             */
 /* -------------------------------------------------------------------------- */
 /**
  * This function groups  many of the initialization in on  function. For most of
  * basics  case the  function should  be  enough. The  functions initialize  the
  * model, the internal  vectors, set them to 0, and  depending on the parameters
  * it also initialize the explicit or implicit solver.
  *
  * @param material_file the  file containing the materials to  use
  * @param method the analysis method wanted.  See the akantu::AnalysisMethod for
  * the different possibilities
  */
 void SolidMechanicsModel::initFullImpl(const ModelOptions & options) {
   material_index.initialize(mesh, _element_kind = _ek_not_defined,
                             _default_value = UInt(-1), _with_nb_element = true);
   material_local_numbering.initialize(mesh, _element_kind = _ek_not_defined,
                                       _with_nb_element = true);
 
   Model::initFullImpl(options);
 
   // initialize pbc
   if (this->pbc_pair.size() != 0)
     this->initPBC();
 
   // initialize the materials
   if (this->parser.getLastParsedFile() != "") {
     this->instantiateMaterials();
   }
 
   this->initMaterials();
 
   this->initBC(*this, *displacement, *displacement_increment, *external_force);
 }
 
 /* -------------------------------------------------------------------------- */
 TimeStepSolverType SolidMechanicsModel::getDefaultSolverType() const {
   return _tsst_dynamic_lumped;
 }
 
 /* -------------------------------------------------------------------------- */
 ModelSolverOptions SolidMechanicsModel::getDefaultSolverOptions(
     const TimeStepSolverType & type) const {
   ModelSolverOptions options;
 
   switch (type) {
   case _tsst_dynamic_lumped: {
     options.non_linear_solver_type = _nls_lumped;
     options.integration_scheme_type["displacement"] = _ist_central_difference;
     options.solution_type["displacement"] = IntegrationScheme::_acceleration;
     break;
   }
   case _tsst_static: {
     options.non_linear_solver_type = _nls_newton_raphson;
     options.integration_scheme_type["displacement"] = _ist_pseudo_time;
     options.solution_type["displacement"] = IntegrationScheme::_not_defined;
     break;
   }
   case _tsst_dynamic: {
     if (this->method == _explicit_consistent_mass) {
       options.non_linear_solver_type = _nls_newton_raphson;
       options.integration_scheme_type["displacement"] = _ist_central_difference;
       options.solution_type["displacement"] = IntegrationScheme::_acceleration;
     } else {
       options.non_linear_solver_type = _nls_newton_raphson;
       options.integration_scheme_type["displacement"] = _ist_trapezoidal_rule_2;
       options.solution_type["displacement"] = IntegrationScheme::_displacement;
     }
     break;
   }
   default:
     AKANTU_EXCEPTION(type << " is not a valid time step solver type");
   }
 
   return options;
 }
 
 /* -------------------------------------------------------------------------- */
 std::tuple<ID, TimeStepSolverType>
 SolidMechanicsModel::getDefaultSolverID(const AnalysisMethod & method) {
   switch (method) {
   case _explicit_lumped_mass: {
     return std::make_tuple("explicit_lumped", _tsst_dynamic_lumped);
   }
   case _explicit_consistent_mass: {
     return std::make_tuple("explicit", _tsst_dynamic);
   }
   case _static: {
     return std::make_tuple("static", _tsst_static);
   }
   case _implicit_dynamic: {
     return std::make_tuple("implicit", _tsst_dynamic);
   }
   default:
     return std::make_tuple("unknown", _tsst_not_defined);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::initSolver(TimeStepSolverType time_step_solver_type,
                                      NonLinearSolverType) {
   auto & dof_manager = this->getDOFManager();
 
   /* ------------------------------------------------------------------------ */
   // for alloc type of solvers
   this->allocNodalField(this->displacement, spatial_dimension, "displacement");
   this->allocNodalField(this->previous_displacement, spatial_dimension,
                         "previous_displacement");
   this->allocNodalField(this->displacement_increment, spatial_dimension,
                         "displacement_increment");
   this->allocNodalField(this->internal_force, spatial_dimension,
                         "internal_force");
   this->allocNodalField(this->external_force, spatial_dimension,
                         "external_force");
   this->allocNodalField(this->blocked_dofs, spatial_dimension, "blocked_dofs");
   this->allocNodalField(this->current_position, spatial_dimension,
                         "current_position");
 
   // initialize the current positions
   this->current_position->copy(this->mesh.getNodes());
 
   /* ------------------------------------------------------------------------ */
   if (!dof_manager.hasDOFs("displacement")) {
     dof_manager.registerDOFs("displacement", *this->displacement, _dst_nodal);
     dof_manager.registerBlockedDOFs("displacement", *this->blocked_dofs);
     dof_manager.registerDOFsIncrement("displacement",
                                       *this->displacement_increment);
     dof_manager.registerDOFsPrevious("displacement",
                                      *this->previous_displacement);
   }
 
   /* ------------------------------------------------------------------------ */
   // for dynamic
   if (time_step_solver_type == _tsst_dynamic ||
       time_step_solver_type == _tsst_dynamic_lumped) {
     this->allocNodalField(this->velocity, spatial_dimension, "velocity");
     this->allocNodalField(this->acceleration, spatial_dimension,
                           "acceleration");
 
     if (!dof_manager.hasDOFsDerivatives("displacement", 1)) {
       dof_manager.registerDOFsDerivative("displacement", 1, *this->velocity);
       dof_manager.registerDOFsDerivative("displacement", 2,
                                          *this->acceleration);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Initialize the model,basically it  pre-compute the shapes, shapes derivatives
  * and jacobian
  */
 void SolidMechanicsModel::initModel() {
   /// \todo add  the current position  as a parameter to  initShapeFunctions for
   /// large deformation
   getFEEngine().initShapeFunctions(_not_ghost);
   getFEEngine().initShapeFunctions(_ghost);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleResidual() {
   AKANTU_DEBUG_IN();
 
   /* ------------------------------------------------------------------------ */
   // computes the internal forces
   this->assembleInternalForces();
 
   /* ------------------------------------------------------------------------ */
   this->getDOFManager().assembleToResidual("displacement",
                                            *this->external_force, 1);
   this->getDOFManager().assembleToResidual("displacement",
                                            *this->internal_force, 1);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 MatrixType SolidMechanicsModel::getMatrixType(const ID & matrix_id) {
   // \TODO check the materials to know what is the correct answer
   if (matrix_id == "C")
     return _mt_not_defined;
 
   return _symmetric;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleMatrix(const ID & matrix_id) {
   if (matrix_id == "K") {
     this->assembleStiffnessMatrix();
   } else if (matrix_id == "M") {
     this->assembleMass();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleLumpedMatrix(const ID & matrix_id) {
   if (matrix_id == "M") {
     this->assembleMassLumped();
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::beforeSolveStep() {
   for (auto & material : materials)
     material->beforeSolveStep();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::afterSolveStep() {
   for (auto & material : materials)
     material->afterSolveStep();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::predictor() { ++displacement_release; }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::corrector() { ++displacement_release; }
 
 /* -------------------------------------------------------------------------- */
 /**
  * This function computes the internal forces as F_{int} = \int_{\Omega} N
  * \sigma d\Omega@f$
  */
 void SolidMechanicsModel::assembleInternalForces() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Assemble the internal forces");
 
   this->internal_force->clear();
 
   // compute the stresses of local elements
   AKANTU_DEBUG_INFO("Compute local stresses");
   for (auto & material : materials) {
     material->computeAllStresses(_not_ghost);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Computation of the non local part */
   if (this->non_local_manager)
     this->non_local_manager->computeAllNonLocalStresses();
 
   // communicate the stresses
   AKANTU_DEBUG_INFO("Send data for residual assembly");
   this->asynchronousSynchronize(_gst_smm_stress);
 
   // assemble the forces due to local stresses
   AKANTU_DEBUG_INFO("Assemble residual for local elements");
   for (auto & material : materials) {
     material->assembleInternalForces(_not_ghost);
   }
 
   // finalize communications
   AKANTU_DEBUG_INFO("Wait distant stresses");
   this->waitEndSynchronize(_gst_smm_stress);
 
   // assemble the stresses due to ghost elements
   AKANTU_DEBUG_INFO("Assemble residual for ghost elements");
   for (auto & material : materials) {
     material->assembleInternalForces(_ghost);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::assembleStiffnessMatrix() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_INFO("Assemble the new stiffness matrix.");
 
   // Check if materials need to recompute the matrix
   bool need_to_reassemble = false;
 
   for (auto & material : materials) {
     need_to_reassemble |= material->hasStiffnessMatrixChanged();
   }
 
   if (need_to_reassemble) {
     this->getDOFManager().getMatrix("K").clear();
 
     // call compute stiffness matrix on each local elements
     for (auto & material : materials) {
       material->assembleStiffnessMatrix(_not_ghost);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::updateCurrentPosition() {
   if (this->current_position_release == this->displacement_release)
     return;
 
   this->current_position->copy(this->mesh.getNodes());
 
   auto cpos_it = this->current_position->begin(Model::spatial_dimension);
   auto cpos_end = this->current_position->end(Model::spatial_dimension);
   auto disp_it = this->displacement->begin(Model::spatial_dimension);
 
   for (; cpos_it != cpos_end; ++cpos_it, ++disp_it) {
     *cpos_it += *disp_it;
   }
 
   this->current_position_release = this->displacement_release;
 }
 
 /* -------------------------------------------------------------------------- */
 const Array<Real> & SolidMechanicsModel::getCurrentPosition() {
   this->updateCurrentPosition();
   return *this->current_position;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::updateDataForNonLocalCriterion(
     ElementTypeMapReal & criterion) {
   const ID field_name = criterion.getName();
   for (auto & material : materials) {
     if (!material->isInternal<Real>(field_name, _ek_regular))
       continue;
 
     for (auto ghost_type : ghost_types) {
       material->flattenInternal(field_name, criterion, ghost_type, _ek_regular);
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 /* Information                                                                */
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getStableTimeStep() {
   AKANTU_DEBUG_IN();
 
   Real min_dt = getStableTimeStep(_not_ghost);
 
   /// reduction min over all processors
   mesh.getCommunicator().allReduce(min_dt, SynchronizerOperation::_min);
 
   AKANTU_DEBUG_OUT();
   return min_dt;
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getStableTimeStep(const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   Real min_dt = std::numeric_limits<Real>::max();
 
   this->updateCurrentPosition();
 
   Element elem;
   elem.ghost_type = ghost_type;
 
   for (auto type :
        mesh.elementTypes(Model::spatial_dimension, ghost_type, _ek_regular)) {
     elem.type = type;
     UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type);
     UInt nb_element = mesh.getNbElement(type);
 
     auto mat_indexes = material_index(type, ghost_type).begin();
     auto mat_loc_num = material_local_numbering(type, ghost_type).begin();
 
     Array<Real> X(0, nb_nodes_per_element * Model::spatial_dimension);
     FEEngine::extractNodalToElementField(mesh, *current_position, X, type,
                                          _not_ghost);
 
     auto X_el = X.begin(Model::spatial_dimension, nb_nodes_per_element);
 
     for (UInt el = 0; el < nb_element;
          ++el, ++X_el, ++mat_indexes, ++mat_loc_num) {
       elem.element = *mat_loc_num;
       Real el_h = getFEEngine().getElementInradius(*X_el, type);
       Real el_c = this->materials[*mat_indexes]->getCelerity(elem);
       Real el_dt = el_h / el_c;
 
       min_dt = std::min(min_dt, el_dt);
     }
   }
 
   AKANTU_DEBUG_OUT();
   return min_dt;
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getKineticEnergy() {
   AKANTU_DEBUG_IN();
 
   Real ekin = 0.;
   UInt nb_nodes = mesh.getNbNodes();
 
   if (this->getDOFManager().hasLumpedMatrix("M")) {
     auto m_it = this->mass->begin(Model::spatial_dimension);
     auto m_end = this->mass->end(Model::spatial_dimension);
     auto v_it = this->velocity->begin(Model::spatial_dimension);
 
     for (UInt n = 0; m_it != m_end; ++n, ++m_it, ++v_it) {
       const Vector<Real> & v = *v_it;
       const Vector<Real> & m = *m_it;
 
       Real mv2 = 0;
       bool is_local_node = mesh.isLocalOrMasterNode(n);
       // bool is_not_pbc_slave_node = !isPBCSlaveNode(n);
       bool count_node = is_local_node; // && is_not_pbc_slave_node;
       if (count_node) {
         for (UInt i = 0; i < Model::spatial_dimension; ++i) {
           if (m(i) > std::numeric_limits<Real>::epsilon())
             mv2 += v(i) * v(i) * m(i);
         }
       }
 
       ekin += mv2;
     }
   } else if (this->getDOFManager().hasMatrix("M")) {
     Array<Real> Mv(nb_nodes, Model::spatial_dimension);
     this->getDOFManager().getMatrix("M").matVecMul(*this->velocity, Mv);
 
     auto mv_it = Mv.begin(Model::spatial_dimension);
     auto mv_end = Mv.end(Model::spatial_dimension);
     auto v_it = this->velocity->begin(Model::spatial_dimension);
 
     for (; mv_it != mv_end; ++mv_it, ++v_it) {
       ekin += v_it->dot(*mv_it);
     }
   } else {
     AKANTU_ERROR("No function called to assemble the mass matrix.");
   }
 
   mesh.getCommunicator().allReduce(ekin, SynchronizerOperation::_sum);
 
   AKANTU_DEBUG_OUT();
   return ekin * .5;
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getKineticEnergy(const ElementType & type,
                                            UInt index) {
   AKANTU_DEBUG_IN();
 
   UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
 
   Array<Real> vel_on_quad(nb_quadrature_points, Model::spatial_dimension);
   Array<UInt> filter_element(1, 1, index);
 
   getFEEngine().interpolateOnIntegrationPoints(*velocity, vel_on_quad,
                                                Model::spatial_dimension, type,
                                                _not_ghost, filter_element);
 
-  Array<Real>::vector_iterator vit =
+  auto vit =
       vel_on_quad.begin(Model::spatial_dimension);
-  Array<Real>::vector_iterator vend = vel_on_quad.end(Model::spatial_dimension);
+  auto vend = vel_on_quad.end(Model::spatial_dimension);
 
   Vector<Real> rho_v2(nb_quadrature_points);
 
   Real rho = materials[material_index(type)(index)]->getRho();
 
   for (UInt q = 0; vit != vend; ++vit, ++q) {
     rho_v2(q) = rho * vit->dot(*vit);
   }
 
   AKANTU_DEBUG_OUT();
 
   return .5 * getFEEngine().integrate(rho_v2, type, index);
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getExternalWork() {
   AKANTU_DEBUG_IN();
 
   auto ext_force_it = external_force->begin(Model::spatial_dimension);
   auto int_force_it = internal_force->begin(Model::spatial_dimension);
   auto boun_it = blocked_dofs->begin(Model::spatial_dimension);
 
   decltype(ext_force_it) incr_or_velo_it;
   if (this->method == _static) {
     incr_or_velo_it =
         this->displacement_increment->begin(Model::spatial_dimension);
   } else {
     incr_or_velo_it = this->velocity->begin(Model::spatial_dimension);
   }
 
   Real work = 0.;
 
   UInt nb_nodes = this->mesh.getNbNodes();
 
   for (UInt n = 0; n < nb_nodes;
        ++n, ++ext_force_it, ++int_force_it, ++boun_it, ++incr_or_velo_it) {
     const auto & int_force = *int_force_it;
     const auto & ext_force = *ext_force_it;
     const auto & boun = *boun_it;
     const auto & incr_or_velo = *incr_or_velo_it;
 
     bool is_local_node = this->mesh.isLocalOrMasterNode(n);
     // bool is_not_pbc_slave_node = !this->isPBCSlaveNode(n);
     bool count_node = is_local_node; // && is_not_pbc_slave_node;
 
     if (count_node) {
       for (UInt i = 0; i < Model::spatial_dimension; ++i) {
         if (boun(i))
           work -= int_force(i) * incr_or_velo(i);
         else
           work += ext_force(i) * incr_or_velo(i);
       }
     }
   }
 
   mesh.getCommunicator().allReduce(work, SynchronizerOperation::_sum);
 
   if (this->method != _static)
     work *= this->getTimeStep();
 
   AKANTU_DEBUG_OUT();
   return work;
 }
 
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getEnergy(const std::string & energy_id) {
   AKANTU_DEBUG_IN();
 
   if (energy_id == "kinetic") {
     return getKineticEnergy();
   } else if (energy_id == "external work") {
     return getExternalWork();
   }
 
   Real energy = 0.;
   for (auto & material : materials)
     energy += material->getEnergy(energy_id);
 
   /// reduction sum over all processors
   mesh.getCommunicator().allReduce(energy, SynchronizerOperation::_sum);
 
   AKANTU_DEBUG_OUT();
   return energy;
 }
 /* -------------------------------------------------------------------------- */
 Real SolidMechanicsModel::getEnergy(const std::string & energy_id,
                                     const ElementType & type, UInt index) {
   AKANTU_DEBUG_IN();
 
   if (energy_id == "kinetic") {
     return getKineticEnergy(type, index);
   }
 
   UInt mat_index = this->material_index(type, _not_ghost)(index);
   UInt mat_loc_num = this->material_local_numbering(type, _not_ghost)(index);
   Real energy =
       this->materials[mat_index]->getEnergy(energy_id, type, mat_loc_num);
 
   AKANTU_DEBUG_OUT();
   return energy;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::onElementsAdded(const Array<Element> & element_list,
                                           const NewElementsEvent & event) {
   AKANTU_DEBUG_IN();
 
   this->material_index.initialize(mesh, _element_kind = _ek_not_defined,
                                   _with_nb_element = true,
                                   _default_value = UInt(-1));
   this->material_local_numbering.initialize(
       mesh, _element_kind = _ek_not_defined, _with_nb_element = true,
       _default_value = UInt(-1));
 
   ElementTypeMapArray<UInt> filter("new_element_filter", this->getID(),
                                    this->getMemoryID());
 
   for (auto & elem : element_list) {
     if (!filter.exists(elem.type, elem.ghost_type))
       filter.alloc(0, 1, elem.type, elem.ghost_type);
     filter(elem.type, elem.ghost_type).push_back(elem.element);
   }
 
   this->assignMaterialToElements(&filter);
 
   for (auto & material : materials)
     material->onElementsAdded(element_list, event);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::onElementsRemoved(
     const Array<Element> & element_list,
     const ElementTypeMapArray<UInt> & new_numbering,
     const RemovedElementsEvent & event) {
   for (auto & material : materials) {
     material->onElementsRemoved(element_list, new_numbering, event);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::onNodesAdded(const Array<UInt> & nodes_list,
                                        const NewNodesEvent & event) {
   AKANTU_DEBUG_IN();
   UInt nb_nodes = mesh.getNbNodes();
 
   if (displacement) {
     displacement->resize(nb_nodes, 0.);
     ++displacement_release;
   }
   if (mass)
     mass->resize(nb_nodes, 0.);
   if (velocity)
     velocity->resize(nb_nodes, 0.);
   if (acceleration)
     acceleration->resize(nb_nodes, 0.);
   if (external_force)
     external_force->resize(nb_nodes, 0.);
   if (internal_force)
     internal_force->resize(nb_nodes, 0.);
   if (blocked_dofs)
     blocked_dofs->resize(nb_nodes, 0.);
   if (current_position)
     current_position->resize(nb_nodes, 0.);
 
   if (previous_displacement)
     previous_displacement->resize(nb_nodes, 0.);
   if (displacement_increment)
     displacement_increment->resize(nb_nodes, 0.);
 
   for (auto & material : materials) {
     material->onNodesAdded(nodes_list, event);
   }
 
   need_to_reassemble_lumped_mass = true;
   need_to_reassemble_mass = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::onNodesRemoved(const Array<UInt> & /*element_list*/,
                                          const Array<UInt> & new_numbering,
                                          const RemovedNodesEvent & /*event*/) {
   if (displacement) {
     mesh.removeNodesFromArray(*displacement, new_numbering);
     ++displacement_release;
   }
   if (mass)
     mesh.removeNodesFromArray(*mass, new_numbering);
   if (velocity)
     mesh.removeNodesFromArray(*velocity, new_numbering);
   if (acceleration)
     mesh.removeNodesFromArray(*acceleration, new_numbering);
   if (internal_force)
     mesh.removeNodesFromArray(*internal_force, new_numbering);
   if (external_force)
     mesh.removeNodesFromArray(*external_force, new_numbering);
   if (blocked_dofs)
     mesh.removeNodesFromArray(*blocked_dofs, new_numbering);
 
   // if (increment_acceleration)
   //   mesh.removeNodesFromArray(*increment_acceleration, new_numbering);
   if (displacement_increment)
     mesh.removeNodesFromArray(*displacement_increment, new_numbering);
 
   if (previous_displacement)
     mesh.removeNodesFromArray(*previous_displacement, new_numbering);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "Solid Mechanics Model [" << std::endl;
   stream << space << " + id                : " << id << std::endl;
   stream << space << " + spatial dimension : " << Model::spatial_dimension
          << std::endl;
   stream << space << " + fem [" << std::endl;
   getFEEngine().printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
   stream << space << " + nodals information [" << std::endl;
   displacement->printself(stream, indent + 2);
   if (velocity)
     velocity->printself(stream, indent + 2);
   if (acceleration)
     acceleration->printself(stream, indent + 2);
   if (mass)
     mass->printself(stream, indent + 2);
   external_force->printself(stream, indent + 2);
   internal_force->printself(stream, indent + 2);
   blocked_dofs->printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << " + material information [" << std::endl;
   material_index.printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << " + materials [" << std::endl;
   for (auto & material : materials) {
     material->printself(stream, indent + 1);
   }
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::initializeNonLocal() {
   this->non_local_manager->synchronize(*this, _gst_material_id);
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::insertIntegrationPointsInNeighborhoods(
     const GhostType & ghost_type) {
   for (auto & mat : materials) {
     MaterialNonLocalInterface * mat_non_local;
     if ((mat_non_local =
              dynamic_cast<MaterialNonLocalInterface *>(mat.get())) == nullptr)
       continue;
 
     ElementTypeMapArray<Real> quadrature_points_coordinates(
         "quadrature_points_coordinates_tmp_nl", this->id, this->memory_id);
     quadrature_points_coordinates.initialize(this->getFEEngine(),
                                              _nb_component = spatial_dimension,
                                              _ghost_type = ghost_type);
 
     for (auto & type : quadrature_points_coordinates.elementTypes(
              Model::spatial_dimension, ghost_type)) {
       this->getFEEngine().computeIntegrationPointsCoordinates(
           quadrature_points_coordinates(type, ghost_type), type, ghost_type);
     }
 
     mat_non_local->initMaterialNonLocal();
 
     mat_non_local->insertIntegrationPointsInNeighborhoods(
         ghost_type, quadrature_points_coordinates);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::computeNonLocalStresses(
     const GhostType & ghost_type) {
   for (auto & mat : materials) {
     if (dynamic_cast<MaterialNonLocalInterface *>(mat.get()) == nullptr)
       continue;
 
     auto & mat_non_local = dynamic_cast<MaterialNonLocalInterface &>(*mat);
     mat_non_local.computeNonLocalStresses(ghost_type);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::updateLocalInternal(
     ElementTypeMapReal & internal_flat, const GhostType & ghost_type,
     const ElementKind & kind) {
   const ID field_name = internal_flat.getName();
   for (auto & material : materials) {
     if (material->isInternal<Real>(field_name, kind))
       material->flattenInternal(field_name, internal_flat, ghost_type, kind);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::updateNonLocalInternal(
     ElementTypeMapReal & internal_flat, const GhostType & ghost_type,
     const ElementKind & kind) {
 
   const ID field_name = internal_flat.getName();
 
   for (auto & mat : materials) {
     if (dynamic_cast<MaterialNonLocalInterface *>(mat.get()) == nullptr)
       continue;
 
     auto & mat_non_local = dynamic_cast<MaterialNonLocalInterface &>(*mat);
     mat_non_local.updateNonLocalInternals(internal_flat, field_name, ghost_type,
                                           kind);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 FEEngine & SolidMechanicsModel::getFEEngineBoundary(const ID & name) {
   return dynamic_cast<FEEngine &>(
       getFEEngineClassBoundary<MyFEEngineType>(name));
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::splitElementByMaterial(
     const Array<Element> & elements,
     std::vector<Array<Element>> & elements_per_mat) const {
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   const Array<UInt> * mat_indexes = nullptr;
   const Array<UInt> * mat_loc_num = nullptr;
 
   for (const auto & el : elements) {
     if (el.type != current_element_type ||
         el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type = el.ghost_type;
       mat_indexes = &(this->material_index(el.type, el.ghost_type));
       mat_loc_num = &(this->material_local_numbering(el.type, el.ghost_type));
     }
 
     Element mat_el = el;
 
     mat_el.element = (*mat_loc_num)(el.element);
     elements_per_mat[(*mat_indexes)(el.element)].push_back(mat_el);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModel::getNbData(const Array<Element> & elements,
                                     const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   UInt nb_nodes_per_element = 0;
 
   for (const Element & el : elements) {
     nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
   }
 
   switch (tag) {
   case _gst_material_id: {
     size += elements.size() * sizeof(UInt);
     break;
   }
   case _gst_smm_mass: {
     size += nb_nodes_per_element * sizeof(Real) *
             Model::spatial_dimension; // mass vector
     break;
   }
   case _gst_smm_for_gradu: {
     size += nb_nodes_per_element * Model::spatial_dimension *
             sizeof(Real); // displacement
     break;
   }
   case _gst_smm_boundary: {
     // force, displacement, boundary
     size += nb_nodes_per_element * Model::spatial_dimension *
             (2 * sizeof(Real) + sizeof(bool));
     break;
   }
   case _gst_for_dump: {
     // displacement, velocity, acceleration, residual, force
     size += nb_nodes_per_element * Model::spatial_dimension * sizeof(Real) * 5;
     break;
   }
   default: {}
   }
 
   if (tag != _gst_material_id) {
     splitByMaterial(elements, [&](auto && mat, auto && elements) {
       size += mat.getNbData(elements, tag);
     });
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::packData(CommunicationBuffer & buffer,
                                    const Array<Element> & elements,
                                    const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   switch (tag) {
   case _gst_material_id: {
     this->packElementalDataHelper(material_index, buffer, elements, false,
                                   getFEEngine());
     break;
   }
   case _gst_smm_mass: {
     packNodalDataHelper(*mass, buffer, elements, mesh);
     break;
   }
   case _gst_smm_for_gradu: {
     packNodalDataHelper(*displacement, buffer, elements, mesh);
     break;
   }
   case _gst_for_dump: {
     packNodalDataHelper(*displacement, buffer, elements, mesh);
     packNodalDataHelper(*velocity, buffer, elements, mesh);
     packNodalDataHelper(*acceleration, buffer, elements, mesh);
     packNodalDataHelper(*internal_force, buffer, elements, mesh);
     packNodalDataHelper(*external_force, buffer, elements, mesh);
     break;
   }
   case _gst_smm_boundary: {
     packNodalDataHelper(*external_force, buffer, elements, mesh);
     packNodalDataHelper(*velocity, buffer, elements, mesh);
     packNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
     break;
   }
   default: {}
   }
 
   if (tag != _gst_material_id) {
     splitByMaterial(elements, [&](auto && mat, auto && elements) {
       mat.packData(buffer, elements, tag);
     });
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::unpackData(CommunicationBuffer & buffer,
                                      const Array<Element> & elements,
                                      const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   switch (tag) {
   case _gst_material_id: {
     for (auto && element : elements) {
       UInt recv_mat_index;
       buffer >> recv_mat_index;
       UInt & mat_index = material_index(element);
       if (mat_index != UInt(-1))
         continue;
 
       // add ghosts element to the correct material
       mat_index = recv_mat_index;
       UInt index = materials[mat_index]->addElement(element);
       material_local_numbering(element) = index;
     }
     break;
   }
   case _gst_smm_mass: {
     unpackNodalDataHelper(*mass, buffer, elements, mesh);
     break;
   }
   case _gst_smm_for_gradu: {
     unpackNodalDataHelper(*displacement, buffer, elements, mesh);
     break;
   }
   case _gst_for_dump: {
     unpackNodalDataHelper(*displacement, buffer, elements, mesh);
     unpackNodalDataHelper(*velocity, buffer, elements, mesh);
     unpackNodalDataHelper(*acceleration, buffer, elements, mesh);
     unpackNodalDataHelper(*internal_force, buffer, elements, mesh);
     unpackNodalDataHelper(*external_force, buffer, elements, mesh);
     break;
   }
   case _gst_smm_boundary: {
     unpackNodalDataHelper(*external_force, buffer, elements, mesh);
     unpackNodalDataHelper(*velocity, buffer, elements, mesh);
     unpackNodalDataHelper(*blocked_dofs, buffer, elements, mesh);
     break;
   }
   default: {}
   }
 
   if (tag != _gst_material_id) {
     splitByMaterial(elements, [&](auto && mat, auto && elements) {
       mat.unpackData(buffer, elements, tag);
     });
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt SolidMechanicsModel::getNbData(const Array<UInt> & dofs,
                                     const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   //  UInt nb_nodes = mesh.getNbNodes();
 
   switch (tag) {
   case _gst_smm_uv: {
     size += sizeof(Real) * Model::spatial_dimension * 2;
     break;
   }
   case _gst_smm_res: {
     size += sizeof(Real) * Model::spatial_dimension;
     break;
   }
   case _gst_smm_mass: {
     size += sizeof(Real) * Model::spatial_dimension;
     break;
   }
   case _gst_for_dump: {
     size += sizeof(Real) * Model::spatial_dimension * 5;
     break;
   }
   default: {
     AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
   return size * dofs.size();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::packData(CommunicationBuffer & buffer,
                                    const Array<UInt> & dofs,
                                    const SynchronizationTag & tag) const {
   AKANTU_DEBUG_IN();
 
   switch (tag) {
   case _gst_smm_uv: {
     packDOFDataHelper(*displacement, buffer, dofs);
     packDOFDataHelper(*velocity, buffer, dofs);
     break;
   }
   case _gst_smm_res: {
     packDOFDataHelper(*internal_force, buffer, dofs);
     break;
   }
   case _gst_smm_mass: {
     packDOFDataHelper(*mass, buffer, dofs);
     break;
   }
   case _gst_for_dump: {
     packDOFDataHelper(*displacement, buffer, dofs);
     packDOFDataHelper(*velocity, buffer, dofs);
     packDOFDataHelper(*acceleration, buffer, dofs);
     packDOFDataHelper(*internal_force, buffer, dofs);
     packDOFDataHelper(*external_force, buffer, dofs);
     break;
   }
   default: {
     AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void SolidMechanicsModel::unpackData(CommunicationBuffer & buffer,
                                      const Array<UInt> & dofs,
                                      const SynchronizationTag & tag) {
   AKANTU_DEBUG_IN();
 
   switch (tag) {
   case _gst_smm_uv: {
     unpackDOFDataHelper(*displacement, buffer, dofs);
     unpackDOFDataHelper(*velocity, buffer, dofs);
     break;
   }
   case _gst_smm_res: {
     unpackDOFDataHelper(*internal_force, buffer, dofs);
     break;
   }
   case _gst_smm_mass: {
     unpackDOFDataHelper(*mass, buffer, dofs);
     break;
   }
   case _gst_for_dump: {
     unpackDOFDataHelper(*displacement, buffer, dofs);
     unpackDOFDataHelper(*velocity, buffer, dofs);
     unpackDOFDataHelper(*acceleration, buffer, dofs);
     unpackDOFDataHelper(*internal_force, buffer, dofs);
     unpackDOFDataHelper(*external_force, buffer, dofs);
     break;
   }
   default: {
     AKANTU_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
index 3a3ff1816..acf03716c 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/fragment_manager.cc
@@ -1,615 +1,615 @@
 /**
  * @file   fragment_manager.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Thu Jan 23 2014
  * @date last modification: Mon Dec 14 2015
  *
  * @brief  Group manager to handle fragments
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "fragment_manager.hh"
 #include "aka_iterators.hh"
 #include "material_cohesive.hh"
 #include "mesh_iterators.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <functional>
 #include <numeric>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 FragmentManager::FragmentManager(SolidMechanicsModelCohesive & model,
                                  bool dump_data, const ID & id,
                                  const MemoryID & memory_id)
     : GroupManager(model.getMesh(), id, memory_id), model(model),
       mass_center(0, model.getSpatialDimension(), "mass_center"),
       mass(0, model.getSpatialDimension(), "mass"),
       velocity(0, model.getSpatialDimension(), "velocity"),
       inertia_moments(0, model.getSpatialDimension(), "inertia_moments"),
       principal_directions(
           0, model.getSpatialDimension() * model.getSpatialDimension(),
           "principal_directions"),
       quad_coordinates("quad_coordinates", id),
       mass_density("mass_density", id),
       nb_elements_per_fragment(0, 1, "nb_elements_per_fragment"),
       dump_data(dump_data) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   /// compute quadrature points' coordinates
   quad_coordinates.initialize(mesh, _nb_component = spatial_dimension,
                               _spatial_dimension = spatial_dimension,
                               _ghost_type = _not_ghost);
   // mesh.initElementTypeMapArray(quad_coordinates, spatial_dimension,
   //                              spatial_dimension, _not_ghost);
 
   model.getFEEngine().interpolateOnIntegrationPoints(model.getMesh().getNodes(),
                                                      quad_coordinates);
 
   /// store mass density per quadrature point
   mass_density.initialize(mesh, _spatial_dimension = spatial_dimension,
                           _ghost_type = _not_ghost);
   // mesh.initElementTypeMapArray(mass_density, 1, spatial_dimension,
   // _not_ghost);
 
   storeMassDensityPerIntegrationPoint();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 class CohesiveElementFilter : public GroupManager::ClusteringFilter {
 public:
   CohesiveElementFilter(const SolidMechanicsModelCohesive & model,
                         const Real max_damage = 1.)
       : model(model), is_unbroken(max_damage) {}
 
   bool operator()(const Element & el) const override {
     if (Mesh::getKind(el.type) == _ek_regular)
       return true;
 
     const Array<UInt> & mat_indexes =
         model.getMaterialByElement(el.type, el.ghost_type);
     const Array<UInt> & mat_loc_num =
         model.getMaterialLocalNumbering(el.type, el.ghost_type);
 
     const auto & mat = static_cast<const MaterialCohesive &>(
         model.getMaterial(mat_indexes(el.element)));
 
     UInt el_index = mat_loc_num(el.element);
     UInt nb_quad_per_element =
         model.getFEEngine("CohesiveFEEngine")
             .getNbIntegrationPoints(el.type, el.ghost_type);
 
     const Array<Real> & damage_array = mat.getDamage(el.type, el.ghost_type);
 
     AKANTU_DEBUG_ASSERT(nb_quad_per_element * el_index < damage_array.size(),
                         "This quadrature point is out of range");
 
     const Real * element_damage =
         damage_array.storage() + nb_quad_per_element * el_index;
 
     UInt unbroken_quads = std::count_if(
         element_damage, element_damage + nb_quad_per_element, is_unbroken);
 
     if (unbroken_quads > 0)
       return true;
     return false;
   }
 
 private:
   struct IsUnbrokenFunctor {
     IsUnbrokenFunctor(const Real & max_damage) : max_damage(max_damage) {}
     bool operator()(const Real & x) { return x < max_damage; }
     const Real max_damage;
   };
 
   const SolidMechanicsModelCohesive & model;
   const IsUnbrokenFunctor is_unbroken;
 };
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::buildFragments(Real damage_limit) {
   AKANTU_DEBUG_IN();
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   ElementSynchronizer * cohesive_synchronizer =
       const_cast<ElementSynchronizer *>(model.getCohesiveSynchronizer());
 
   if (cohesive_synchronizer) {
     cohesive_synchronizer->computeBufferSize(model, _gst_smmc_damage);
     cohesive_synchronizer->asynchronousSynchronize(model, _gst_smmc_damage);
     cohesive_synchronizer->waitEndSynchronize(model, _gst_smmc_damage);
   }
 #endif
 
   auto & mesh_facets = const_cast<Mesh &>(mesh.getMeshFacets());
 
   UInt spatial_dimension = model.getSpatialDimension();
   std::string fragment_prefix("fragment");
 
   /// generate fragments
   global_nb_fragment =
       createClusters(spatial_dimension, mesh_facets, fragment_prefix,
                      CohesiveElementFilter(model, damage_limit));
 
   nb_fragment = getNbElementGroups(spatial_dimension);
   fragment_index.resize(nb_fragment);
 
   UInt * fragment_index_it = fragment_index.storage();
 
   /// loop over fragments
   for (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it, ++fragment_index_it) {
 
     /// get fragment index
     std::string fragment_index_string =
         it->first.substr(fragment_prefix.size() + 1);
     std::stringstream sstr(fragment_index_string.c_str());
     sstr >> *fragment_index_it;
 
     AKANTU_DEBUG_ASSERT(!sstr.fail(), "fragment_index is not an integer");
   }
 
   /// compute fragments' mass
   computeMass();
 
   if (dump_data) {
     createDumpDataArray(fragment_index, "fragments", true);
     createDumpDataArray(mass, "fragments mass");
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeMass() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   /// create a unit field per quadrature point, since to compute mass
   /// it's neccessary to integrate only density
   ElementTypeMapArray<Real> unit_field("unit_field", id);
   unit_field.initialize(model.getFEEngine(), _nb_component = spatial_dimension,
                         _spatial_dimension = spatial_dimension,
                         _ghost_type = _not_ghost, _default_value = 1.);
   // mesh.initElementTypeMapArray(unit_field, spatial_dimension,
   // spatial_dimension,
   //                              _not_ghost);
 
   // ElementTypeMapArray<Real>::type_iterator it =
   //     unit_field.firstType(spatial_dimension, _not_ghost, _ek_regular);
   // ElementTypeMapArray<Real>::type_iterator end =
   //     unit_field.lastType(spatial_dimension, _not_ghost, _ek_regular);
 
   // for (; it != end; ++it) {
   //   ElementType type = *it;
   //   Array<Real> & field_array = unit_field(type);
   //   UInt nb_element = mesh.getNbElement(type);
   //   UInt nb_quad_per_element =
   //   model.getFEEngine().getNbIntegrationPoints(type);
 
   //   field_array.resize(nb_element * nb_quad_per_element);
   //   field_array.set(1.);
   // }
 
   integrateFieldOnFragments(unit_field, mass);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeCenterOfMass() {
   AKANTU_DEBUG_IN();
 
   /// integrate position multiplied by density
   integrateFieldOnFragments(quad_coordinates, mass_center);
 
   /// divide it by the fragments' mass
   Real * mass_storage = mass.storage();
   Real * mass_center_storage = mass_center.storage();
 
   UInt total_components = mass_center.size() * mass_center.getNbComponent();
 
   for (UInt i = 0; i < total_components; ++i)
     mass_center_storage[i] /= mass_storage[i];
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeVelocity() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   /// compute velocity per quadrature point
   ElementTypeMapArray<Real> velocity_field("velocity_field", id);
   velocity_field.initialize(
       model.getFEEngine(), _nb_component = spatial_dimension,
       _spatial_dimension = spatial_dimension, _ghost_type = _not_ghost);
 
   // mesh.initElementTypeMapArray(velocity_field, spatial_dimension,
   //                              spatial_dimension, _not_ghost);
 
   model.getFEEngine().interpolateOnIntegrationPoints(model.getVelocity(),
                                                      velocity_field);
 
   /// integrate on fragments
   integrateFieldOnFragments(velocity_field, velocity);
 
   /// divide it by the fragments' mass
   Real * mass_storage = mass.storage();
   Real * velocity_storage = velocity.storage();
 
   UInt total_components = velocity.size() * velocity.getNbComponent();
 
   for (UInt i = 0; i < total_components; ++i)
     velocity_storage[i] /= mass_storage[i];
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Given the distance @f$ \mathbf{r} @f$ between a quadrature point
  * and its center of mass, the moment of inertia is computed as \f[
  * I_\mathrm{CM} = \mathrm{tr}(\mathbf{r}\mathbf{r}^\mathrm{T})
  * \mathbf{I} - \mathbf{r}\mathbf{r}^\mathrm{T} \f] for more
  * information check Wikipedia
  * (http://en.wikipedia.org/wiki/Moment_of_inertia#Identities_for_a_skew-symmetric_matrix)
  *
  */
 
 void FragmentManager::computeInertiaMoments() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   computeCenterOfMass();
 
   /// compute local coordinates products with respect to the center of match
   ElementTypeMapArray<Real> moments_coords("moments_coords", id);
   moments_coords.initialize(model.getFEEngine(),
                             _nb_component =
                                 spatial_dimension * spatial_dimension,
                             _spatial_dimension = spatial_dimension,
                             _ghost_type = _not_ghost, _default_value = 1.);
 
   // mesh.initElementTypeMapArray(moments_coords,
   //                              spatial_dimension * spatial_dimension,
   //                              spatial_dimension, _not_ghost);
 
   // /// resize the by element type
   // ElementTypeMapArray<Real>::type_iterator it =
   //     moments_coords.firstType(spatial_dimension, _not_ghost, _ek_regular);
   // ElementTypeMapArray<Real>::type_iterator end =
   //     moments_coords.lastType(spatial_dimension, _not_ghost, _ek_regular);
 
   // for (; it != end; ++it) {
   //   ElementType type = *it;
   //   Array<Real> & field_array = moments_coords(type);
   //   UInt nb_element = mesh.getNbElement(type);
   //   UInt nb_quad_per_element =
   //   model.getFEEngine().getNbIntegrationPoints(type);
 
   //   field_array.resize(nb_element * nb_quad_per_element);
   // }
 
   /// compute coordinates
-  Array<Real>::const_vector_iterator mass_center_it =
+  auto mass_center_it =
       mass_center.begin(spatial_dimension);
 
   /// loop over fragments
   for (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it, ++mass_center_it) {
 
     const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
     /// loop over elements of the fragment
     for (auto type :
          el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
       UInt nb_quad_per_element =
           model.getFEEngine().getNbIntegrationPoints(type);
 
       Array<Real> & moments_coords_array = moments_coords(type);
       const Array<Real> & quad_coordinates_array = quad_coordinates(type);
       const Array<UInt> & el_list_array = el_list(type);
 
       Array<Real>::matrix_iterator moments_begin =
           moments_coords_array.begin(spatial_dimension, spatial_dimension);
-      Array<Real>::const_vector_iterator quad_coordinates_begin =
+      auto quad_coordinates_begin =
           quad_coordinates_array.begin(spatial_dimension);
 
       Vector<Real> relative_coords(spatial_dimension);
 
       for (UInt el = 0; el < el_list_array.size(); ++el) {
         UInt global_el = el_list_array(el);
 
         /// loop over quadrature points
         for (UInt q = 0; q < nb_quad_per_element; ++q) {
           UInt global_q = global_el * nb_quad_per_element + q;
           Matrix<Real> moments_matrix = moments_begin[global_q];
           const Vector<Real> & quad_coord_vector =
               quad_coordinates_begin[global_q];
 
           /// to understand this read the documentation written just
           /// before this function
           relative_coords = quad_coord_vector;
           relative_coords -= *mass_center_it;
 
           moments_matrix.outerProduct(relative_coords, relative_coords);
           Real trace = moments_matrix.trace();
           moments_matrix *= -1.;
           moments_matrix += Matrix<Real>::eye(spatial_dimension, trace);
         }
       }
     }
   }
 
   /// integrate moments
   Array<Real> integrated_moments(global_nb_fragment,
                                  spatial_dimension * spatial_dimension);
 
   integrateFieldOnFragments(moments_coords, integrated_moments);
 
   /// compute and store principal moments
   inertia_moments.resize(global_nb_fragment);
   principal_directions.resize(global_nb_fragment);
 
   Array<Real>::matrix_iterator integrated_moments_it =
       integrated_moments.begin(spatial_dimension, spatial_dimension);
-  Array<Real>::vector_iterator inertia_moments_it =
+  auto inertia_moments_it =
       inertia_moments.begin(spatial_dimension);
   Array<Real>::matrix_iterator principal_directions_it =
       principal_directions.begin(spatial_dimension, spatial_dimension);
 
   for (UInt frag = 0; frag < global_nb_fragment; ++frag,
             ++integrated_moments_it, ++inertia_moments_it,
             ++principal_directions_it) {
     integrated_moments_it->eig(*inertia_moments_it, *principal_directions_it);
   }
 
   if (dump_data)
     createDumpDataArray(inertia_moments, "moments of inertia");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeAllData() {
   AKANTU_DEBUG_IN();
 
   buildFragments();
   computeVelocity();
   computeInertiaMoments();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::storeMassDensityPerIntegrationPoint() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
 
   Mesh::type_iterator it = mesh.firstType(spatial_dimension);
   Mesh::type_iterator end = mesh.lastType(spatial_dimension);
 
   for (; it != end; ++it) {
     ElementType type = *it;
 
     Array<Real> & mass_density_array = mass_density(type);
 
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
     mass_density_array.resize(nb_element * nb_quad_per_element);
 
     const Array<UInt> & mat_indexes = model.getMaterialByElement(type);
 
     Real * mass_density_it = mass_density_array.storage();
 
     /// store mass_density for each element and quadrature point
     for (UInt el = 0; el < nb_element; ++el) {
       Material & mat = model.getMaterial(mat_indexes(el));
 
       for (UInt q = 0; q < nb_quad_per_element; ++q, ++mass_density_it)
         *mass_density_it = mat.getRho();
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::integrateFieldOnFragments(
     ElementTypeMapArray<Real> & field, Array<Real> & output) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
   UInt nb_component = output.getNbComponent();
 
   /// integration part
   output.resize(global_nb_fragment);
   output.clear();
 
   UInt * fragment_index_it = fragment_index.storage();
-  Array<Real>::vector_iterator output_begin = output.begin(nb_component);
+  auto output_begin = output.begin(nb_component);
 
   /// loop over fragments
   for (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it, ++fragment_index_it) {
 
     const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
 
     /// loop over elements of the fragment
     for (auto type :
          el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
 
       UInt nb_quad_per_element =
           model.getFEEngine().getNbIntegrationPoints(type);
 
       const Array<Real> & density_array = mass_density(type);
       Array<Real> & field_array = field(type);
       const Array<UInt> & elements = el_list(type);
       UInt nb_element = elements.size();
 
       /// generate array to be integrated by filtering fragment's elements
       Array<Real> integration_array(elements.size() * nb_quad_per_element,
                                     nb_component);
 
       Array<Real>::matrix_iterator int_array_it =
           integration_array.begin_reinterpret(nb_quad_per_element, nb_component,
                                               nb_element);
       Array<Real>::matrix_iterator int_array_end =
           integration_array.end_reinterpret(nb_quad_per_element, nb_component,
                                             nb_element);
       Array<Real>::matrix_iterator field_array_begin =
           field_array.begin_reinterpret(nb_quad_per_element, nb_component,
                                         field_array.size() /
                                             nb_quad_per_element);
-      Array<Real>::const_vector_iterator density_array_begin =
+      auto density_array_begin =
           density_array.begin_reinterpret(nb_quad_per_element,
                                           density_array.size() /
                                               nb_quad_per_element);
 
       for (UInt el = 0; int_array_it != int_array_end; ++int_array_it, ++el) {
         UInt global_el = elements(el);
         *int_array_it = field_array_begin[global_el];
 
         /// multiply field by density
         const Vector<Real> & density_vector = density_array_begin[global_el];
 
         for (UInt i = 0; i < nb_quad_per_element; ++i) {
           for (UInt j = 0; j < nb_component; ++j) {
             (*int_array_it)(i, j) *= density_vector(i);
           }
         }
       }
 
       /// integrate the field over the fragment
       Array<Real> integrated_array(elements.size(), nb_component);
       model.getFEEngine().integrate(integration_array, integrated_array,
                                     nb_component, type, _not_ghost, elements);
 
       /// sum over all elements and store the result
       Vector<Real> output_tmp(output_begin[*fragment_index_it]);
       output_tmp += std::accumulate(integrated_array.begin(nb_component),
                                     integrated_array.end(nb_component),
                                     Vector<Real>(nb_component));
     }
   }
 
   /// sum output over all processors
   const Communicator & comm = mesh.getCommunicator();
   comm.allReduce(output, SynchronizerOperation::_sum);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void FragmentManager::computeNbElementsPerFragment() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = model.getSpatialDimension();
   nb_elements_per_fragment.resize(global_nb_fragment);
   nb_elements_per_fragment.clear();
 
   UInt * fragment_index_it = fragment_index.storage();
 
   /// loop over fragments
   for (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it, ++fragment_index_it) {
 
     const ElementTypeMapArray<UInt> & el_list = it->second->getElements();
 
     /// loop over elements of the fragment
     for (auto type :
          el_list.elementTypes(spatial_dimension, _not_ghost, _ek_regular)) {
       UInt nb_element = el_list(type).size();
 
       nb_elements_per_fragment(*fragment_index_it) += nb_element;
     }
   }
 
   /// sum values over all processors
   const auto & comm = mesh.getCommunicator();
   comm.allReduce(nb_elements_per_fragment, SynchronizerOperation::_sum);
 
   if (dump_data)
     createDumpDataArray(nb_elements_per_fragment, "elements per fragment");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void FragmentManager::createDumpDataArray(Array<T> & data, std::string name,
                                           bool fragment_index_output) {
   AKANTU_DEBUG_IN();
 
   if (data.size() == 0)
     return;
 
   auto & mesh_not_const = const_cast<Mesh &>(mesh);
 
   auto && spatial_dimension = mesh.getSpatialDimension();
   auto && nb_component = data.getNbComponent();
   auto && data_begin = data.begin(nb_component);
   auto fragment_index_it = fragment_index.begin();
 
   /// loop over fragments
   for (const auto & fragment : ElementGroupsIterable(*this)) {
     const auto & fragment_idx = *fragment_index_it;
 
     /// loop over cluster types
     for (auto & type : fragment.elementTypes(spatial_dimension)) {
       /// init mesh data
       auto & mesh_data = mesh_not_const.getDataPointer<T>(
           name, type, _not_ghost, nb_component);
 
       auto mesh_data_begin = mesh_data.begin(nb_component);
 
       /// fill mesh data
       for (const auto & elem : fragment.getElements(type)) {
         Vector<T> md_tmp = mesh_data_begin[elem];
         if (fragment_index_output) {
           md_tmp(0) = fragment_idx;
         } else {
           md_tmp = data_begin[fragment_idx];
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_bilinear.cc
index 5e3d137d6..1c936b9c7 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,219 +1,219 @@
 /**
  * @file   material_cohesive_bilinear.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Feb 22 2012
  * @date last modification: Thu Oct 15 2015
  *
  * @brief  Bilinear cohesive constitutive law
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_bilinear.hh"
 //#include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveBilinear<spatial_dimension>::MaterialCohesiveBilinear(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesiveLinear<spatial_dimension>(model, id) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("delta_0", delta_0, Real(0.),
                       _pat_parsable | _pat_readable,
                       "Elastic limit displacement");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   this->sigma_c_eff.setRandomDistribution(this->sigma_c.getRandomParameter());
   MaterialCohesiveLinear<spatial_dimension>::initMaterial();
 
   this->delta_max.setDefaultValue(delta_0);
   this->insertion_stress.setDefaultValue(0);
 
   this->delta_max.reset();
   this->insertion_stress.reset();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::onElementsAdded(
     const Array<Element> & element_list, const NewElementsEvent & event) {
   AKANTU_DEBUG_IN();
 
   MaterialCohesiveLinear<spatial_dimension>::onElementsAdded(element_list,
                                                              event);
 
   bool scale_traction = false;
 
   // don't scale sigma_c if volume_s hasn't been specified by the user
   if (!Math::are_float_equal(this->volume_s, 0.))
     scale_traction = true;
 
   Array<Element>::const_scalar_iterator el_it = element_list.begin();
   Array<Element>::const_scalar_iterator el_end = element_list.end();
 
   for (; el_it != el_end; ++el_it) {
     // filter not ghost cohesive elements
     if (el_it->ghost_type != _not_ghost ||
         Mesh::getKind(el_it->type) != _ek_cohesive)
       continue;
 
     UInt index = el_it->element;
     ElementType type = el_it->type;
     UInt nb_element = this->model->getMesh().getNbElement(type);
     UInt nb_quad_per_element = this->fem_cohesive.getNbIntegrationPoints(type);
 
-    Array<Real>::vector_iterator sigma_c_begin =
+    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];
 
-    Array<Real>::vector_iterator delta_c_begin =
+    auto delta_c_begin =
         this->delta_c_eff(type).begin_reinterpret(nb_quad_per_element,
                                                   nb_element);
     Vector<Real> delta_c_vec = delta_c_begin[index];
 
     if (scale_traction)
       scaleTraction(*el_it, sigma_c_vec);
 
     /**
      * Recompute sigma_c as
      * @f$ {\sigma_c}_\textup{new} =
      * \frac{{\sigma_c}_\textup{old} \delta_c} {\delta_c - \delta_0} @f$
      */
 
     for (UInt q = 0; q < nb_quad_per_element; ++q) {
       delta_c_vec(q) = 2 * this->G_c / sigma_c_vec(q);
 
       if (delta_c_vec(q) - delta_0 < Math::getTolerance())
         AKANTU_ERROR("delta_0 = "
                            << delta_0 << " must be lower than delta_c = "
                            << delta_c_vec(q) << ", modify your material file");
 
       sigma_c_vec(q) *= delta_c_vec(q) / (delta_c_vec(q) - delta_0);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::scaleTraction(
     const Element & el, Vector<Real> & sigma_c_vec) {
   AKANTU_DEBUG_IN();
 
   Real base_sigma_c = this->sigma_c_eff;
 
   const Mesh & mesh_facets = this->model->getMeshFacets();
   const FEEngine & fe_engine = this->model->getFEEngine();
 
   auto coh_element_to_facet_begin =
       mesh_facets.getSubelementToElement(el.type).begin(2);
   const Vector<Element> & coh_element_to_facet =
       coh_element_to_facet_begin[el.element];
 
   // compute bounding volume
   Real volume = 0;
 
   // loop over facets
   for (UInt f = 0; f < 2; ++f) {
     const Element & facet = coh_element_to_facet(f);
 
     const Array<std::vector<Element>> & facet_to_element =
         mesh_facets.getElementToSubelement(facet.type, facet.ghost_type);
 
     const std::vector<Element> & element_list = facet_to_element(facet.element);
 
     auto elem = element_list.begin();
     auto elem_end = element_list.end();
 
     // loop over elements connected to each facet
     for (; elem != elem_end; ++elem) {
       // skip cohesive elements and dummy elements
       if (*elem == ElementNull || Mesh::getKind(elem->type) == _ek_cohesive)
         continue;
 
       // unit vector for integration in order to obtain the volume
       UInt nb_quadrature_points = fe_engine.getNbIntegrationPoints(elem->type);
       Vector<Real> unit_vector(nb_quadrature_points, 1);
 
       volume += fe_engine.integrate(unit_vector, elem->type, elem->element,
                                     elem->ghost_type);
     }
   }
 
   // scale sigma_c
   sigma_c_vec -= base_sigma_c;
   sigma_c_vec *= std::pow(this->volume_s / volume, 1. / this->m_s);
   sigma_c_vec += base_sigma_c;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveBilinear<spatial_dimension>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   MaterialCohesiveLinear<spatial_dimension>::computeTraction(normal, el_type,
                                                              ghost_type);
 
   // adjust damage
   Array<Real>::scalar_iterator delta_c_it =
       this->delta_c_eff(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator delta_max_it =
       this->delta_max(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator damage_it =
       this->damage(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator damage_end =
       this->damage(el_type, ghost_type).end();
 
   for (; damage_it != damage_end; ++damage_it, ++delta_max_it, ++delta_c_it) {
     *damage_it =
         std::max((*delta_max_it - delta_0) / (*delta_c_it - delta_0), Real(0.));
     *damage_it = std::min(*damage_it, Real(1.));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_bilinear, MaterialCohesiveBilinear);
 
 } // namespace akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_exponential.cc
index ff2e48708..010024676 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,358 +1,358 @@
 /**
  * @file   material_cohesive_exponential.cc
  *
  * @author Seyedeh Mohadeseh Taheri Mousavi <mohadeseh.taherimousavi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Mon Jul 09 2012
  * @date last modification: Tue Aug 04 2015
  *
  * @brief  Exponential irreversible cohesive law of mixed mode loading
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_exponential.hh"
 #include "dof_synchronizer.hh"
 #include "solid_mechanics_model.hh"
 #include "sparse_matrix.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveExponential<spatial_dimension>::MaterialCohesiveExponential(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesive(model, id) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("beta", beta, Real(0.), _pat_parsable, "Beta parameter");
 
   this->registerParam("exponential_penalty", exp_penalty, true, _pat_parsable,
                       "Is contact penalty following the exponential law?");
 
   this->registerParam(
       "contact_tangent", contact_tangent, Real(1.0), _pat_parsable,
       "Ratio of contact tangent over the initial exponential tangent");
 
   // this->initInternalArray(delta_max, 1, _ek_cohesive);
 
   use_previous_delta_max = true;
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::initMaterial() {
 
   AKANTU_DEBUG_IN();
   MaterialCohesive::initMaterial();
 
   if ((exp_penalty) && (contact_tangent != 1)) {
 
     contact_tangent = 1;
     AKANTU_DEBUG_WARNING("The parsed paramter <contact_tangent> is forced to "
                          "1.0 when the contact penalty follows the exponential "
                          "law");
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
-  Array<Real>::vector_iterator traction_it =
+  auto traction_it =
       tractions(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::vector_iterator opening_it =
+  auto opening_it =
       opening(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::const_vector_iterator normal_it =
+  auto normal_it =
       normal.begin(spatial_dimension);
 
-  Array<Real>::vector_iterator traction_end =
+  auto traction_end =
       tractions(el_type, ghost_type).end(spatial_dimension);
 
-  Array<Real>::iterator<Real> delta_max_it =
+  auto delta_max_it =
       delta_max(el_type, ghost_type).begin();
 
-  Array<Real>::iterator<Real> delta_max_prev_it =
+  auto delta_max_prev_it =
       delta_max.previous(el_type, ghost_type).begin();
 
   /// compute scalars
   Real beta2 = beta * beta;
 
   /// loop on each quadrature point
   for (; traction_it != traction_end; ++traction_it, ++opening_it, ++normal_it,
                                       ++delta_max_it, ++delta_max_prev_it) {
 
     /// compute normal and tangential opening vectors
     Real normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening(spatial_dimension);
     normal_opening = (*normal_it);
     normal_opening *= normal_opening_norm;
 
     Vector<Real> tangential_opening(spatial_dimension);
     tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
 
     Real tangential_opening_norm = tangential_opening.norm();
 
     /**
      * compute effective opening displacement
      * @f$ \delta = \sqrt{
      * \beta^2 \Delta_t^2 + \Delta_n^2 } @f$
      */
     Real delta = tangential_opening_norm;
     delta *= delta * beta2;
     delta += normal_opening_norm * normal_opening_norm;
 
     delta = sqrt(delta);
 
     if ((normal_opening_norm < 0) &&
         (std::abs(normal_opening_norm) > Math::getTolerance())) {
 
       Vector<Real> op_n(*normal_it);
       op_n *= normal_opening_norm;
       Vector<Real> delta_s(*opening_it);
       delta_s -= op_n;
       delta = tangential_opening_norm * beta;
 
       computeCoupledTraction(*traction_it, *normal_it, delta, delta_s,
                              *delta_max_it, *delta_max_prev_it);
 
       computeCompressiveTraction(*traction_it, *normal_it, normal_opening_norm,
                                  *opening_it);
 
     } else
       computeCoupledTraction(*traction_it, *normal_it, delta, *opening_it,
                              *delta_max_it, *delta_max_prev_it);
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTraction(
     Vector<Real> & tract, const Vector<Real> & normal, Real delta,
     const Vector<Real> & opening, Real & delta_max_new, Real delta_max) {
   AKANTU_DEBUG_IN();
 
   /// full damage case
   if (std::abs(delta) < Math::getTolerance()) {
     /// set traction to zero
     tract.clear();
   } else { /// element not fully damaged
     /**
      * Compute traction loading @f$ \mathbf{T} =
      * e \sigma_c \frac{\delta}{\delta_c} e^{-\delta/ \delta_c}@f$
      */
     /**
      * Compute traction unloading @f$ \mathbf{T} =
      *  \frac{t_{max}}{\delta_{max}} \delta @f$
      */
     Real beta2 = beta * beta;
     Real normal_open_norm = opening.dot(normal);
     Vector<Real> op_n_n(spatial_dimension);
     op_n_n = normal;
     op_n_n *= (1 - beta2);
     op_n_n *= normal_open_norm;
     tract = beta2 * opening;
     tract += op_n_n;
 
     delta_max_new = std::max(delta_max, delta);
     tract *= exp(1) * sigma_c * exp(-delta_max_new / delta_c) / delta_c;
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeCompressiveTraction(
     Vector<Real> & tract, const Vector<Real> & normal, Real delta_n,
     __attribute__((unused)) const Vector<Real> & opening) {
   Vector<Real> temp_tract(normal);
 
   if (exp_penalty) {
     temp_tract *=
         delta_n * exp(1) * sigma_c * exp(-delta_n / delta_c) / delta_c;
   } else {
     Real initial_tg = contact_tangent * exp(1) * sigma_c * delta_n / delta_c;
     temp_tract *= initial_tg;
   }
 
   tract += temp_tract;
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeTangentTraction(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     const Array<Real> & normal, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<Real>::matrix_iterator tangent_it =
       tangent_matrix.begin(spatial_dimension, spatial_dimension);
 
   Array<Real>::matrix_iterator tangent_end =
       tangent_matrix.end(spatial_dimension, spatial_dimension);
 
-  Array<Real>::const_vector_iterator normal_it =
+  auto normal_it =
       normal.begin(spatial_dimension);
 
-  Array<Real>::vector_iterator opening_it =
+  auto opening_it =
       opening(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::iterator<Real> delta_max_it =
+  auto delta_max_it =
       delta_max.previous(el_type, ghost_type).begin();
 
   Real beta2 = beta * beta;
 
   /**
    * compute tangent matrix  @f$ \frac{\partial \mathbf{t}}
    * {\partial \delta} = \hat{\mathbf{t}} \otimes
    * \frac{\partial (t/\delta)}{\partial \delta}
    * \frac{\hat{\mathbf{t}}}{\delta}+ \frac{t}{\delta}  [ \beta^2 \mathbf{I} +
    * (1-\beta^2) (\mathbf{n} \otimes \mathbf{n})] @f$
    **/
 
   /**
    * In which @f$
    *  \frac{\partial(t/ \delta)}{\partial \delta} =
    * \left\{\begin{array} {l l}
    *  -e  \frac{\sigma_c}{\delta_c^2  }e^{-\delta  /  \delta_c} &  \quad  if
    *  \delta \geq \delta_{max} \\
    *  0 & \quad if \delta < \delta_{max}, \delta_n > 0
    *  \end{array}\right. @f$
    **/
 
   for (; tangent_it != tangent_end;
        ++tangent_it, ++normal_it, ++opening_it, ++delta_max_it) {
 
     Real normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening(spatial_dimension);
     normal_opening = (*normal_it);
     normal_opening *= normal_opening_norm;
 
     Vector<Real> tangential_opening(spatial_dimension);
     tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
 
     Real tangential_opening_norm = tangential_opening.norm();
 
     Real delta = tangential_opening_norm;
     delta *= delta * beta2;
     delta += normal_opening_norm * normal_opening_norm;
     delta = sqrt(delta);
 
     if ((normal_opening_norm < 0) &&
         (std::abs(normal_opening_norm) > Math::getTolerance())) {
 
       Vector<Real> op_n(*normal_it);
       op_n *= normal_opening_norm;
       Vector<Real> delta_s(*opening_it);
       delta_s -= op_n;
       delta = tangential_opening_norm * beta;
 
       computeCoupledTangent(*tangent_it, *normal_it, delta, delta_s,
                             *delta_max_it);
 
       computeCompressivePenalty(*tangent_it, *normal_it, normal_opening_norm);
 
     } else
       computeCoupledTangent(*tangent_it, *normal_it, delta, *opening_it,
                             *delta_max_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeCoupledTangent(
     Matrix<Real> & tangent, const Vector<Real> & normal, Real delta,
     const Vector<Real> & opening, Real) {
   AKANTU_DEBUG_IN();
 
   Real beta2 = beta * beta;
   Matrix<Real> J(spatial_dimension, spatial_dimension);
   J.eye(beta2);
 
   if (std::abs(delta) < Math::getTolerance()) {
     delta = Math::getTolerance();
   }
 
   Real opening_normal;
   opening_normal = opening.dot(normal);
 
   Vector<Real> delta_e(normal);
   delta_e *= opening_normal;
   delta_e *= (1 - beta2);
   delta_e += (beta2 * opening);
 
   Real exponent = exp(1 - delta / delta_c) * sigma_c / delta_c;
 
   Matrix<Real> first_term(spatial_dimension, spatial_dimension);
   first_term.outerProduct(normal, normal);
   first_term *= (1 - beta2);
   first_term += J;
 
   Matrix<Real> second_term(spatial_dimension, spatial_dimension);
   second_term.outerProduct(delta_e, delta_e);
   second_term /= delta;
   second_term /= delta_c;
 
   Matrix<Real> diff(first_term);
   diff -= second_term;
 
   tangent = diff;
   tangent *= exponent;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveExponential<spatial_dimension>::computeCompressivePenalty(
     Matrix<Real> & tangent, const Vector<Real> & normal, Real delta_n) {
 
   if (!exp_penalty)
     delta_n = 0;
 
   Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
   n_outer_n.outerProduct(normal, normal);
 
   Real normal_tg = contact_tangent * exp(1) * sigma_c *
                    exp(-delta_n / delta_c) * (1 - delta_n / delta_c) / delta_c;
 
   n_outer_n *= normal_tg;
 
   tangent += n_outer_n;
 }
 
 INSTANTIATE_MATERIAL(cohesive_exponential, MaterialCohesiveExponential);
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.cc
index 5780ec6e0..06bd8aff0 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,651 +1,650 @@
 /**
  * @file   material_cohesive_linear.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Feb 22 2012
  * @date last modification: Thu Jan 14 2016
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <numeric>
 
 /* -------------------------------------------------------------------------- */
 #include "dof_synchronizer.hh"
 #include "material_cohesive_linear.hh"
 #include "solid_mechanics_model_cohesive.hh"
 #include "sparse_matrix.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveLinear<spatial_dimension>::MaterialCohesiveLinear(
     SolidMechanicsModel & model, const ID & id)
     : MaterialCohesive(model, id), sigma_c_eff("sigma_c_eff", *this),
       delta_c_eff("delta_c_eff", *this),
       insertion_stress("insertion_stress", *this),
       opening_prec("opening_prec", *this),
       reduction_penalty("reduction_penalty", *this) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("beta", beta, Real(0.), _pat_parsable | _pat_readable,
                       "Beta parameter");
 
   this->registerParam("G_c", G_c, Real(0.), _pat_parsable | _pat_readable,
                       "Mode I fracture energy");
 
   this->registerParam("penalty", penalty, Real(0.),
                       _pat_parsable | _pat_readable, "Penalty coefficient");
 
   this->registerParam("volume_s", volume_s, Real(0.),
                       _pat_parsable | _pat_readable,
                       "Reference volume for sigma_c scaling");
 
   this->registerParam("m_s", m_s, Real(1.), _pat_parsable | _pat_readable,
                       "Weibull exponent for sigma_c scaling");
 
   this->registerParam("kappa", kappa, Real(1.), _pat_parsable | _pat_readable,
                       "Kappa parameter");
 
   this->registerParam(
       "contact_after_breaking", contact_after_breaking, false,
       _pat_parsable | _pat_readable,
       "Activation of contact when the elements are fully damaged");
 
   this->registerParam("max_quad_stress_insertion", max_quad_stress_insertion,
                       false, _pat_parsable | _pat_readable,
                       "Insertion of cohesive element when stress is high "
                       "enough just on one quadrature point");
 
   this->registerParam("recompute", recompute, false,
                       _pat_parsable | _pat_modifiable, "recompute solution");
 
   this->use_previous_delta_max = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   MaterialCohesive::initMaterial();
 
   /// 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;
 
   sigma_c_eff.initialize(1);
   delta_c_eff.initialize(1);
   insertion_stress.initialize(spatial_dimension);
   opening_prec.initialize(spatial_dimension);
   reduction_penalty.initialize(1);
 
   if (!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();
   opening_prec.initializeHistory();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::scaleInsertionTraction() {
   AKANTU_DEBUG_IN();
 
   // do nothing if volume_s hasn't been specified by the user
   if (Math::are_float_equal(volume_s, 0.))
     return;
 
   const Mesh & mesh_facets = model->getMeshFacets();
-  const FEEngine & fe_engine = model->getFEEngine();
-  const FEEngine & fe_engine_facet = model->getFEEngine("FacetsFEEngine");
+  const auto & fe_engine = model->getFEEngine();
+  const auto & fe_engine_facet = model->getFEEngine("FacetsFEEngine");
 
   // loop over facet type
-  Mesh::type_iterator first = mesh_facets.firstType(spatial_dimension - 1);
-  Mesh::type_iterator last = mesh_facets.lastType(spatial_dimension - 1);
+  auto first = mesh_facets.firstType(spatial_dimension - 1);
+  auto last = mesh_facets.lastType(spatial_dimension - 1);
 
   Real base_sigma_c = sigma_c;
 
   for (; first != last; ++first) {
     ElementType type_facet = *first;
 
     const Array<std::vector<Element>> & facet_to_element =
         mesh_facets.getElementToSubelement(type_facet);
 
     UInt nb_facet = facet_to_element.size();
     UInt nb_quad_per_facet = fe_engine_facet.getNbIntegrationPoints(type_facet);
 
     // iterator to modify sigma_c for all the quadrature points of a facet
-    Array<Real>::vector_iterator sigma_c_iterator =
+    auto sigma_c_iterator =
         sigma_c(type_facet).begin_reinterpret(nb_quad_per_facet, nb_facet);
 
     for (UInt f = 0; f < nb_facet; ++f, ++sigma_c_iterator) {
 
       const std::vector<Element> & element_list = facet_to_element(f);
 
       // compute bounding volume
       Real volume = 0;
 
       auto elem = element_list.begin();
       auto elem_end = element_list.end();
 
       for (; elem != elem_end; ++elem) {
         if (*elem == ElementNull)
           continue;
 
         // unit vector for integration in order to obtain the volume
         UInt nb_quadrature_points =
             fe_engine.getNbIntegrationPoints(elem->type);
         Vector<Real> unit_vector(nb_quadrature_points, 1);
 
         volume += fe_engine.integrate(unit_vector, elem->type, elem->element,
                                       elem->ghost_type);
       }
 
       // scale sigma_c
       *sigma_c_iterator -= base_sigma_c;
       *sigma_c_iterator *= std::pow(volume_s / volume, 1. / m_s);
       *sigma_c_iterator += base_sigma_c;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::checkInsertion(
     bool check_only) {
   AKANTU_DEBUG_IN();
 
   const Mesh & mesh_facets = model->getMeshFacets();
   CohesiveElementInserter & inserter = model->getElementInserter();
 
   for (auto && type_facet : mesh_facets.elementTypes(spatial_dimension - 1)) {
     ElementType type_cohesive = FEEngine::getCohesiveElementType(type_facet);
-    const Array<bool> & facets_check = inserter.getCheckFacets(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);
     auto & open_prec = opening_prec(type_cohesive);
     auto & red_penalty = reduction_penalty(type_cohesive);
     const auto & f_stress = model->getStressOnFacets(type_facet);
     const auto & sigma_lim = sigma_c(type_facet);
     Real max_ratio = 0.;
     UInt index_f = 0;
     UInt index_filter = 0;
     UInt nn = 0;
 
     UInt nb_quad_facet =
         model->getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
     UInt nb_quad_cohesive = model->getFEEngine("CohesiveFEEngine")
                                 .getNbIntegrationPoints(type_cohesive);
 
     AKANTU_DEBUG_ASSERT(nb_quad_cohesive == nb_quad_facet,
                         "The cohesive element and the corresponding facet do "
                         "not have the same numbers of integration points");
 
     UInt nb_facet = f_filter.size();
     //  if (nb_facet == 0) continue;
 
     auto sigma_lim_it = sigma_lim.begin();
 
     Matrix<Real> stress_tmp(spatial_dimension, spatial_dimension);
     Matrix<Real> normal_traction(spatial_dimension, nb_quad_facet);
     Vector<Real> stress_check(nb_quad_facet);
     UInt sp2 = spatial_dimension * spatial_dimension;
 
     const auto & tangents = model->getTangents(type_facet);
     const auto & normals = model->getFEEngine("FacetsFEEngine")
                                .getNormalsOnIntegrationPoints(type_facet);
     auto normal_begin = normals.begin(spatial_dimension);
     auto tangent_begin = tangents.begin(tangents.getNbComponent());
     auto facet_stress_begin =
         f_stress.begin(spatial_dimension, spatial_dimension * 2);
 
     std::vector<Real> new_sigmas;
     std::vector<Vector<Real>> new_normal_traction;
     std::vector<Real> new_delta_c;
 
     // loop over each facet belonging to this material
     for (UInt f = 0; f < nb_facet; ++f, ++sigma_lim_it) {
       UInt facet = f_filter(f);
       // skip facets where check shouldn't be realized
       if (!facets_check(facet))
         continue;
 
       // compute the effective norm on each quadrature point of the facet
       for (UInt q = 0; q < nb_quad_facet; ++q) {
         UInt current_quad = facet * nb_quad_facet + q;
         const Vector<Real> & normal = normal_begin[current_quad];
         const Vector<Real> & tangent = tangent_begin[current_quad];
         const Matrix<Real> & facet_stress_it = facet_stress_begin[current_quad];
 
         // compute average stress on the current quadrature point
         Matrix<Real> stress_1(facet_stress_it.storage(), spatial_dimension,
                               spatial_dimension);
 
         Matrix<Real> stress_2(facet_stress_it.storage() + sp2,
                               spatial_dimension, spatial_dimension);
 
         stress_tmp.copy(stress_1);
         stress_tmp += stress_2;
         stress_tmp /= 2.;
 
         Vector<Real> normal_traction_vec(normal_traction(q));
 
         // compute normal and effective stress
         stress_check(q) = computeEffectiveNorm(stress_tmp, normal, tangent,
                                                normal_traction_vec);
       }
 
       // verify if the effective stress overcomes the threshold
       Real final_stress = stress_check.mean();
       if (max_quad_stress_insertion)
         final_stress = *std::max_element(
             stress_check.storage(), stress_check.storage() + nb_quad_facet);
 
       if (final_stress > *sigma_lim_it) {
         if (model->isDefaultSolverExplicit()) {
           f_insertion(facet) = true;
 
           if (check_only)
             continue;
 
           // store the new cohesive material parameters for each quadrature
           // point
           for (UInt q = 0; q < nb_quad_facet; ++q) {
             Real new_sigma = stress_check(q);
             Vector<Real> normal_traction_vec(normal_traction(q));
 
             if (spatial_dimension != 3)
               normal_traction_vec *= -1.;
 
             new_sigmas.push_back(new_sigma);
             new_normal_traction.push_back(normal_traction_vec);
 
             Real new_delta;
 
             // set delta_c in function of G_c or a given delta_c value
             if (Math::are_float_equal(delta_c, 0.))
               new_delta = 2 * G_c / new_sigma;
             else
               new_delta = (*sigma_lim_it) / new_sigma * delta_c;
 
             new_delta_c.push_back(new_delta);
           }
 
         } else {
           Real ratio = final_stress / (*sigma_lim_it);
           if (ratio > max_ratio) {
             ++nn;
             max_ratio = ratio;
             index_f = f;
             index_filter = f_filter(f);
           }
         }
       }
     }
 
     /// Insertion of only 1 cohesive element in case of implicit approach. The
     /// one subjected to the highest stress.
     if (!model->isDefaultSolverExplicit()) {
       const Communicator & comm = model->getMesh().getCommunicator();
       Array<Real> abs_max(comm.getNbProc());
       abs_max(comm.whoAmI()) = max_ratio;
       comm.allGather(abs_max);
 
       auto it = std::max_element(abs_max.begin(), abs_max.end());
       Int pos = it - abs_max.begin();
 
       if (pos != comm.whoAmI()) {
         AKANTU_DEBUG_OUT();
         return;
       }
 
       if (nn) {
         f_insertion(index_filter) = true;
 
         if (!check_only) {
           //  Array<Real>::iterator<Matrix<Real> > normal_traction_it =
           //  normal_traction.begin_reinterpret(nb_quad_facet,
           //  spatial_dimension, nb_facet);
-          Array<Real>::const_iterator<Real> sigma_lim_it = sigma_lim.begin();
+          auto sigma_lim_it = sigma_lim.begin();
 
           for (UInt q = 0; q < nb_quad_cohesive; ++q) {
 
             Real new_sigma = (sigma_lim_it[index_f]);
             Vector<Real> normal_traction_vec(spatial_dimension, 0.0);
 
             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 = delta_c;
             else
               new_delta = 2 * G_c / (new_sigma);
 
             new_delta_c.push_back(new_delta);
           }
         }
       }
     }
 
     // update material data for the new elements
     UInt old_nb_quad_points = sig_c_eff.size();
     UInt new_nb_quad_points = new_sigmas.size();
     sig_c_eff.resize(old_nb_quad_points + new_nb_quad_points);
     ins_stress.resize(old_nb_quad_points + new_nb_quad_points);
     trac_old.resize(old_nb_quad_points + new_nb_quad_points);
     del_c.resize(old_nb_quad_points + new_nb_quad_points);
     open_prec.resize(old_nb_quad_points + new_nb_quad_points);
     red_penalty.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];
       red_penalty(old_nb_quad_points + q) = false;
       for (UInt dim = 0; dim < spatial_dimension; ++dim) {
         ins_stress(old_nb_quad_points + q, dim) = new_normal_traction[q](dim);
         trac_old(old_nb_quad_points + q, dim) = new_normal_traction[q](dim);
         open_prec(old_nb_quad_points + q, dim) = 0.;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::computeTraction(
     const Array<Real> & normal, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto traction_it = tractions(el_type, ghost_type).begin(spatial_dimension);
   auto opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
   /// opening_prec is the opening of the previous step in the
   /// Newton-Raphson loop
   auto opening_prec_it =
       opening_prec(el_type, ghost_type).begin(spatial_dimension);
 
   auto contact_traction_it =
       contact_tractions(el_type, ghost_type).begin(spatial_dimension);
   auto contact_opening_it =
       contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto normal_it = normal.begin(spatial_dimension);
   auto traction_end = tractions(el_type, ghost_type).end(spatial_dimension);
   auto sigma_c_it = sigma_c_eff(el_type, ghost_type).begin();
   auto delta_max_it = delta_max(el_type, ghost_type).begin();
-  auto delta_max_prev_it = delta_max.previous(el_type, ghost_type).begin();
   auto delta_c_it = delta_c_eff(el_type, ghost_type).begin();
   auto damage_it = damage(el_type, ghost_type).begin();
   auto insertion_stress_it =
       insertion_stress(el_type, ghost_type).begin(spatial_dimension);
   auto reduction_penalty_it = reduction_penalty(el_type, ghost_type).begin();
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   if (!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, ++opening_prec_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, ++reduction_penalty_it) {
+       ++reduction_penalty_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     Real current_penalty = 0.;
     this->computeTractionOnQuad(
-        *traction_it, *delta_max_it, *delta_max_prev_it, *delta_c_it,
-        *insertion_stress_it, *sigma_c_it, *opening_it, *opening_prec_it,
-        *normal_it, normal_opening, tangential_opening, normal_opening_norm,
-        tangential_opening_norm, *damage_it, penetration, *reduction_penalty_it,
-        current_penalty, *contact_traction_it, *contact_opening_it);
+        *traction_it, *opening_it, *opening_prec_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, *reduction_penalty_it, current_penalty,
+        *contact_traction_it, *contact_opening_it);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::checkDeltaMax(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /**
   * This function set a predefined value to the parameter
   * delta_max_prev of the elements that have been inserted in the
   * last loading step for which convergence has not been
   * reached. This is done before reducing the loading and re-doing
   * the step.  Otherwise, the updating of delta_max_prev would be
   * done with reference to the non-convergent solution. In this
   * function also other variables related to the contact and
   * friction behavior are correctly set.
   */
 
   Mesh & mesh = fem_cohesive.getMesh();
   Mesh::type_iterator it =
       mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive);
   Mesh::type_iterator last_type =
       mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive);
 
   /**
   * the variable "recompute" is set to true to activate the
   * procedure that reduce the penalty parameter for
   * compression. This procedure is set true only during the phase of
   * load_reduction, that has to be set in the maiin file. The
   * penalty parameter will be reduced only for the elements having
   * reduction_penalty = true.
   */
   recompute = true;
 
   for (; it != last_type; ++it) {
     Array<UInt> & elem_filter = element_filter(*it, ghost_type);
 
     UInt nb_element = elem_filter.size();
     if (nb_element == 0)
       continue;
 
     ElementType el_type = *it;
 
     /// define iterators
     auto delta_max_it = delta_max(el_type, ghost_type).begin();
     auto delta_max_end = delta_max(el_type, ghost_type).end();
     auto delta_max_prev_it = delta_max.previous(el_type, ghost_type).begin();
     auto delta_c_it = delta_c_eff(el_type, ghost_type).begin();
     auto opening_prec_it =
         opening_prec(el_type, ghost_type).begin(spatial_dimension);
     auto opening_prec_prev_it =
         opening_prec.previous(el_type, ghost_type).begin(spatial_dimension);
 
     /// loop on each quadrature point
     for (; delta_max_it != delta_max_end; ++delta_max_it, ++delta_max_prev_it,
                                           ++delta_c_it, ++opening_prec_it,
                                           ++opening_prec_prev_it) {
 
       if (*delta_max_prev_it == 0)
         /// elements inserted in the last incremental step, that did
         /// not converge
         *delta_max_it = *delta_c_it / 1000;
       else
         /// elements introduced in previous incremental steps, for
         /// which a correct value of delta_max_prev already exists
         *delta_max_it = *delta_max_prev_it;
 
       /// in case convergence is not reached, set opening_prec to the
       /// value referred to the previous incremental step
       *opening_prec_it = *opening_prec_prev_it;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::resetVariables(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /**
   * This function set the variables "recompute" and
   * "reduction_penalty" to false. It is called by solveStepCohesive
   * when convergence is reached. Such variables, in fact, have to be
   * false at the beginning of a new incremental step.
   */
 
   Mesh & mesh = fem_cohesive.getMesh();
   Mesh::type_iterator it =
       mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive);
   Mesh::type_iterator last_type =
       mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive);
 
   recompute = false;
 
   for (; it != last_type; ++it) {
     Array<UInt> & elem_filter = element_filter(*it, ghost_type);
 
     UInt nb_element = elem_filter.size();
     if (nb_element == 0)
       continue;
 
     ElementType el_type = *it;
 
     auto reduction_penalty_it = reduction_penalty(el_type, ghost_type).begin();
     auto reduction_penalty_end = reduction_penalty(el_type, ghost_type).end();
 
     /// loop on each quadrature point
     for (; reduction_penalty_it != reduction_penalty_end;
          ++reduction_penalty_it) {
 
       *reduction_penalty_it = false;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinear<spatial_dimension>::computeTangentTraction(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     const Array<Real> & normal, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   auto tangent_it = tangent_matrix.begin(spatial_dimension, spatial_dimension);
 
   auto tangent_end = tangent_matrix.end(spatial_dimension, spatial_dimension);
 
   auto normal_it = normal.begin(spatial_dimension);
 
   auto opening_it = opening(el_type, ghost_type).begin(spatial_dimension);
 
   /// NB: delta_max_it points on delta_max_previous, i.e. the
   /// delta_max related to the solution of the previous incremental
   /// step
   auto delta_max_it = delta_max.previous(el_type, ghost_type).begin();
 
   auto sigma_c_it = sigma_c_eff(el_type, ghost_type).begin();
 
   auto delta_c_it = delta_c_eff(el_type, ghost_type).begin();
 
   auto damage_it = damage(el_type, ghost_type).begin();
 
   auto contact_opening_it =
       contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   auto reduction_penalty_it = reduction_penalty(el_type, ghost_type).begin();
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   for (; tangent_it != tangent_end; ++tangent_it, ++normal_it, ++opening_it,
                                     ++delta_max_it, ++sigma_c_it, ++delta_c_it,
                                     ++damage_it, ++contact_opening_it,
                                     ++reduction_penalty_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     Real current_penalty = 0.;
     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, *reduction_penalty_it,
         current_penalty, *contact_opening_it);
 
     // check if the tangential stiffness matrix is symmetric
     //    for (UInt h = 0; h < spatial_dimension; ++h){
     //      for (UInt l = h; l < spatial_dimension; ++l){
     //        if (l > h){
     //          Real k_ls = (*tangent_it)[spatial_dimension*h+l];
     //          Real k_us =  (*tangent_it)[spatial_dimension*l+h];
     //          //          std::cout << "k_ls = " << k_ls << std::endl;
     //          //          std::cout << "k_us = " << k_us << std::endl;
     //          if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
     //            Real error = std::abs((k_ls - k_us) / k_us);
     //            if (error > 1e-10){
     //	      std::cout << "non symmetric cohesive matrix" << std::endl;
     //	      //  std::cout << "error " << error << std::endl;
     //            }
     //          }
     //        }
     //      }
     //    }
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear, MaterialCohesiveLinear);
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear.hh
index f298b4a96..038db7968 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,212 +1,206 @@
 /**
  * @file   material_cohesive_linear.hh
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Jan 14 2016
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You 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)
+ *   - 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 <UInt spatial_dimension>
 class MaterialCohesiveLinear : public MaterialCohesive {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
-
   MaterialCohesiveLinear(SolidMechanicsModel & model, const ID & id = "");
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
-
   /// initialize the material parameters
   void initMaterial() override;
 
   /// check stress for cohesive elements' insertion
   void checkInsertion(bool check_only = false) override;
 
   /// compute effective stress norm for insertion check
   Real computeEffectiveNorm(const Matrix<Real> & stress,
-			    const Vector<Real> & normal,
-			    const Vector<Real> & tangent,
-			    Vector<Real> & normal_stress) const;
+                            const Vector<Real> & normal,
+                            const Vector<Real> & tangent,
+                            Vector<Real> & normal_stress) const;
 
 protected:
-
   /// constitutive law
   void computeTraction(const Array<Real> & normal, ElementType el_type,
                        GhostType ghost_type = _not_ghost) override;
 
   /// check delta_max for cohesive elements in case of no convergence
   /// in the solveStep (only for extrinsic-implicit)
   void checkDeltaMax(GhostType ghost_type = _not_ghost) override;
 
   /// reset variables when convergence is reached (only for
   /// extrinsic-implicit)
   void resetVariables(GhostType ghost_type = _not_ghost) override;
 
   /// compute tangent stiffness matrix
   void computeTangentTraction(const ElementType & el_type,
                               Array<Real> & tangent_matrix,
                               const Array<Real> & normal,
                               GhostType ghost_type) override;
 
   /**
    * Scale insertion traction sigma_c according to the volume of the
    * two elements surrounding a facet
    *
    * see the article: F. Zhou and J. F. Molinari "Dynamic crack
    * propagation with cohesive elements: a methodology to address mesh
    * dependency" International Journal for Numerical Methods in
    * Engineering (2004)
    */
   void scaleInsertionTraction();
 
   /// compute the traction for a given quadrature point
-  inline void computeTractionOnQuad(Vector<Real> & traction, Real & delta_max,
-    const Real & delta_max_prev, const Real & delta_c,
-    const Vector<Real> & insertion_stress, const Real & sigma_c,
-    Vector<Real> & opening, Vector<Real> & opening_prec, const Vector<Real> & normal,
-    Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
-    Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
-    bool & penetration, bool & reduction_penalty, Real & current_penalty,
-    Vector<Real> & contact_traction, Vector<Real> & contact_opening);
-
-  inline void computeTangentTractionOnQuad(Matrix<Real> & tangent,
-    Real & delta_max, const Real & delta_c,
-    const Real & sigma_c,
-    Vector<Real> & opening, const Vector<Real> & normal,
-    Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
-    Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
-    bool & penetration, bool & reduction_penalty, Real & current_penalty,
-    Vector<Real> & contact_opening);
+  inline void computeTractionOnQuad(
+      Vector<Real> & traction, Vector<Real> & opening,
+      Vector<Real> & opening_prec, const Vector<Real> & normal,
+      Real & delta_max, const Real & delta_c,
+      const Vector<Real> & insertion_stress, const Real & sigma_c,
+      Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
+      Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
+      bool & penetration, bool & reduction_penalty, Real & current_penalty,
+      Vector<Real> & contact_traction, Vector<Real> & contact_opening);
+
+  inline void computeTangentTractionOnQuad(
+      Matrix<Real> & tangent, Real & delta_max, const Real & delta_c,
+      const Real & sigma_c, Vector<Real> & opening, const Vector<Real> & normal,
+      Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
+      Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
+      bool & penetration, bool & reduction_penalty, Real & current_penalty,
+      Vector<Real> & contact_opening);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
-
   /// get sigma_c_eff
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(InsertionTraction, sigma_c_eff, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// beta parameter
   Real beta;
 
   /// beta square inverse to compute effective norm
   Real beta2_inv;
 
   /// mode I fracture energy
   Real G_c;
 
   /// kappa parameter
   Real kappa;
 
   /// constitutive law scalar to compute delta
   Real beta2_kappa2;
 
   /// constitutive law scalar to compute traction
   Real beta2_kappa;
 
   /// penalty coefficient
   Real penalty;
 
   /// reference volume used to scale sigma_c
   Real volume_s;
 
   /// weibull exponent used to scale sigma_c
   Real m_s;
 
   /// variable defining if we are recomputing the last loading step
   /// after load_reduction
   bool recompute;
 
   /// critical effective stress
   RandomInternalField<Real, CohesiveInternalField> sigma_c_eff;
 
   /// effective critical displacement (each element can have a
   /// different value)
   CohesiveInternalField<Real> delta_c_eff;
 
   /// stress at insertion
   CohesiveInternalField<Real> insertion_stress;
 
   /// delta of the previous step
   CohesiveInternalField<Real> opening_prec;
 
   /**
    * variable that defines if the penalty parameter for compression
    * has to be decreased for problems of convergence in the solution
    * loops
    */
   CohesiveInternalField<bool> reduction_penalty;
 
   /// variable saying if there should be penalty contact also after
   /// breaking the cohesive elements
   bool contact_after_breaking;
 
   /// insertion of cohesive element when stress is high enough just on
   /// one quadrature point
   bool max_quad_stress_insertion;
-
 };
 
-
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 } // akantu
 
 #include "material_cohesive_linear_inline_impl.cc"
 
 #endif /* __AKANTU_MATERIAL_COHESIVE_LINEAR_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_fatigue.cc
index aeffe864e..e38bd4c1b 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,296 +1,296 @@
 /**
  * @file   material_cohesive_linear_fatigue.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Feb 20 2015
  * @date last modification: Tue Jan 12 2016
  *
  * @brief  See material_cohesive_linear_fatigue.hh for information
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear_fatigue.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveLinearFatigue<spatial_dimension>
 ::MaterialCohesiveLinearFatigue(SolidMechanicsModel & model,
 				const ID & id) :
   MaterialCohesiveLinear<spatial_dimension>(model, id),
   delta_prec("delta_prec", *this),
   K_plus("K_plus", *this),
   K_minus("K_minus", *this),
   T_1d("T_1d", *this),
   switches("switches", *this),
   delta_dot_prec("delta_dot_prec", *this),
   normal_regime("normal_regime", *this) {
 
   this->registerParam("delta_f", delta_f, Real(-1.) ,
 		      _pat_parsable | _pat_readable,
 		      "delta_f");
 
   this->registerParam("progressive_delta_f", progressive_delta_f, false,
 		      _pat_parsable | _pat_readable,
 		      "Whether or not delta_f is equal to delta_max");
 
   this->registerParam("count_switches", count_switches, false,
 		      _pat_parsable | _pat_readable,
 		      "Count the opening/closing switches per element");
 
   this->registerParam("fatigue_ratio", fatigue_ratio, Real(1.),
 		      _pat_parsable | _pat_readable,
 		      "What portion of the cohesive law is subjected to fatigue");
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFatigue<spatial_dimension>::initMaterial() {
   MaterialCohesiveLinear<spatial_dimension>::initMaterial();
 
   // check that delta_f has a proper value or assign a defaul value
   if (delta_f < 0) delta_f = this->delta_c_eff;
   else if (delta_f < this->delta_c_eff)
     AKANTU_ERROR("Delta_f must be greater or equal to delta_c");
 
   delta_prec.initialize(1);
   K_plus.initialize(1);
   K_minus.initialize(1);
   T_1d.initialize(1);
   normal_regime.initialize(1);
 
   if (count_switches) {
     switches.initialize(1);
     delta_dot_prec.initialize(1);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template<UInt spatial_dimension>
 void MaterialCohesiveLinearFatigue<spatial_dimension>
 ::computeTraction(const Array<Real> & normal,
 		  ElementType el_type,
 		  GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
-  Array<Real>::vector_iterator traction_it =
+  auto traction_it =
     this->tractions(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::vector_iterator opening_it =
+  auto opening_it =
     this->opening(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::vector_iterator contact_traction_it =
+  auto contact_traction_it =
     this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::vector_iterator contact_opening_it =
+  auto contact_opening_it =
     this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::const_vector_iterator normal_it = normal.begin(spatial_dimension);
+  auto normal_it = normal.begin(spatial_dimension);
 
-  Array<Real>::vector_iterator traction_end =
+  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);
 
-  Array<Real>::vector_iterator insertion_stress_it =
+  auto insertion_stress_it =
     this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
 
   Array<Real> & delta_prec_array = delta_prec(el_type, ghost_type);
   Array<Real> & K_plus_array = K_plus(el_type, ghost_type);
   Array<Real> & K_minus_array = K_minus(el_type, ghost_type);
   Array<Real> & T_1d_array = T_1d(el_type, ghost_type);
   Array<bool> & normal_regime_array = normal_regime(el_type, ghost_type);
 
   Array<UInt> * switches_array = nullptr;
   Array<Real> * delta_dot_prec_array = nullptr;
 
   if (count_switches) {
     switches_array = &switches(el_type, ghost_type);
     delta_dot_prec_array = &delta_dot_prec(el_type, ghost_type);
   }
 
   auto * memory_space = new Real[2 * spatial_dimension];
   Vector<Real> normal_opening(memory_space, spatial_dimension);
   Vector<Real> tangential_opening(memory_space + spatial_dimension,
 				  spatial_dimension);
 
   Real tolerance = Math::getTolerance();
 
   /// loop on each quadrature point
   for (UInt q = 0; traction_it != traction_end;
        ++traction_it, ++opening_it, ++normal_it,
 	 ++contact_traction_it, ++insertion_stress_it, ++contact_opening_it, ++q) {
 
     /// compute normal and tangential opening vectors
     Real normal_opening_norm = opening_it->dot(*normal_it);
     normal_opening  = (*normal_it);
     normal_opening *= normal_opening_norm;
 
     tangential_opening  = *opening_it;
     tangential_opening -=  normal_opening;
 
     Real tangential_opening_norm = tangential_opening.norm();
 
     /**
      * compute effective opening displacement
      * @f$ \delta = \sqrt{
      * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
      */
     Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
     bool penetration = normal_opening_norm < -tolerance;
     if (this->contact_after_breaking == false && Math::are_float_equal(damage_array(q), 1.))
       penetration = false;
 
     if (penetration) {
       /// use penalty coefficient in case of penetration
       *contact_traction_it = normal_opening;
       *contact_traction_it *= this->penalty;
       *contact_opening_it = normal_opening;
       /// don't consider penetration contribution for delta
       *opening_it = tangential_opening;
       normal_opening.clear();
     }
     else {
       delta += normal_opening_norm * normal_opening_norm;
       contact_traction_it->clear();
       contact_opening_it->clear();
     }
 
     delta = std::sqrt(delta);
 
     /**
      * Compute traction @f$ \mathbf{T} = \left(
      * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
      * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
      * \frac{\delta}{\delta_c} \right)@f$
      */
 
 
     // update maximum displacement and damage
     delta_max_array(q) = std::max(delta, delta_max_array(q));
     damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
 
     Real delta_dot = delta - delta_prec_array(q);
 
     // count switches if asked
     if (count_switches) {
       if ( (delta_dot > 0. && (*delta_dot_prec_array)(q) <= 0.) ||
 	   (delta_dot < 0. && (*delta_dot_prec_array)(q) >= 0.) )
 	++((*switches_array)(q));
 
       (*delta_dot_prec_array)(q) = delta_dot;
     }
 
     // set delta_f equal to delta_max if desired
     if (progressive_delta_f) delta_f = delta_max_array(q);
 
     // broken element case
     if (Math::are_float_equal(damage_array(q), 1.))
       traction_it->clear();
     // just inserted element case
     else if (Math::are_float_equal(damage_array(q), 0.)) {
       if (penetration)
 	traction_it->clear();
       else
 	*traction_it = *insertion_stress_it;
       // initialize the 1d traction to sigma_c
       T_1d_array(q) = sigma_c_array(q);
     }
     // normal case
     else {
       // if element is closed then there are zero tractions
       if (delta <= tolerance)
 	traction_it->clear();
       // otherwise compute new tractions if the new delta is different
       // than the previous one
       else if (std::abs(delta_dot) > tolerance) {
 	// loading case
 	if (delta_dot > 0.) {
 	  if (!normal_regime_array(q)) {
 	    // equation (4) of the article
 	    K_plus_array(q) *= 1. - delta_dot / delta_f;
 	    // equivalent to equation (2) of the article
 	    T_1d_array(q) += K_plus_array(q) * delta_dot;
 
 	    // in case of reloading, traction must not exceed that of the
 	    // envelop of the cohesive law
 	    Real max_traction = sigma_c_array(q) * (1 - delta / delta_c_array(q));
 	    bool max_traction_exceeded = T_1d_array(q) > max_traction;
 	    if (max_traction_exceeded) T_1d_array(q) = max_traction;
 
 	    // switch to standard linear cohesive law
 	    if (delta_max_array(q) > fatigue_ratio * delta_c_array(q)) {
 	      // reset delta_max to avoid big jumps in the traction
 	      delta_max_array(q) = sigma_c_array(q) / (T_1d_array(q) / delta + sigma_c_array(q) / delta_c_array(q));
 	      damage_array(q) = std::min(delta_max_array(q) / delta_c_array(q), Real(1.));
 	      K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
 	      normal_regime_array(q) = true;
 	    } else {
 	      // equation (3) of the article
 	      K_minus_array(q) = T_1d_array(q) / delta;
 
 	      // if the traction is following the cohesive envelop, then
 	      // K_plus has to be reset
 	      if (max_traction_exceeded) K_plus_array(q) = K_minus_array(q);
 	    }
 	  } else {
 	    // compute stiffness according to the standard law
 	    K_minus_array(q) = sigma_c_array(q) / delta_max_array(q) * (1. - damage_array(q));
 	  }
 	}
 	// unloading case
 	else if (!normal_regime_array(q)) {
 	  // equation (4) of the article
 	  K_plus_array(q) += (K_plus_array(q) - K_minus_array(q)) * delta_dot / delta_f;
 	  // equivalent to equation (2) of the article
 	  T_1d_array(q) = K_minus_array(q) * delta;
 	}
 
 	// applying the actual stiffness
 	*traction_it  = tangential_opening;
 	*traction_it *= this->beta2_kappa;
 	*traction_it += normal_opening;
 	*traction_it *= K_minus_array(q);
       }
     }
 
     // update precendent delta
     delta_prec_array(q) = delta;
   }
 
   delete [] memory_space;
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear_fatigue, MaterialCohesiveLinearFatigue);
 
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_friction.cc
index 748481c51..0fe8e55af 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,386 +1,356 @@
 /**
  * @file   material_cohesive_linear_friction.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Tue Jan 12 2016
  * @date last modification: Thu Jan 14 2016
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear_friction.hh"
 #include "solid_mechanics_model_cohesive.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveLinearFriction<spatial_dimension>::
     MaterialCohesiveLinearFriction(SolidMechanicsModel & model, const ID & id)
     : MaterialParent(model, id), residual_sliding("residual_sliding", *this),
       friction_force("friction_force", *this) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("mu", mu_max, Real(0.), _pat_parsable | _pat_readable,
                       "Maximum value of the friction coefficient");
 
   this->registerParam("penalty_for_friction", friction_penalty, Real(0.),
                       _pat_parsable | _pat_readable,
                       "Penalty parameter for the friction behavior");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFriction<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   MaterialParent::initMaterial();
 
   friction_force.initialize(spatial_dimension);
   residual_sliding.initialize(1);
   residual_sliding.initializeHistory();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFriction<spatial_dimension>::computeTraction(
     __attribute__((unused)) const Array<Real> & normal, ElementType el_type,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   residual_sliding.resize();
   friction_force.resize();
 
   /// define iterators
-  Array<Real>::vector_iterator traction_it =
+  auto traction_it =
       this->tractions(el_type, ghost_type).begin(spatial_dimension);
-
-  Array<Real>::vector_iterator traction_end =
+  auto traction_end =
       this->tractions(el_type, ghost_type).end(spatial_dimension);
-
-  Array<Real>::vector_iterator opening_it =
-      this->opening(el_type, ghost_type).begin(spatial_dimension);
+  auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
 
   /// opening_prec is the opening at the end of the previous step in
   /// the Newton-Raphson loop
-  Array<Real>::vector_iterator opening_prec_it =
+  auto opening_prec_it =
       this->opening_prec(el_type, ghost_type).begin(spatial_dimension);
 
   /// opening_prec_prev is the opening (opening + penetration)
   /// referred to the convergence of the previous incremental step
-  Array<Real>::vector_iterator opening_prec_prev_it =
+  auto opening_prec_prev_it =
       this->opening_prec.previous(el_type, ghost_type).begin(spatial_dimension);
-
-  Array<Real>::vector_iterator contact_traction_it =
+  auto contact_traction_it =
       this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
-
-  Array<Real>::vector_iterator contact_opening_it =
+  auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   Array<Real>::const_iterator<Vector<Real>> normal_it =
       this->normal.begin(spatial_dimension);
 
-  Array<Real>::iterator<Real> sigma_c_it =
-      this->sigma_c_eff(el_type, ghost_type).begin();
-
-  Array<Real>::iterator<Real> delta_max_it =
-      this->delta_max(el_type, ghost_type).begin();
-
-  Array<Real>::iterator<Real> delta_max_prev_it =
+  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();
 
-  Array<Real>::iterator<Real> delta_c_it =
-      this->delta_c_eff(el_type, ghost_type).begin();
-
-  Array<Real>::iterator<Real> damage_it =
-      this->damage(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();
 
-  Array<Real>::vector_iterator insertion_stress_it =
+  auto insertion_stress_it =
       this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::iterator<Real> res_sliding_it =
-      this->residual_sliding(el_type, ghost_type).begin();
-
-  Array<Real>::iterator<Real> res_sliding_prev_it =
+  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();
 
-  Array<Real>::vector_iterator friction_force_it =
+  auto friction_force_it =
       this->friction_force(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<bool>::iterator<bool> reduction_penalty_it =
+  auto reduction_penalty_it =
       this->reduction_penalty(el_type, ghost_type).begin();
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   if (!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, ++opening_prec_prev_it, ++opening_prec_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, ++reduction_penalty_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     Real current_penalty = 0.;
     this->computeTractionOnQuad(
-        *traction_it, *delta_max_it, *delta_max_prev_it, *delta_c_it,
-        *insertion_stress_it, *sigma_c_it, *opening_it, *opening_prec_it,
-        *normal_it, normal_opening, tangential_opening, normal_opening_norm,
-        tangential_opening_norm, *damage_it, penetration, *reduction_penalty_it,
-        current_penalty, *contact_traction_it, *contact_opening_it);
+        *traction_it, *opening_it, *opening_prec_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, *reduction_penalty_it, current_penalty,
+        *contact_traction_it, *contact_opening_it);
 
     if (penetration) {
 
       /// the friction coefficient mu increases with the damage. It
       /// equals the maximum value when damage = 1.
       //      Real damage = std::min(*delta_max_prev_it / *delta_c_it,
       //      Real(1.));
       Real mu = mu_max; // * damage;
 
       /// the definition of tau_max refers to the opening
       /// (penetration) of the previous incremental step
       Real normal_opening_prev_norm =
           std::min(opening_prec_prev_it->dot(*normal_it), Real(0.));
 
       //      Vector<Real> normal_opening_prev = (*normal_it);
       //      normal_opening_prev *= normal_opening_prev_norm;
 
       Real tau_max =
           mu * current_penalty * (std::abs(normal_opening_prev_norm));
       Real delta_sliding_norm =
           std::abs(tangential_opening_norm - *res_sliding_prev_it);
 
       /// tau is the norm of the friction force, acting tangentially to the
       /// surface
       Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
 
       if ((tangential_opening_norm - *res_sliding_prev_it) < 0.0)
         tau = -tau;
 
       /// from tau get the x and y components of friction, to be added in the
       /// force vector
       Vector<Real> tangent_unit_vector(spatial_dimension);
       tangent_unit_vector = tangential_opening / tangential_opening_norm;
       *friction_force_it = tau * tangent_unit_vector;
 
       /// update residual_sliding
       *res_sliding_it =
           tangential_opening_norm - (std::abs(tau) / friction_penalty);
 
     } else {
 
       friction_force_it->clear();
     }
 
     *traction_it += *friction_force_it;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFriction<spatial_dimension>::checkDeltaMax(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   MaterialParent::checkDeltaMax();
 
   Mesh & mesh = this->fem_cohesive.getMesh();
-  Mesh::type_iterator it =
-      mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive);
-  Mesh::type_iterator last_type =
-      mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive);
+  auto it = mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive);
+  auto last_type = mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive);
 
   for (; it != last_type; ++it) {
     Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
 
     UInt nb_element = elem_filter.size();
     if (nb_element == 0)
       continue;
 
     ElementType el_type = *it;
 
     /// define iterators
-    Array<Real>::iterator<Real> delta_max_it =
-        this->delta_max(el_type, ghost_type).begin();
-
-    Array<Real>::iterator<Real> delta_max_end =
-        this->delta_max(el_type, ghost_type).end();
+    auto delta_max_it = this->delta_max(el_type, ghost_type).begin();
+    auto delta_max_end = this->delta_max(el_type, ghost_type).end();
 
-    Array<Real>::iterator<Real> res_sliding_it =
-        this->residual_sliding(el_type, ghost_type).begin();
-
-    Array<Real>::iterator<Real> res_sliding_prev_it =
+    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();
 
     /// loop on each quadrature point
     for (; delta_max_it != delta_max_end;
          ++delta_max_it, ++res_sliding_it, ++res_sliding_prev_it) {
 
       /**
        * in case convergence is not reached, set "residual_sliding"
        * for the friction behaviour to the value referred to the
        * previous incremental step
        */
       *res_sliding_it = *res_sliding_prev_it;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearFriction<spatial_dimension>::computeTangentTraction(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     __attribute__((unused)) const Array<Real> & normal, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   Array<Real>::matrix_iterator tangent_it =
       tangent_matrix.begin(spatial_dimension, spatial_dimension);
 
   Array<Real>::matrix_iterator tangent_end =
       tangent_matrix.end(spatial_dimension, spatial_dimension);
 
-  Array<Real>::const_vector_iterator normal_it =
-      this->normal.begin(spatial_dimension);
+  auto normal_it = this->normal.begin(spatial_dimension);
 
-  Array<Real>::vector_iterator opening_it =
-      this->opening(el_type, ghost_type).begin(spatial_dimension);
+  auto opening_it = this->opening(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::vector_iterator opening_prec_prev_it =
+  auto opening_prec_prev_it =
       this->opening_prec.previous(el_type, ghost_type).begin(spatial_dimension);
 
   /**
    * NB: delta_max_it points on delta_max_previous, i.e. the
    * delta_max related to the solution of the previous incremental
    * step
    */
-  Array<Real>::iterator<Real> delta_max_it =
-      this->delta_max.previous(el_type, ghost_type).begin();
-
-  Array<Real>::iterator<Real> sigma_c_it =
-      this->sigma_c_eff(el_type, ghost_type).begin();
-
-  Array<Real>::iterator<Real> delta_c_it =
-      this->delta_c_eff(el_type, ghost_type).begin();
-
-  Array<Real>::iterator<Real> damage_it =
-      this->damage(el_type, ghost_type).begin();
+  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();
 
-  Array<Real>::iterator<Vector<Real>> contact_opening_it =
+  auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::iterator<Real> res_sliding_prev_it =
+  auto res_sliding_prev_it =
       this->residual_sliding.previous(el_type, ghost_type).begin();
 
-  Array<bool>::iterator<bool> reduction_penalty_it =
+  auto reduction_penalty_it =
       this->reduction_penalty(el_type, ghost_type).begin();
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   for (; tangent_it != tangent_end;
        ++tangent_it, ++normal_it, ++opening_it, ++opening_prec_prev_it,
        ++delta_max_it, ++sigma_c_it, ++delta_c_it, ++damage_it,
        ++contact_opening_it, ++res_sliding_prev_it, ++reduction_penalty_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     Real current_penalty = 0.;
     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, *reduction_penalty_it,
         current_penalty, *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(opening_prec_prev_it->dot(*normal_it), Real(0.));
       //      Vector<Real> normal_opening_prev = (*normal_it);
       //      normal_opening_prev *= normal_opening_prev_norm;
 
       Real tau_max =
           mu * current_penalty * (std::abs(normal_opening_prev_norm));
       Real delta_sliding_norm =
           std::abs(tangential_opening_norm - *res_sliding_prev_it);
 
       // tau is the norm of the friction force, acting tangentially to the
       // surface
       Real tau = std::min(friction_penalty * delta_sliding_norm, tau_max);
 
       if (tau < tau_max && tau_max > Math::getTolerance()) {
         Matrix<Real> I(spatial_dimension, spatial_dimension);
         I.eye(1.);
 
         Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
         n_outer_n.outerProduct(*normal_it, *normal_it);
 
         Matrix<Real> nn(n_outer_n);
         I -= nn;
         *tangent_it += I * friction_penalty;
       }
     }
 
     // check if the tangential stiffness matrix is symmetric
     //    for (UInt h = 0; h < spatial_dimension; ++h){
     //      for (UInt l = h; l < spatial_dimension; ++l){
     //        if (l > h){
     //          Real k_ls = (*tangent_it)[spatial_dimension*h+l];
     //          Real k_us =  (*tangent_it)[spatial_dimension*l+h];
     //          //          std::cout << "k_ls = " << k_ls << std::endl;
     //          //          std::cout << "k_us = " << k_us << std::endl;
     //          if (std::abs(k_ls) > 1e-13 && std::abs(k_us) > 1e-13){
     //            Real error = std::abs((k_ls - k_us) / k_us);
     //            if (error > 1e-10){
     //	      std::cout << "non symmetric cohesive matrix" << std::endl;
     //	      //  std::cout << "error " << error << std::endl;
     //            }
     //          }
     //        }
     //      }
     //    }
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear_friction, MaterialCohesiveLinearFriction);
 
 } // akantu
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc
index e4bb60b53..593e961c4 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_inline_impl.cc
@@ -1,319 +1,296 @@
 /**
  * @file   material_cohesive_linear_inline_impl.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Apr 22 2015
  * @date last modification: Thu Jan 14 2016
  *
  * @brief  Inline functions of the MaterialCohesiveLinear
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear.hh"
 #include "solid_mechanics_model_cohesive.hh"
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
 #define __AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-template<UInt dim>
-inline Real MaterialCohesiveLinear<dim>::computeEffectiveNorm(const Matrix<Real> & stress,
-							      const Vector<Real> & normal,
-							      const Vector<Real> & tangent,
-							      Vector<Real> & normal_traction) const {
+template <UInt dim>
+inline Real MaterialCohesiveLinear<dim>::computeEffectiveNorm(
+    const Matrix<Real> & stress, const Vector<Real> & normal,
+    const Vector<Real> & tangent, Vector<Real> & normal_traction) const {
   normal_traction.mul<false>(stress, normal);
 
   Real normal_contrib = normal_traction.dot(normal);
 
   /// in 3D tangential components must be summed
   Real tangent_contrib = 0;
 
   if (dim == 2) {
     Real tangent_contrib_tmp = normal_traction.dot(tangent);
     tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
-  }
-  else if (dim == 3) {
+  } else if (dim == 3) {
     for (UInt s = 0; s < dim - 1; ++s) {
       const Vector<Real> tangent_v(tangent.storage() + s * dim, dim);
       Real tangent_contrib_tmp = normal_traction.dot(tangent_v);
       tangent_contrib += tangent_contrib_tmp * tangent_contrib_tmp;
     }
   }
 
   tangent_contrib = std::sqrt(tangent_contrib);
   normal_contrib = std::max(Real(0.), normal_contrib);
 
-  return std::sqrt(normal_contrib * normal_contrib + tangent_contrib * tangent_contrib * beta2_inv);
+  return std::sqrt(normal_contrib * normal_contrib +
+                   tangent_contrib * tangent_contrib * beta2_inv);
 }
 
 /* -------------------------------------------------------------------------- */
-template<UInt dim>
+template <UInt dim>
 inline void MaterialCohesiveLinear<dim>::computeTractionOnQuad(
-    Vector<Real> & traction,
-    Real & delta_max,
-    __attribute__((unused)) const Real & delta_max_prev,
-    const Real & delta_c,
-    const Vector<Real> & insertion_stress,
-    const Real & sigma_c,
-    Vector<Real> & opening,
-    Vector<Real> & opening_prec,
-    const Vector<Real> & normal,
-    Vector<Real> & normal_opening,
-    Vector<Real> & tangential_opening,
-    Real & normal_opening_norm,
-    Real & tangential_opening_norm,
-    Real & damage,
-    bool & penetration,
-    bool & reduction_penalty,
-    Real & current_penalty,
-    Vector<Real> & contact_traction,
-    Vector<Real> & contact_opening) {
+    Vector<Real> & traction, Vector<Real> & opening,
+    Vector<Real> & opening_prec, const Vector<Real> & normal, Real & delta_max,
+    const Real & delta_c, const Vector<Real> & insertion_stress,
+    const Real & sigma_c, Vector<Real> & normal_opening,
+    Vector<Real> & tangential_opening, Real & normal_opening_norm,
+    Real & tangential_opening_norm, Real & damage, bool & penetration,
+    bool & reduction_penalty, Real & current_penalty,
+    Vector<Real> & contact_traction, Vector<Real> & contact_opening) {
 
   /// compute normal and tangential opening vectors
   normal_opening_norm = opening.dot(normal);
-  normal_opening  = normal;
+  normal_opening = normal;
   normal_opening *= normal_opening_norm;
 
-  tangential_opening  = opening;
+  tangential_opening = opening;
   tangential_opening -= normal_opening;
   tangential_opening_norm = tangential_opening.norm();
 
   /**
    * compute effective opening displacement
    * @f$ \delta = \sqrt{
    * \frac{\beta^2}{\kappa^2} \Delta_t^2 + \Delta_n^2 } @f$
    */
-  Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
+  Real delta =
+      tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
   penetration = normal_opening_norm < 0.0;
-  if (this->contact_after_breaking == false && Math::are_float_equal(damage, 1.))
+  if (this->contact_after_breaking == false &&
+      Math::are_float_equal(damage, 1.))
     penetration = false;
 
-  /** 
+  /**
    * if during the convergence loop a cohesive element continues to
    * jumps from penetration to opening, and convergence is not
    * reached, its penalty parameter will be reduced in the
    * recomputation of the same incremental step. recompute is set
    * equal to true when convergence is not reached in the
    * solveStepCohesive function and the execution of the program
    * goes back to the main file where the variable load_reduction
    * is set equal to true.
    */
-    
+
   Real normal_opening_prec_norm = opening_prec.dot(normal);
   opening_prec = opening;
 
   if (!this->model->isDefaultSolverExplicit() && !this->recompute)
     if ((normal_opening_prec_norm * normal_opening_norm) < 0.0) {
       reduction_penalty = true;
     }
 
   if (penetration) {
-    if (this->recompute && reduction_penalty){
+    if (this->recompute && reduction_penalty) {
       /// the penalty parameter is locally reduced
       current_penalty = this->penalty / 100.;
-    }
-    else
+    } else
       current_penalty = this->penalty;
 
     /// use penalty coefficient in case of penetration
     contact_traction = normal_opening;
     contact_traction *= current_penalty;
     contact_opening = normal_opening;
 
     /// don't consider penetration contribution for delta
     opening = tangential_opening;
     normal_opening.clear();
 
-  }
-  else {
+  } else {
     delta += normal_opening_norm * normal_opening_norm;
     contact_traction.clear();
     contact_opening.clear();
   }
 
   delta = std::sqrt(delta);
 
   /// update maximum displacement and damage
   delta_max = std::max(delta_max, delta);
   damage = std::min(delta_max / delta_c, Real(1.));
 
   /**
    * Compute traction @f$ \mathbf{T} = \left(
    * \frac{\beta^2}{\kappa} \Delta_t \mathbf{t} + \Delta_n
    * \mathbf{n} \right) \frac{\sigma_c}{\delta} \left( 1-
    * \frac{\delta}{\delta_c} \right)@f$
    */
 
   if (Math::are_float_equal(damage, 1.))
     traction.clear();
   else if (Math::are_float_equal(damage, 0.)) {
     if (penetration)
       traction.clear();
     else
       traction = insertion_stress;
-  }
-  else {
-    traction  = tangential_opening;
+  } else {
+    traction = tangential_opening;
     traction *= this->beta2_kappa;
     traction += normal_opening;
 
     AKANTU_DEBUG_ASSERT(delta_max != 0.,
-			"Division by zero, tolerance might be too low");
+                        "Division by zero, tolerance might be too low");
 
     traction *= sigma_c / delta_max * (1. - damage);
   }
 }
 
-
 /* -------------------------------------------------------------------------- */
-template<UInt dim>
+template <UInt dim>
 inline void MaterialCohesiveLinear<dim>::computeTangentTractionOnQuad(
-    Matrix<Real> & tangent,
-    Real & delta_max,
-    const Real & delta_c,
-    const Real & sigma_c,
-    Vector<Real> & opening,
-    const Vector<Real> & normal,
-    Vector<Real> & normal_opening,
-    Vector<Real> & tangential_opening,
-    Real & normal_opening_norm,
-    Real & tangential_opening_norm,
-    Real & damage,
-    bool & penetration,
-    bool & reduction_penalty,
-    Real & current_penalty,
+    Matrix<Real> & tangent, Real & delta_max, const Real & delta_c,
+    const Real & sigma_c, Vector<Real> & opening, const Vector<Real> & normal,
+    Vector<Real> & normal_opening, Vector<Real> & tangential_opening,
+    Real & normal_opening_norm, Real & tangential_opening_norm, Real & damage,
+    bool & penetration, bool & reduction_penalty, Real & current_penalty,
     Vector<Real> & contact_opening) {
 
   /**
    * During the update of the residual the interpenetrations are
    * stored in the array "contact_opening", therefore, in the case
    * of penetration, in the array "opening" there are only the
    * tangential components.
    */
   opening += contact_opening;
 
   /// compute normal and tangential opening vectors
   normal_opening_norm = opening.dot(normal);
   normal_opening = normal;
   normal_opening *= normal_opening_norm;
 
   tangential_opening = opening;
   tangential_opening -= normal_opening;
   tangential_opening_norm = tangential_opening.norm();
 
-  Real delta = tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
+  Real delta =
+      tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
   penetration = normal_opening_norm < 0.0;
-  if (this->contact_after_breaking == false && Math::are_float_equal(damage, 1.))
+  if (this->contact_after_breaking == false &&
+      Math::are_float_equal(damage, 1.))
     penetration = false;
 
   Real derivative = 0; // derivative = d(t/delta)/ddelta
   Real t = 0;
 
   Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
   n_outer_n.outerProduct(normal, normal);
 
-  if (penetration){
+  if (penetration) {
     if (this->recompute && reduction_penalty)
       current_penalty = this->penalty / 100.;
     else
       current_penalty = this->penalty;
 
     /// stiffness in compression given by the penalty parameter
     tangent += n_outer_n;
     tangent *= current_penalty;
 
     opening = tangential_opening;
     normal_opening_norm = opening.dot(normal);
     normal_opening = normal;
     normal_opening *= normal_opening_norm;
-  }
-  else{
+  } 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){
+  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){
+  } else if (delta < delta_max) {
     Real tmax = sigma_c * (1 - delta_max / delta_c);
     t = tmax / delta_max * delta;
   }
 
-
   /// computation of the derivative of the constitutive law (dT/ddelta)
   Matrix<Real> I(spatial_dimension, spatial_dimension);
   I.eye(this->beta2_kappa);
 
   Matrix<Real> nn(n_outer_n);
   nn *= (1. - this->beta2_kappa);
   nn += I;
-  nn *= t/delta;
+  nn *= t / delta;
 
   Vector<Real> t_tilde(normal_opening);
   t_tilde *= (1. - this->beta2_kappa2);
 
   Vector<Real> mm(opening);
   mm *= this->beta2_kappa2;
   t_tilde += mm;
 
   Vector<Real> t_hat(normal_opening);
   t_hat += this->beta2_kappa * tangential_opening;
 
   Matrix<Real> prov(spatial_dimension, spatial_dimension);
   prov.outerProduct(t_hat, t_tilde);
-  prov *= derivative/delta;
+  prov *= derivative / delta;
   prov += nn;
 
   Matrix<Real> prov_t = prov.transpose();
   tangent += prov_t;
 }
 
 /* -------------------------------------------------------------------------- */
 } // akantu
 
 /* -------------------------------------------------------------------------- */
 #endif //__AKANTU_MATERIAL_COHESIVE_LINEAR_INLINE_IMPL_CC__
diff --git a/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc b/src/model/solid_mechanics/solid_mechanics_model_cohesive/materials/constitutive_laws/material_cohesive_linear_uncoupled.cc
index f24dd6900..e7b16ffe7 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,596 +1,596 @@
 /**
  * @file   material_cohesive_linear_uncoupled.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Wed Feb 22 2012
  * @date last modification: Thu Jan 14 2016
  *
  * @brief  Linear irreversible cohesive law of mixed mode loading with
  * random stress definition for extrinsic type
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <numeric>
 
 /* -------------------------------------------------------------------------- */
 #include "material_cohesive_linear_uncoupled.hh"
 #include "solid_mechanics_model_cohesive.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 MaterialCohesiveLinearUncoupled<spatial_dimension>::
     MaterialCohesiveLinearUncoupled(SolidMechanicsModel & model, const ID & id)
     : MaterialCohesiveLinear<spatial_dimension>(model, id),
       delta_n_max("delta_n_max", *this), delta_t_max("delta_t_max", *this),
       damage_n("damage_n", *this), damage_t("damage_t", *this) {
 
   AKANTU_DEBUG_IN();
 
   this->registerParam(
       "roughness", R, Real(1.), _pat_parsable | _pat_readable,
       "Roughness to define coupling between mode II and mode I");
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearUncoupled<spatial_dimension>::initMaterial() {
   AKANTU_DEBUG_IN();
 
   MaterialCohesiveLinear<spatial_dimension>::initMaterial();
 
   delta_n_max.initialize(1);
   delta_t_max.initialize(1);
   damage_n.initialize(1);
   damage_t.initialize(1);
 
   delta_n_max.initializeHistory();
   delta_t_max.initializeHistory();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearUncoupled<spatial_dimension>::computeTraction(
     const Array<Real> &, ElementType el_type, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   delta_n_max.resize();
   delta_t_max.resize();
   damage_n.resize();
   damage_t.resize();
 
   /// define iterators
-  Array<Real>::vector_iterator traction_it =
+  auto traction_it =
       this->tractions(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::vector_iterator traction_end =
+  auto traction_end =
       this->tractions(el_type, ghost_type).end(spatial_dimension);
 
-  Array<Real>::vector_iterator opening_it =
+  auto opening_it =
       this->opening(el_type, ghost_type).begin(spatial_dimension);
 
   /// opening_prec is the opening of the previous step in the
   /// Newton-Raphson loop
-  Array<Real>::vector_iterator opening_prec_it =
+  auto opening_prec_it =
       this->opening_prec(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::vector_iterator contact_traction_it =
+  auto contact_traction_it =
       this->contact_tractions(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::vector_iterator contact_opening_it =
+  auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
-  Array<Real>::const_vector_iterator normal_it =
+  auto normal_it =
       this->normal.begin(spatial_dimension);
 
   Array<Real>::scalar_iterator sigma_c_it =
       this->sigma_c_eff(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator delta_n_max_it =
       delta_n_max(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator delta_t_max_it =
       delta_t_max(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator delta_c_it =
       this->delta_c_eff(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator damage_n_it =
       damage_n(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator damage_t_it =
       damage_t(el_type, ghost_type).begin();
 
-  Array<Real>::vector_iterator insertion_stress_it =
+  auto insertion_stress_it =
       this->insertion_stress(el_type, ghost_type).begin(spatial_dimension);
 
   Array<bool>::scalar_iterator reduction_penalty_it =
       this->reduction_penalty(el_type, ghost_type).begin();
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   if (!this->model->isDefaultSolverExplicit()) {
     this->delta_n_max(el_type, ghost_type)
         .copy(this->delta_n_max.previous(el_type, ghost_type));
     this->delta_t_max(el_type, ghost_type)
         .copy(this->delta_t_max.previous(el_type, ghost_type));
   }
 
   /// loop on each quadrature point
   for (; traction_it != traction_end;
        ++traction_it, ++opening_it, ++opening_prec_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, ++reduction_penalty_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     Real current_penalty = 0.;
     Real delta_c2_R2 = *delta_c_it * (*delta_c_it) / R / R;
 
     /// compute normal and tangential opening vectors
     normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening = *normal_it;
     normal_opening *= normal_opening_norm;
 
     //    std::cout<< "normal_opening_norm = " << normal_opening_norm
     //    <<std::endl;
 
     Vector<Real> tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
     tangential_opening_norm = tangential_opening.norm();
 
     /// compute effective opening displacement
     Real delta_n =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
     Real delta_t =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
     penetration = normal_opening_norm < 0.0;
     if (this->contact_after_breaking == false &&
         Math::are_float_equal(*damage_n_it, 1.))
       penetration = false;
 
     /**
      * If during the convergence loop a cohesive element continues to
      * jumps from penetration to opening, and convergence is not
      * reached, its penalty parameter will be reduced in the
      * recomputation of the same incremental step. Recompute is set
      * equal to true when convergence is not reached in the
      * solveStepCohesive function and the execution of the program
      * goes back to the main file where the variable load_reduction
      * is set equal to true.
      */
     Real normal_opening_prec_norm = opening_prec_it->dot(*normal_it);
     //    Vector<Real> normal_opening_prec  = *normal_it;
     //    normal_opening_prec *= normal_opening_prec_norm;
     if (!this->model->isDefaultSolverExplicit()) // && !this->recompute)
       if ((normal_opening_prec_norm * normal_opening_norm) < 0.0)
         *reduction_penalty_it = true;
 
     *opening_prec_it = *opening_it;
 
     if (penetration) {
       if (this->recompute && *reduction_penalty_it) {
         /// the penalty parameter is locally reduced
         current_penalty = this->penalty / 100.;
       } else
         current_penalty = this->penalty;
 
       /// use penalty coefficient in case of penetration
       *contact_traction_it = normal_opening;
       *contact_traction_it *= current_penalty;
       *contact_opening_it = normal_opening;
 
       /// don't consider penetration contribution for delta
       *opening_it = tangential_opening;
       normal_opening.clear();
 
     } else {
       delta_n += normal_opening_norm * normal_opening_norm;
       delta_t += normal_opening_norm * normal_opening_norm * delta_c2_R2;
       contact_traction_it->clear();
       contact_opening_it->clear();
     }
 
     delta_n = std::sqrt(delta_n);
     delta_t = std::sqrt(delta_t);
 
     /// update maximum displacement and damage
     *delta_n_max_it = std::max(*delta_n_max_it, delta_n);
     *damage_n_it = std::min(*delta_n_max_it / *delta_c_it, Real(1.));
 
     *delta_t_max_it = std::max(*delta_t_max_it, delta_t);
     *damage_t_it = std::min(*delta_t_max_it / *delta_c_it, Real(1.));
 
     Vector<Real> normal_traction(spatial_dimension);
     Vector<Real> shear_traction(spatial_dimension);
 
     /// NORMAL TRACTIONS
     if (Math::are_float_equal(*damage_n_it, 1.))
       normal_traction.clear();
     else if (Math::are_float_equal(*damage_n_it, 0.)) {
       if (penetration)
         normal_traction.clear();
       else
         normal_traction = *insertion_stress_it;
     } else {
       // the following formulation holds both in loading and in
       // unloading-reloading
       normal_traction = normal_opening;
 
       AKANTU_DEBUG_ASSERT(*delta_n_max_it != 0.,
                           "Division by zero, tolerance might be too low");
 
       normal_traction *= *sigma_c_it / (*delta_n_max_it) * (1. - *damage_n_it);
     }
 
     /// SHEAR TRACTIONS
     if (Math::are_float_equal(*damage_t_it, 1.))
       shear_traction.clear();
     else if (Math::are_float_equal(*damage_t_it, 0.)) {
       shear_traction.clear();
     } else {
       shear_traction = tangential_opening;
 
       AKANTU_DEBUG_ASSERT(*delta_t_max_it != 0.,
                           "Division by zero, tolerance might be too low");
 
       shear_traction *= this->beta2_kappa;
       shear_traction *= *sigma_c_it / (*delta_t_max_it) * (1. - *damage_t_it);
     }
 
     *traction_it = normal_traction;
     *traction_it += shear_traction;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearUncoupled<spatial_dimension>::checkDeltaMax(
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /**
    * This function set a predefined value to the parameter
    * delta_max_prev of the elements that have been inserted in the
    * last loading step for which convergence has not been
    * reached. This is done before reducing the loading and re-doing
    * the step.  Otherwise, the updating of delta_max_prev would be
    * done with reference to the non-convergent solution. In this
    * function also other variables related to the contact and
    * friction behavior are correctly set.
    */
 
   Mesh & mesh = this->fem_cohesive.getMesh();
   Mesh::type_iterator it =
       mesh.firstType(spatial_dimension, ghost_type, _ek_cohesive);
   Mesh::type_iterator last_type =
       mesh.lastType(spatial_dimension, ghost_type, _ek_cohesive);
 
   /**
    * the variable "recompute" is set to true to activate the
    * procedure that reduces the penalty parameter for
    * compression. This procedure is available only during the phase of
    * load_reduction, that has to be set in the main file. The
    * penalty parameter will be reduced only for the elements having
    * reduction_penalty = true.
    */
   this->recompute = true;
 
   for (; it != last_type; ++it) {
     Array<UInt> & elem_filter = this->element_filter(*it, ghost_type);
 
     UInt nb_element = elem_filter.size();
     if (nb_element == 0)
       continue;
 
     ElementType el_type = *it;
 
     //    std::cout << "element type: " << el_type << std::endl;
 
     /// define iterators
     Array<Real>::scalar_iterator delta_n_max_it =
         delta_n_max(el_type, ghost_type).begin();
 
     Array<Real>::scalar_iterator delta_n_max_end =
         delta_n_max(el_type, ghost_type).end();
 
     Array<Real>::scalar_iterator delta_n_max_prev_it =
         delta_n_max.previous(el_type, ghost_type).begin();
 
     Array<Real>::scalar_iterator delta_t_max_it =
         delta_t_max(el_type, ghost_type).begin();
 
     Array<Real>::scalar_iterator delta_t_max_prev_it =
         delta_t_max.previous(el_type, ghost_type).begin();
 
     Array<Real>::scalar_iterator delta_c_it =
         this->delta_c_eff(el_type, ghost_type).begin();
 
-    Array<Real>::vector_iterator opening_prec_it =
+    auto opening_prec_it =
         this->opening_prec(el_type, ghost_type).begin(spatial_dimension);
 
-    Array<Real>::vector_iterator opening_prec_prev_it =
+    auto opening_prec_prev_it =
         this->opening_prec.previous(el_type, ghost_type)
             .begin(spatial_dimension);
 
     Int it = 0;
 
     /// loop on each quadrature point
     for (; delta_n_max_it != delta_n_max_end;
          ++delta_n_max_it, ++delta_t_max_it, ++delta_c_it,
          ++delta_n_max_prev_it, ++delta_t_max_prev_it, ++opening_prec_it,
          ++opening_prec_prev_it) {
 
       ++it;
 
       if (*delta_n_max_prev_it == 0) {
         /// elements inserted in the last incremental step, that did
         /// not converge
         *delta_n_max_it = *delta_c_it / 1000.;
       } else
         /// elements introduced in previous incremental steps, for
         /// which a correct value of delta_max_prev already exists
         *delta_n_max_it = *delta_n_max_prev_it;
 
       if (*delta_t_max_prev_it == 0) {
         *delta_t_max_it = *delta_c_it * this->kappa / this->beta / 1000.;
       } else
         *delta_t_max_it = *delta_t_max_prev_it;
 
       /// in case convergence is not reached, set opening_prec to the
       /// value referred to the previous incremental step
       *opening_prec_it = *opening_prec_prev_it;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <UInt spatial_dimension>
 void MaterialCohesiveLinearUncoupled<spatial_dimension>::computeTangentTraction(
     const ElementType & el_type, Array<Real> & tangent_matrix,
     const Array<Real> &, GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   /// define iterators
   Array<Real>::matrix_iterator tangent_it =
       tangent_matrix.begin(spatial_dimension, spatial_dimension);
 
   Array<Real>::matrix_iterator tangent_end =
       tangent_matrix.end(spatial_dimension, spatial_dimension);
 
-  Array<Real>::const_vector_iterator normal_it =
+  auto normal_it =
       this->normal.begin(spatial_dimension);
 
-  Array<Real>::vector_iterator opening_it =
+  auto opening_it =
       this->opening(el_type, ghost_type).begin(spatial_dimension);
 
   /// NB: delta_max_it points on delta_max_previous, i.e. the
   /// delta_max related to the solution of the previous incremental
   /// step
   Array<Real>::scalar_iterator delta_n_max_it =
       delta_n_max.previous(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator delta_t_max_it =
       delta_t_max.previous(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator sigma_c_it =
       this->sigma_c_eff(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator delta_c_it =
       this->delta_c_eff(el_type, ghost_type).begin();
 
   Array<Real>::scalar_iterator damage_n_it =
       damage_n(el_type, ghost_type).begin();
 
-  Array<Real>::vector_iterator contact_opening_it =
+  auto contact_opening_it =
       this->contact_opening(el_type, ghost_type).begin(spatial_dimension);
 
   Array<bool>::scalar_iterator reduction_penalty_it =
       this->reduction_penalty(el_type, ghost_type).begin();
 
   Vector<Real> normal_opening(spatial_dimension);
   Vector<Real> tangential_opening(spatial_dimension);
 
   for (; tangent_it != tangent_end;
        ++tangent_it, ++normal_it, ++opening_it, ++sigma_c_it, ++delta_c_it,
        ++delta_n_max_it, ++delta_t_max_it, ++damage_n_it, ++contact_opening_it,
        ++reduction_penalty_it) {
 
     Real normal_opening_norm, tangential_opening_norm;
     bool penetration;
     Real current_penalty = 0.;
     Real delta_c2_R2 = *delta_c_it * (*delta_c_it) / R / R;
 
     /**
      * During the update of the residual the interpenetrations are
      * stored in the array "contact_opening", therefore, in the case
      * of penetration, in the array "opening" there are only the
      * tangential components.
      */
     *opening_it += *contact_opening_it;
 
     /// compute normal and tangential opening vectors
     normal_opening_norm = opening_it->dot(*normal_it);
     Vector<Real> normal_opening = *normal_it;
     normal_opening *= normal_opening_norm;
 
     Vector<Real> tangential_opening = *opening_it;
     tangential_opening -= normal_opening;
     tangential_opening_norm = tangential_opening.norm();
 
     Real delta_n =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
     Real delta_t =
         tangential_opening_norm * tangential_opening_norm * this->beta2_kappa2;
 
     penetration = normal_opening_norm < 0.0;
     if (this->contact_after_breaking == false &&
         Math::are_float_equal(*damage_n_it, 1.))
       penetration = false;
 
     Real derivative = 0; // derivative = d(t/delta)/ddelta
     Real T = 0;
 
     /// TANGENT STIFFNESS FOR NORMAL TRACTIONS
     Matrix<Real> n_outer_n(spatial_dimension, spatial_dimension);
     n_outer_n.outerProduct(*normal_it, *normal_it);
 
     if (penetration) {
       if (this->recompute && *reduction_penalty_it)
         current_penalty = this->penalty / 100.;
       else
         current_penalty = this->penalty;
 
       /// stiffness in compression given by the penalty parameter
       *tangent_it = n_outer_n;
       *tangent_it *= current_penalty;
 
       *opening_it = tangential_opening;
       normal_opening.clear();
     } else {
       delta_n += normal_opening_norm * normal_opening_norm;
       delta_n = std::sqrt(delta_n);
 
       delta_t += normal_opening_norm * normal_opening_norm * delta_c2_R2;
 
       /**
        * Delta has to be different from 0 to have finite values of
        * tangential stiffness.  At the element insertion, delta =
        * 0. Therefore, a fictictious value is defined, for the
        * evaluation of the first value of K.
        */
       if (delta_n < Math::getTolerance())
         delta_n = *delta_c_it / 1000.;
 
       // loading
       if (delta_n >= *delta_n_max_it) {
         if (delta_n <= *delta_c_it) {
           derivative = -(*sigma_c_it) / (delta_n * delta_n);
           T = *sigma_c_it * (1 - delta_n / *delta_c_it);
         } else {
           derivative = 0.;
           T = 0.;
         }
         // unloading-reloading
       } else if (delta_n < *delta_n_max_it) {
         Real T_max = *sigma_c_it * (1 - *delta_n_max_it / *delta_c_it);
         derivative = 0.;
         T = T_max / *delta_n_max_it * delta_n;
       }
 
       /// computation of the derivative of the constitutive law (dT/ddelta)
       Matrix<Real> nn(n_outer_n);
       nn *= T / delta_n;
 
       Vector<Real> Delta_tilde(normal_opening);
       Delta_tilde *= (1. - this->beta2_kappa2);
       Vector<Real> mm(*opening_it);
       mm *= this->beta2_kappa2;
       Delta_tilde += mm;
 
       const Vector<Real> & Delta_hat(normal_opening);
       Matrix<Real> prov(spatial_dimension, spatial_dimension);
       prov.outerProduct(Delta_hat, Delta_tilde);
       prov *= derivative / delta_n;
       prov += nn;
 
       Matrix<Real> prov_t = prov.transpose();
 
       *tangent_it = prov_t;
     }
 
     derivative = 0.;
     T = 0.;
 
     /// TANGENT STIFFNESS FOR SHEAR TRACTIONS
     delta_t = std::sqrt(delta_t);
 
     /**
      * Delta has to be different from 0 to have finite values of
      * tangential stiffness.  At the element insertion, delta =
      * 0. Therefore, a fictictious value is defined, for the
      * evaluation of the first value of K.
      */
     if (delta_t < Math::getTolerance())
       delta_t = *delta_c_it / 1000.;
 
     // loading
     if (delta_t >= *delta_t_max_it) {
       if (delta_t <= *delta_c_it) {
         derivative = -(*sigma_c_it) / (delta_t * delta_t);
         T = *sigma_c_it * (1 - delta_t / *delta_c_it);
       } else {
         derivative = 0.;
         T = 0.;
       }
       // unloading-reloading
     } else if (delta_t < *delta_t_max_it) {
       Real T_max = *sigma_c_it * (1 - *delta_t_max_it / *delta_c_it);
       derivative = 0.;
       T = T_max / *delta_t_max_it * delta_t;
     }
 
     /// computation of the derivative of the constitutive law (dT/ddelta)
     Matrix<Real> I(spatial_dimension, spatial_dimension);
     I.eye();
     Matrix<Real> nn(n_outer_n);
     I -= nn;
     I *= T / delta_t;
 
     Vector<Real> Delta_tilde(normal_opening);
     Delta_tilde *= (delta_c2_R2 - this->beta2_kappa2);
     Vector<Real> mm(*opening_it);
     mm *= this->beta2_kappa2;
     Delta_tilde += mm;
 
     Vector<Real> Delta_hat(tangential_opening);
     Delta_hat *= this->beta2_kappa;
     Matrix<Real> prov(spatial_dimension, spatial_dimension);
     prov.outerProduct(Delta_hat, Delta_tilde);
     prov *= derivative / delta_t;
     prov += I;
 
     Matrix<Real> prov_t = prov.transpose();
 
     *tangent_it += prov_t;
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 
 INSTANTIATE_MATERIAL(cohesive_linear_uncoupled, MaterialCohesiveLinearUncoupled);
 
 } // akantu
diff --git a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh
index 24d4b45c6..f4c3c121d 100644
--- a/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh
+++ b/src/model/structural_mechanics/structural_elements/structural_element_bernoulli_beam_3.hh
@@ -1,190 +1,190 @@
 /**
  * @file   structural_element_bernoulli_beam_3.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
  * @date creation  Tue Sep 19 2017
  *
  * @brief Specific functions for bernoulli beam 3d
  *
  * @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/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__
 #define __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__
 
 #include "structural_mechanics_model.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void StructuralMechanicsModel::assembleMass<_bernoulli_beam_3>() {
   AKANTU_DEBUG_IN();
 #if 0
   GhostType ghost_type = _not_ghost;
   ElementType type = _bernoulli_beam_3;
   MyFEEngineType & fem = getFEEngineClass<MyFEEngineType>();
   UInt nb_element = getFEEngine().getMesh().getNbElement(type);
   UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   UInt nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
   UInt nb_fields_to_interpolate =
       getTangentStiffnessVoigtSize<_bernoulli_beam_3>();
 
   UInt nt_n_field_size = nb_degree_of_freedom * nb_nodes_per_element;
 
   Array<Real> * n =
       new Array<Real>(nb_element * nb_quadrature_points,
                       nb_fields_to_interpolate * nt_n_field_size, "N");
   n->clear();
   Array<Real> * rho_field =
       new Array<Real>(nb_element * nb_quadrature_points, "Rho");
   rho_field->clear();
   computeRho(*rho_field, type, _not_ghost);
 
   /* --------------------------------------------------------------------------
    */
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           0, 0, 0, true, ghost_type); // Ni ui ->         u
 
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           1, 1, 1, true, ghost_type); // Mi vi ->         v
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           2, 5, 1, true, ghost_type); // Li Theta_z_i ->  v
 
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           1, 2, 2, true, ghost_type); // Mi wi ->        w
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           2, 4, 2, false, ghost_type); // -Li Theta_y_i ->  w
 
   fem.computeShapesMatrix(type, nb_degree_of_freedom, nb_nodes_per_element, n,
                           0, 3, 3, true, ghost_type); // Ni Theta_x_i->Theta_x
   /* --------------------------------------------------------------------------
    */
 
   fem.assembleFieldMatrix(*rho_field, nb_degree_of_freedom, *mass_matrix, n,
                           rotation_matrix, type, ghost_type);
 
   delete n;
   delete rho_field;
 #endif
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void StructuralMechanicsModel::computeRotationMatrix<_bernoulli_beam_3>(
     Array<Real> & rotations) {
   ElementType type = _bernoulli_beam_3;
   Mesh & mesh = getFEEngine().getMesh();
   UInt nb_element = mesh.getNbElement(type);
 
-  Array<Real>::vector_iterator n_it =
+  auto n_it =
       mesh.getNormals(type).begin(spatial_dimension);
   Array<UInt>::iterator<Vector<UInt> > connec_it =
       mesh.getConnectivity(type).begin(2);
-  Array<Real>::vector_iterator nodes_it =
+  auto nodes_it =
       mesh.getNodes().begin(spatial_dimension);
 
   Matrix<Real> Pe(spatial_dimension, spatial_dimension);
   Matrix<Real> Pg(spatial_dimension, spatial_dimension);
   Matrix<Real> inv_Pg(spatial_dimension, spatial_dimension);
   Vector<Real> x_n(spatial_dimension); // x vect n
 
   Array<Real>::matrix_iterator R_it =
       rotations.begin(nb_degree_of_freedom, nb_degree_of_freedom);
 
   for (UInt e = 0; e < nb_element; ++e, ++n_it, ++connec_it, ++R_it) {
     Vector<Real> & n = *n_it;
     Matrix<Real> & R = *R_it;
     Vector<UInt> & connec = *connec_it;
 
     Vector<Real> x;
     x = nodes_it[connec(1)]; // X2
     Vector<Real> y;
     y = nodes_it[connec(0)]; // X1
 
     Real l = x.distance(y);
     x -= y; // X2 - X1
     x_n.crossProduct(x, n);
 
     Pe.eye();
     Pe(0, 0) *= l;
     Pe(1, 1) *= -l;
 
     Pg(0, 0) = x(0);
     Pg(0, 1) = x_n(0);
     Pg(0, 2) = n(0);
     Pg(1, 0) = x(1);
     Pg(1, 1) = x_n(1);
     Pg(1, 2) = n(1);
     Pg(2, 0) = x(2);
     Pg(2, 1) = x_n(2);
     Pg(2, 2) = n(2);
 
     inv_Pg.inverse(Pg);
 
     Pe *= inv_Pg;
     for (UInt i = 0; i < spatial_dimension; ++i) {
       for (UInt j = 0; j < spatial_dimension; ++j) {
         R(i, j) = Pe(i, j);
         R(i + spatial_dimension, j + spatial_dimension) = Pe(i, j);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 void StructuralMechanicsModel::computeTangentModuli<_bernoulli_beam_3>(
     Array<Real> & tangent_moduli) {
   UInt nb_element = getFEEngine().getMesh().getNbElement(_bernoulli_beam_3);
   UInt nb_quadrature_points =
       getFEEngine().getNbIntegrationPoints(_bernoulli_beam_3);
   UInt tangent_size = 4;
 
   tangent_moduli.clear();
   Array<Real>::matrix_iterator D_it =
       tangent_moduli.begin(tangent_size, tangent_size);
 
   for (UInt e = 0; e < nb_element; ++e) {
     UInt mat = element_material(_bernoulli_beam_3, _not_ghost)(e);
     Real E = materials[mat].E;
     Real A = materials[mat].A;
     Real Iz = materials[mat].Iz;
     Real Iy = materials[mat].Iy;
     Real GJ = materials[mat].GJ;
     for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_it) {
       Matrix<Real> & D = *D_it;
       D(0, 0) = E * A;
       D(1, 1) = E * Iz;
       D(2, 2) = E * Iy;
       D(3, 3) = GJ;
     }
   }
 }
 
 
 }  // akantu
 
 #endif /* __AKANTU_STRUCTURAL_ELEMENT_BERNOULLI_BEAM_3_HH__ */
diff --git a/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc b/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
index 0e33ccd73..172a8d000 100644
--- a/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
+++ b/src/model/structural_mechanics/structural_mechanics_model_inline_impl.cc
@@ -1,361 +1,361 @@
 /**
  * @file   structural_mechanics_model_inline_impl.cc
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Sébastien Hartmann <sebastien.hartmann@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Damien Spielmann <damien.spielmann@epfl.ch>
  *
  * @date creation: Fri Jul 15 2011
  * @date last modification: Thu Oct 15 2015
  *
  * @brief  Implementation of inline functions of StructuralMechanicsModel
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "structural_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_STRUCTURAL_MECHANICS_MODEL_INLINE_IMPL_CC__
 #define __AKANTU_STRUCTURAL_MECHANICS_MODEL_INLINE_IMPL_CC__
 
 namespace akantu {
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::computeTangentModuli(
     Array<Real> & /*tangent_moduli*/) {
   AKANTU_TO_IMPLEMENT();
 }
 } // namespace akantu
 
 #include "structural_element_bernoulli_beam_2.hh"
 #include "structural_element_bernoulli_beam_3.hh"
 #include "structural_element_kirchhoff_shell.hh"
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::assembleStiffnessMatrix() {
   AKANTU_DEBUG_IN();
 
   auto nb_element = getFEEngine().getMesh().getNbElement(type);
   auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   auto nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
   auto tangent_size = ElementClass<type>::getNbStressComponents();
 
   auto tangent_moduli = std::make_unique<Array<Real>>(
       nb_element * nb_quadrature_points, tangent_size * tangent_size,
       "tangent_stiffness_matrix");
   computeTangentModuli<type>(*tangent_moduli);
 
   /// compute @f$\mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   UInt bt_d_b_size = nb_degree_of_freedom * nb_nodes_per_element;
 
   auto bt_d_b = std::make_unique<Array<Real>>(
       nb_element * nb_quadrature_points, bt_d_b_size * bt_d_b_size, "B^t*D*B");
 
   const auto & b = getFEEngine().getShapesDerivatives(type);
 
   Matrix<Real> BtD(bt_d_b_size, tangent_size);
 
   for (auto && tuple :
        zip(make_view(b, tangent_size, bt_d_b_size),
            make_view(*tangent_moduli, tangent_size, tangent_size),
            make_view(*bt_d_b, bt_d_b_size, bt_d_b_size))) {
     auto & B = std::get<0>(tuple);
     auto & D = std::get<1>(tuple);
     auto & BtDB = std::get<2>(tuple);
     BtD.mul<true, false>(B, D);
     BtDB.template mul<false, false>(BtD, B);
   }
 
   /// compute @f$ k_e = \int_e \mathbf{B}^t * \mathbf{D} * \mathbf{B}@f$
   auto int_bt_d_b = std::make_unique<Array<Real>>(
       nb_element, bt_d_b_size * bt_d_b_size, "int_B^t*D*B");
 
   getFEEngine().integrate(*bt_d_b, *int_bt_d_b, bt_d_b_size * bt_d_b_size,
                           type);
 
   getDOFManager().assembleElementalMatricesToMatrix(
       "K", "displacement", *int_bt_d_b, type, _not_ghost, _symmetric);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::computeStressOnQuad() {
   AKANTU_DEBUG_IN();
 
   Array<Real> & sigma = stress(type, _not_ghost);
 
   auto nb_element = mesh.getNbElement(type);
   auto nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
   auto nb_quadrature_points = getFEEngine().getNbIntegrationPoints(type);
   auto tangent_size = ElementClass<type>::getNbStressComponents();
 
   auto tangent_moduli = std::make_unique<Array<Real>>(
       nb_element * nb_quadrature_points, tangent_size * tangent_size,
       "tangent_stiffness_matrix");
 
   computeTangentModuli<type>(*tangent_moduli);
 
   /// compute DB
   auto d_b_size = nb_degree_of_freedom * nb_nodes_per_element;
 
   auto d_b = std::make_unique<Array<Real>>(nb_element * nb_quadrature_points,
                                            d_b_size * tangent_size, "D*B");
 
   const auto & b = getFEEngine().getShapesDerivatives(type);
 
   auto B = b.begin(tangent_size, d_b_size);
   auto D = tangent_moduli->begin(tangent_size, tangent_size);
   auto D_B = d_b->begin(tangent_size, d_b_size);
 
   for (UInt e = 0; e < nb_element; ++e) {
     for (UInt q = 0; q < nb_quadrature_points; ++q, ++B, ++D, ++D_B) {
       D_B->template mul<false, false>(*D, *B);
     }
   }
 
   /// compute DBu
   D_B = d_b->begin(tangent_size, d_b_size);
   auto DBu = sigma.begin(tangent_size);
   Vector<Real> ul(d_b_size);
 
   Array<Real> u_el(0, d_b_size);
   FEEngine::extractNodalToElementField(mesh, *displacement_rotation, u_el,
                                        type);
 
   auto ug = u_el.begin(d_b_size);
   auto T = rotation_matrix(type).begin(d_b_size, d_b_size);
 
   for (UInt e = 0; e < nb_element; ++e, ++T, ++ug) {
     ul.mul<false>(*T, *ug);
     for (UInt q = 0; q < nb_quadrature_points; ++q, ++D_B, ++DBu) {
       DBu->template mul<false>(*D_B, ul);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::computeForcesByLocalTractionArray(
     const Array<Real> & tractions) {
   AKANTU_DEBUG_IN();
 
 #if 0
   UInt nb_element = getFEEngine().getMesh().getNbElement(type);
   UInt nb_nodes_per_element =
       getFEEngine().getMesh().getNbNodesPerElement(type);
   UInt nb_quad = getFEEngine().getNbIntegrationPoints(type);
 
   // check dimension match
   AKANTU_DEBUG_ASSERT(
       Mesh::getSpatialDimension(type) == getFEEngine().getElementDimension(),
       "element type dimension does not match the dimension of boundaries : "
           << getFEEngine().getElementDimension()
           << " != " << Mesh::getSpatialDimension(type));
 
   // check size of the vector
   AKANTU_DEBUG_ASSERT(
       tractions.size() == nb_quad * nb_element,
       "the size of the vector should be the total number of quadrature points");
 
   // check number of components
   AKANTU_DEBUG_ASSERT(tractions.getNbComponent() == nb_degree_of_freedom,
                       "the number of components should be the spatial "
                       "dimension of the problem");
 
   Array<Real> Nvoigt(nb_element * nb_quad, nb_degree_of_freedom *
                                                nb_degree_of_freedom *
                                                nb_nodes_per_element);
   transferNMatrixToSymVoigtNMatrix<type>(Nvoigt);
 
   Array<Real>::const_matrix_iterator N_it = Nvoigt.begin(
       nb_degree_of_freedom, nb_degree_of_freedom * nb_nodes_per_element);
   Array<Real>::const_matrix_iterator T_it =
       rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element,
                                   nb_degree_of_freedom * nb_nodes_per_element);
-  Array<Real>::const_vector_iterator te_it =
+  auto te_it =
       tractions.begin(nb_degree_of_freedom);
 
   Array<Real> funct(nb_element * nb_quad,
                     nb_degree_of_freedom * nb_nodes_per_element, 0.);
   Array<Real>::iterator<Vector<Real>> Fe_it =
       funct.begin(nb_degree_of_freedom * nb_nodes_per_element);
 
   Vector<Real> fe(nb_degree_of_freedom * nb_nodes_per_element);
   for (UInt e = 0; e < nb_element; ++e, ++T_it) {
     const Matrix<Real> & T = *T_it;
     for (UInt q = 0; q < nb_quad; ++q, ++N_it, ++te_it, ++Fe_it) {
       const Matrix<Real> & N = *N_it;
       const Vector<Real> & te = *te_it;
       Vector<Real> & Fe = *Fe_it;
 
       // compute N^t tl
       fe.mul<true>(N, te);
       // turn N^t tl back in the global referential
       Fe.mul<true>(T, fe);
     }
   }
 
   // allocate the vector that will contain the integrated values
   std::stringstream name;
   name << id << type << ":integral_boundary";
   Array<Real> int_funct(nb_element, nb_degree_of_freedom * nb_nodes_per_element,
                         name.str());
 
   // do the integration
   getFEEngine().integrate(funct, int_funct,
                           nb_degree_of_freedom * nb_nodes_per_element, type);
 
   // assemble the result into force vector
   getFEEngine().assembleArray(int_funct, *force_momentum,
                               dof_synchronizer->getLocalDOFEquationNumbers(),
                               nb_degree_of_freedom, type);
 #endif
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type>
 void StructuralMechanicsModel::computeForcesByGlobalTractionArray(
     const Array<Real> & traction_global) {
   AKANTU_DEBUG_IN();
 #if 0
   UInt nb_element = mesh.getNbElement(type);
   UInt nb_quad = getFEEngine().getNbIntegrationPoints(type);
   UInt nb_nodes_per_element =
       getFEEngine().getMesh().getNbNodesPerElement(type);
 
   std::stringstream name;
   name << id << ":structuralmechanics:imposed_linear_load";
   Array<Real> traction_local(nb_element * nb_quad, nb_degree_of_freedom,
                              name.str());
 
   Array<Real>::const_matrix_iterator T_it =
       rotation_matrix(type).begin(nb_degree_of_freedom * nb_nodes_per_element,
                                   nb_degree_of_freedom * nb_nodes_per_element);
 
   Array<Real>::const_iterator<Vector<Real>> Te_it =
       traction_global.begin(nb_degree_of_freedom);
   Array<Real>::iterator<Vector<Real>> te_it =
       traction_local.begin(nb_degree_of_freedom);
 
   Matrix<Real> R(nb_degree_of_freedom, nb_degree_of_freedom);
   for (UInt e = 0; e < nb_element; ++e, ++T_it) {
     const Matrix<Real> & T = *T_it;
     for (UInt i = 0; i < nb_degree_of_freedom; ++i)
       for (UInt j = 0; j < nb_degree_of_freedom; ++j)
         R(i, j) = T(i, j);
 
     for (UInt q = 0; q < nb_quad; ++q, ++Te_it, ++te_it) {
       const Vector<Real> & Te = *Te_it;
       Vector<Real> & te = *te_it;
       // turn the traction in the local referential
       te.mul<false>(R, Te);
     }
   }
 
   computeForcesByLocalTractionArray<type>(traction_local);
 #endif
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * @param myf pointer  to a function that fills a  vector/tensor with respect to
  * passed coordinates
  */
 #if 0
 template <ElementType type>
 inline void StructuralMechanicsModel::computeForcesFromFunction(
     BoundaryFunction myf, BoundaryFunctionType function_type) {
   /** function type is
    ** _bft_forces : linear load is given
    ** _bft_stress : stress function is given -> Not already done for this kind
    *of model
    */
 
   std::stringstream name;
   name << id << ":structuralmechanics:imposed_linear_load";
   Array<Real> lin_load(0, nb_degree_of_freedom, name.str());
   name.clear();
 
   UInt offset = nb_degree_of_freedom;
 
   // prepare the loop over element types
   UInt nb_quad = getFEEngine().getNbIntegrationPoints(type);
   UInt nb_element = getFEEngine().getMesh().getNbElement(type);
 
   name.clear();
   name << id << ":structuralmechanics:quad_coords";
   Array<Real> quad_coords(nb_element * nb_quad, spatial_dimension,
                           "quad_coords");
 
   getFEEngineClass<MyFEEngineType>()
       .getShapeFunctions()
       .interpolateOnIntegrationPoints<type>(getFEEngine().getMesh().getNodes(),
                                             quad_coords, spatial_dimension);
   getFEEngineClass<MyFEEngineType>()
       .getShapeFunctions()
       .interpolateOnIntegrationPoints<type>(
           getFEEngine().getMesh().getNodes(), quad_coords, spatial_dimension,
           _not_ghost, empty_filter, true, 0, 1, 1);
   if (spatial_dimension == 3)
     getFEEngineClass<MyFEEngineType>()
         .getShapeFunctions()
         .interpolateOnIntegrationPoints<type>(
             getFEEngine().getMesh().getNodes(), quad_coords, spatial_dimension,
             _not_ghost, empty_filter, true, 0, 2, 2);
   lin_load.resize(nb_element * nb_quad);
   Real * imposed_val = lin_load.storage();
 
   /// sigma/load on each quadrature points
   Real * qcoord = quad_coords.storage();
   for (UInt el = 0; el < nb_element; ++el) {
     for (UInt q = 0; q < nb_quad; ++q) {
       myf(qcoord, imposed_val, NULL, 0);
       imposed_val += offset;
       qcoord += spatial_dimension;
     }
   }
 
   switch (function_type) {
   case _bft_traction_local:
     computeForcesByLocalTractionArray<type>(lin_load);
     break;
   case _bft_traction:
     computeForcesByGlobalTractionArray<type>(lin_load);
     break;
   default:
     break;
   }
 }
 #endif
 } // namespace akantu
 
 #endif /* __AKANTU_STRUCTURAL_MECHANICS_MODEL_INLINE_IMPL_CC__ */
diff --git a/test/test_model/test_model_solver/test_model_solver_my_model.hh b/test/test_model/test_model_solver/test_model_solver_my_model.hh
index 769a14e5f..9512d53d9 100644
--- a/test/test_model/test_model_solver/test_model_solver_my_model.hh
+++ b/test/test_model/test_model_solver/test_model_solver_my_model.hh
@@ -1,468 +1,468 @@
 /**
  * @file   test_dof_manager_default.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Feb 24 12:28:44 2016
  *
  * @brief  Test default dof manager
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "aka_iterators.hh"
 #include "data_accessor.hh"
 #include "dof_manager_default.hh"
 #include "element_synchronizer.hh"
 #include "mesh.hh"
 #include "model_solver.hh"
 #include "sparse_matrix.hh"
 #include "communicator.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 #ifndef __AKANTU_TEST_MODEL_SOLVER_MY_MODEL_HH__
 #define __AKANTU_TEST_MODEL_SOLVER_MY_MODEL_HH__
 
 /**
  *   =\o-----o-----o-> F
  *     |           |
  *     |---- L ----|
  */
 class MyModel : public ModelSolver, public DataAccessor<Element> {
 public:
   MyModel(Real F, Mesh & mesh, bool lumped)
       : ModelSolver(mesh, ModelType::_model, "model_solver", 0), nb_dofs(mesh.getNbNodes()),
         nb_elements(mesh.getNbElement()), E(1.), A(1.), rho(1.), lumped(lumped),
         mesh(mesh), displacement(nb_dofs, 1, "disp"),
         velocity(nb_dofs, 1, "velo"), acceleration(nb_dofs, 1, "accel"),
         blocked(nb_dofs, 1, "blocked"), forces(nb_dofs, 1, "force_ext"),
         internal_forces(nb_dofs, 1, "force_int"),
         stresses(nb_elements, 1, "stress"), strains(nb_elements, 1, "strain"),
         initial_lengths(nb_elements, 1, "L0") {
 
     this->initDOFManager();
     this->getDOFManager().registerDOFs("disp", displacement, _dst_nodal);
     this->getDOFManager().registerDOFsDerivative("disp", 1, velocity);
     this->getDOFManager().registerDOFsDerivative("disp", 2, acceleration);
     this->getDOFManager().registerBlockedDOFs("disp", blocked);
 
     displacement.set(0.);
     velocity.set(0.);
     acceleration.set(0.);
 
     forces.set(0.);
     blocked.set(false);
 
     UInt global_nb_nodes = mesh.getNbGlobalNodes();
     for (auto && n : arange(nb_dofs)) {
       auto global_id = mesh.getNodeGlobalId(n);
       if (global_id == (global_nb_nodes - 1))
         forces(n, _x) = F;
 
       if (global_id == 0)
         blocked(n, _x) = true;
     }
 
     auto cit = this->mesh.getConnectivity(_segment_2).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2).end(2);
     auto L_it = this->initial_lengths.begin();
 
     for (; cit != cend; ++cit, ++L_it) {
       const Vector<UInt> & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
       Real p1 = this->mesh.getNodes()(n1, _x);
       Real p2 = this->mesh.getNodes()(n2, _x);
 
       *L_it = std::abs(p2 - p1);
     }
 
     this->registerDataAccessor(*this);
     this->registerSynchronizer(
         const_cast<ElementSynchronizer &>(this->mesh.getElementSynchronizer()),
         _gst_user_1);
   }
 
   void assembleLumpedMass() {
     Array<Real> & M = this->getDOFManager().getLumpedMatrix("M");
     M.clear();
 
     this->assembleLumpedMass(_not_ghost);
     if (this->mesh.getNbElement(_segment_2, _ghost) > 0)
       this->assembleLumpedMass(_ghost);
 
     is_lumped_mass_assembled = true;
   }
 
   void assembleLumpedMass(const GhostType & ghost_type) {
     Array<Real> & M = this->getDOFManager().getLumpedMatrix("M");
 
     Array<Real> m_all_el(this->mesh.getNbElement(_segment_2, ghost_type), 2);
 
-    Array<Real>::vector_iterator m_it = m_all_el.begin(2);
+    auto m_it = m_all_el.begin(2);
 
     auto cit = this->mesh.getConnectivity(_segment_2, ghost_type).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2, ghost_type).end(2);
 
     for (; cit != cend; ++cit, ++m_it) {
       const Vector<UInt> & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
 
       Real p1 = this->mesh.getNodes()(n1, _x);
       Real p2 = this->mesh.getNodes()(n2, _x);
 
       Real L = std::abs(p2 - p1);
 
       Real M_n = rho * A * L / 2;
       (*m_it)(0) = (*m_it)(1) = M_n;
     }
 
     this->getDOFManager().assembleElementalArrayLocalArray(
         m_all_el, M, _segment_2, ghost_type);
   }
 
   void assembleMass() {
     SparseMatrix & M = this->getDOFManager().getMatrix("M");
     M.clear();
 
     Array<Real> m_all_el(this->nb_elements, 4);
     Array<Real>::matrix_iterator m_it = m_all_el.begin(2, 2);
 
     auto cit = this->mesh.getConnectivity(_segment_2).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2).end(2);
 
     Matrix<Real> m(2, 2);
     m(0, 0) = m(1, 1) = 2;
     m(0, 1) = m(1, 0) = 1;
 
     // under integrated
     // m(0, 0) = m(1, 1) = 3./2.;
     // m(0, 1) = m(1, 0) = 3./2.;
 
     // lumping the mass matrix
     // m(0, 0) += m(0, 1);
     // m(1, 1) += m(1, 0);
     // m(0, 1) = m(1, 0) = 0;
 
     for (; cit != cend; ++cit, ++m_it) {
       const Vector<UInt> & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
 
       Real p1 = this->mesh.getNodes()(n1, _x);
       Real p2 = this->mesh.getNodes()(n2, _x);
 
       Real L = std::abs(p2 - p1);
 
       Matrix<Real> & m_el = *m_it;
       m_el = m;
       m_el *= rho * A * L / 6.;
     }
     this->getDOFManager().assembleElementalMatricesToMatrix(
         "M", "disp", m_all_el, _segment_2);
 
     is_mass_assembled = true;
   }
 
   MatrixType getMatrixType(const ID &) { return _symmetric; }
 
   void assembleMatrix(const ID & matrix_id) {
     if (matrix_id == "K") {
       if (not is_stiffness_assembled)
         this->assembleStiffness();
     } else if (matrix_id == "M") {
       if (not is_mass_assembled)
         this->assembleMass();
     } else if (matrix_id == "C") {
       // pass, no damping matrix
     } else {
       AKANTU_EXCEPTION("This solver does not know what to do with a matrix "
                        << matrix_id);
     }
   }
 
   void assembleLumpedMatrix(const ID & matrix_id) {
     if (matrix_id == "M") {
       if (not is_lumped_mass_assembled)
         this->assembleLumpedMass();
     } else {
       AKANTU_EXCEPTION("This solver does not know what to do with a matrix "
                        << matrix_id);
     }
   }
 
   void assembleStiffness() {
     SparseMatrix & K = this->getDOFManager().getMatrix("K");
     K.clear();
 
     Matrix<Real> k(2, 2);
     k(0, 0) = k(1, 1) = 1;
     k(0, 1) = k(1, 0) = -1;
 
     Array<Real> k_all_el(this->nb_elements, 4);
 
     auto k_it = k_all_el.begin(2, 2);
     auto cit = this->mesh.getConnectivity(_segment_2).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2).end(2);
 
     for (; cit != cend; ++cit, ++k_it) {
       const auto & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
 
       Real p1 = this->mesh.getNodes()(n1, _x);
       Real p2 = this->mesh.getNodes()(n2, _x);
 
       Real L = std::abs(p2 - p1);
 
       auto & k_el = *k_it;
       k_el = k;
       k_el *= E * A / L;
     }
 
     this->getDOFManager().assembleElementalMatricesToMatrix(
         "K", "disp", k_all_el, _segment_2);
 
     is_stiffness_assembled = true;
   }
 
   void assembleResidual() {
     this->getDOFManager().assembleToResidual("disp", forces);
     internal_forces.clear();
 
     this->assembleResidual(_not_ghost);
 
     this->synchronize(_gst_user_1);
 
     this->getDOFManager().assembleToResidual("disp", internal_forces, -1.);
 
     // auto & comm = Communicator::getStaticCommunicator();
     // const auto & dof_manager_default =
     //   dynamic_cast<DOFManagerDefault &>(this->getDOFManager());
     // const auto & residual = dof_manager_default.getResidual();
     // int prank = comm.whoAmI();
     // int psize = comm.getNbProc();
 
     // for (int p = 0; p < psize; ++p) {
     //   if (prank == p) {
     //     UInt local_dof = 0;
     //     for (auto res : residual) {
     //       UInt global_dof =
     //       dof_manager_default.localToGlobalEquationNumber(local_dof);
     //       std::cout << local_dof << " [" << global_dof << " - "
     //                 << dof_manager_default.getDOFType(local_dof) << "]: " <<
     //                 res
     //                 << std::endl;
     //       ++local_dof;
     //     }
     //     std::cout << std::flush;
     //   }
     //   comm.barrier();
     // }
 
     // comm.barrier();
     // if(prank == 0) std::cout << "===========================" << std::endl;
   }
 
   void assembleResidual(const GhostType & ghost_type) {
     Array<Real> forces_internal_el(
         this->mesh.getNbElement(_segment_2, ghost_type), 2);
 
     auto cit = this->mesh.getConnectivity(_segment_2, ghost_type).begin(2);
     auto cend = this->mesh.getConnectivity(_segment_2, ghost_type).end(2);
 
     auto f_it = forces_internal_el.begin(2);
 
     auto strain_it = this->strains.begin();
     auto stress_it = this->stresses.begin();
     auto L_it = this->initial_lengths.begin();
 
     for (; cit != cend; ++cit, ++f_it, ++strain_it, ++stress_it, ++L_it) {
       const auto & conn = *cit;
       UInt n1 = conn(0);
       UInt n2 = conn(1);
 
       Real u1 = this->displacement(n1, _x);
       Real u2 = this->displacement(n2, _x);
 
       *strain_it = (u2 - u1) / *L_it;
       *stress_it = E * *strain_it;
       Real f_n = A * *stress_it;
       Vector<Real> & f = *f_it;
 
       f(0) = -f_n;
       f(1) = f_n;
     }
 
     this->getDOFManager().assembleElementalArrayLocalArray(
         forces_internal_el, internal_forces, _segment_2, ghost_type);
   }
 
   Real getPotentialEnergy() {
     Real res = 0;
 
     if (!lumped) {
       res = this->mulVectMatVect(this->displacement,
                                  this->getDOFManager().getMatrix("K"),
                                  this->displacement);
     } else {
       auto strain_it = this->strains.begin();
       auto stress_it = this->stresses.begin();
       auto strain_end = this->strains.end();
       auto L_it = this->initial_lengths.begin();
 
       for (; strain_it != strain_end; ++strain_it, ++stress_it, ++L_it) {
         res += *strain_it * *stress_it * A * *L_it;
       }
 
       mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
     }
 
     return res / 2.;
   }
 
   Real getKineticEnergy() {
     Real res = 0;
     if (!lumped) {
       res = this->mulVectMatVect(
           this->velocity, this->getDOFManager().getMatrix("M"), this->velocity);
     } else {
       auto & m = this->getDOFManager().getLumpedMatrix("M");
       auto it = velocity.begin();
       auto end = velocity.end();
       auto m_it = m.begin();
 
       for (UInt node = 0; it != end; ++it, ++m_it, ++node) {
         if (mesh.isLocalOrMasterNode(node))
           res += *m_it * *it * *it;
       }
 
       mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
     }
 
     return res / 2.;
   }
 
   Real getExternalWorkIncrement() {
     Real res = 0;
 
     auto it = velocity.begin();
     auto end = velocity.end();
     auto if_it = internal_forces.begin();
     auto ef_it = forces.begin();
     auto b_it = blocked.begin();
 
     for (UInt node = 0; it != end; ++it, ++if_it, ++ef_it, ++b_it, ++node) {
       if (mesh.isLocalOrMasterNode(node))
         res += (*b_it ? -*if_it : *ef_it) * *it;
     }
 
     mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
 
     return res * this->getTimeStep();
   }
 
   Real mulVectMatVect(const Array<Real> & x, const SparseMatrix & A,
                       const Array<Real> & y) {
     Array<Real> Ay(this->nb_dofs, 1, 0.);
     A.matVecMul(y, Ay);
     Real res = 0.;
 
     Array<Real>::const_scalar_iterator it = Ay.begin();
     Array<Real>::const_scalar_iterator end = Ay.end();
     Array<Real>::const_scalar_iterator x_it = x.begin();
 
     for (UInt node = 0; it != end; ++it, ++x_it, ++node) {
       if (mesh.isLocalOrMasterNode(node))
         res += *x_it * *it;
     }
 
     mesh.getCommunicator().allReduce(res, SynchronizerOperation::_sum);
     return res;
   }
 
   void predictor() {}
   void corrector() {}
 
   /* ------------------------------------------------------------------------ */
   UInt getNbData(const Array<Element> & elements,
                  const SynchronizationTag &) const {
     return elements.size() * sizeof(Real);
   }
 
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const SynchronizationTag & tag) const {
     if (tag == _gst_user_1) {
       for (const auto & el : elements) {
         buffer << this->stresses(el.element);
       }
     }
   }
 
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const SynchronizationTag & tag) {
     if (tag == _gst_user_1) {
       auto cit = this->mesh.getConnectivity(_segment_2, _ghost).begin(2);
 
       for (const auto & el : elements) {
         Real stress;
         buffer >> stress;
 
         Real f = A * stress;
 
         Vector<UInt> conn = cit[el.element];
         this->internal_forces(conn(0), _x) += -f;
         this->internal_forces(conn(1), _x) += f;
       }
     }
   }
 
 private:
   UInt nb_dofs;
   UInt nb_elements;
   Real E, A, rho;
 
   bool lumped;
 
   bool is_stiffness_assembled{false};
   bool is_mass_assembled{false};
   bool is_lumped_mass_assembled{false};
 
 public:
   Mesh & mesh;
   Array<Real> displacement;
   Array<Real> velocity;
   Array<Real> acceleration;
   Array<bool> blocked;
   Array<Real> forces;
   Array<Real> internal_forces;
 
   Array<Real> stresses;
   Array<Real> strains;
 
   Array<Real> initial_lengths;
 };
 
 #endif /* __AKANTU_TEST_MODEL_SOLVER_MY_MODEL_HH__ */
 
 } // akantu
diff --git a/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
index a266d813a..64de9a4ba 100644
--- a/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
+++ b/test/test_model/test_non_local_toolbox/test_build_neighborhood_parallel.cc
@@ -1,191 +1,191 @@
 /**
  * @file   test_build_neighborhood_parallel.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Sat Sep 26 2015
  * @date last modification: Wed Nov 25 2015
  *
  * @brief  test in parallel for the class NonLocalNeighborhood
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "dumper_iohelper_paraview.hh"
 #include "non_local_neighborhood_base.hh"
 #include "solid_mechanics_model.hh"
 #include "test_material.hh"
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
   akantu::initialize("material_parallel_test.dat", argc, argv);
 
   const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   // some configuration variables
   const UInt spatial_dimension = 2;
 
   // mesh creation and read
   Mesh mesh(spatial_dimension);
   if (prank == 0) {
     mesh.read("parallel_test.msh");
   }
 
   mesh.distribute();
 
   /// model creation
   SolidMechanicsModel model(mesh);
 
   /// dump the ghost elements before the non-local part is intialized
   DumperParaview dumper_ghost("ghost_elements");
   dumper_ghost.registerMesh(mesh, spatial_dimension, _ghost);
   if (psize > 1) {
     dumper_ghost.dump();
   }
 
   /// creation of material selector
   auto && mat_selector = std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names", model);
   model.setMaterialSelector(mat_selector);
 
   /// dump material index in paraview
   model.addDumpField("partitions");
   model.dump();
 
   /// model initialization changed to use our material
   model.initFull();
 
   /// dump the ghost elements after ghosts for non-local have been added
   if (psize > 1)
     dumper_ghost.dump();
 
   model.addDumpField("grad_u");
   model.addDumpField("grad_u non local");
   model.addDumpField("material_index");
 
   /// apply constant strain field everywhere in the plate
   Matrix<Real> applied_strain(spatial_dimension, spatial_dimension);
   applied_strain.clear();
   for (UInt i = 0; i < spatial_dimension; ++i)
     applied_strain(i, i) = 2.;
 
   ElementType element_type = _triangle_3;
   GhostType ghost_type = _not_ghost;
   /// apply constant grad_u field in all elements
   for (UInt m = 0; m < model.getNbMaterials(); ++m) {
     auto & mat = model.getMaterial(m);
     auto & grad_u = const_cast<Array<Real> &>(
         mat.getInternal<Real>("grad_u")(element_type, ghost_type));
     auto grad_u_it = grad_u.begin(spatial_dimension, spatial_dimension);
     auto grad_u_end = grad_u.end(spatial_dimension, spatial_dimension);
     for (; grad_u_it != grad_u_end; ++grad_u_it)
       (*grad_u_it) = -1. * applied_strain;
   }
 
   /// double the strain in the center: find the closed gauss point to the center
   /// compute the quadrature points
   ElementTypeMapReal quad_coords("quad_coords");
   quad_coords.initialize(mesh, _nb_component = spatial_dimension,
                          _spatial_dimension = spatial_dimension,
                          _with_nb_element = true);
   model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
 
   Vector<Real> center(spatial_dimension, 0.);
   Mesh::type_iterator it =
       mesh.firstType(spatial_dimension, _not_ghost, _ek_regular);
   Mesh::type_iterator last_type =
       mesh.lastType(spatial_dimension, _not_ghost, _ek_regular);
   Real min_distance = 2;
   IntegrationPoint q_min;
   for (; it != last_type; ++it) {
     ElementType type = *it;
     UInt nb_elements = mesh.getNbElement(type, _not_ghost);
     UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(type);
     Array<Real> & coords = quad_coords(type, _not_ghost);
-    Array<Real>::const_vector_iterator coord_it =
+    auto coord_it =
         coords.begin(spatial_dimension);
     for (UInt e = 0; e < nb_elements; ++e) {
       for (UInt q = 0; q < nb_quads; ++q, ++coord_it) {
         Real dist = center.distance(*coord_it);
         if (dist < min_distance) {
           min_distance = dist;
           q_min.element = e;
           q_min.num_point = q;
           q_min.global_num = nb_elements * nb_quads + q;
           q_min.type = type;
         }
       }
     }
   }
 
   Real global_min = min_distance;
   comm.allReduce(global_min, SynchronizerOperation::_min);
 
   if (Math::are_float_equal(global_min, min_distance)) {
     UInt mat_index = model.getMaterialByElement(q_min.type, _not_ghost)
                          .begin()[q_min.element];
     Material & mat = model.getMaterial(mat_index);
     UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(q_min.type);
     UInt local_el_index =
         model.getMaterialLocalNumbering(q_min.type, _not_ghost)
             .begin()[q_min.element];
     UInt local_num = (local_el_index * nb_quads) + q_min.num_point;
     Array<Real> & grad_u = const_cast<Array<Real> &>(
         mat.getInternal<Real>("grad_u")(q_min.type, _not_ghost));
     Array<Real>::iterator<Matrix<Real>> grad_u_it =
         grad_u.begin(spatial_dimension, spatial_dimension);
     grad_u_it += local_num;
     Matrix<Real> & g_u = *grad_u_it;
     g_u += applied_strain;
   }
 
   /// compute the non-local strains
   model.assembleInternalForces();
   model.dump();
 
   /// damage the element with higher grad_u completely, so that it is
   /// not taken into account for the averaging
   if (Math::are_float_equal(global_min, min_distance)) {
     UInt mat_index = model.getMaterialByElement(q_min.type, _not_ghost)
                          .begin()[q_min.element];
     Material & mat = model.getMaterial(mat_index);
     UInt nb_quads = model.getFEEngine().getNbIntegrationPoints(q_min.type);
     UInt local_el_index =
         model.getMaterialLocalNumbering(q_min.type, _not_ghost)
             .begin()[q_min.element];
     UInt local_num = (local_el_index * nb_quads) + q_min.num_point;
     Array<Real> & damage = const_cast<Array<Real> &>(
         mat.getInternal<Real>("damage")(q_min.type, _not_ghost));
     Real * dam_ptr = damage.storage();
     dam_ptr += local_num;
     *dam_ptr = 0.9;
   }
 
   /// compute the non-local strains
   model.assembleInternalForces();
   model.dump();
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_non_local_toolbox/test_pair_computation.cc b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
index 486954a9f..d70a01ea5 100644
--- a/test/test_model/test_non_local_toolbox/test_pair_computation.cc
+++ b/test/test_model/test_non_local_toolbox/test_pair_computation.cc
@@ -1,224 +1,224 @@
 /**
  * @file   test_pair_computation.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  *
  * @date creation: Wed Nov 25 2015
  *
  * @brief  test the weight computation with and without grid
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "dumper_paraview.hh"
 #include "non_local_manager.hh"
 #include "non_local_neighborhood.hh"
 #include "solid_mechanics_model.hh"
 #include "test_material_damage.hh"
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 typedef std::vector<std::pair<IntegrationPoint, IntegrationPoint>> PairList;
 
 /* -------------------------------------------------------------------------- */
 void computePairs(SolidMechanicsModel & model, PairList * pair_list);
 int main(int argc, char * argv[]) {
   akantu::initialize("material_remove_damage.dat", argc, argv);
 
   // some configuration variables
   const UInt spatial_dimension = 2;
 
   const auto & comm = Communicator::getStaticCommunicator();
   Int prank = comm.whoAmI();
 
   // mesh creation and read
   Mesh mesh(spatial_dimension);
   if (prank == 0) {
     mesh.read("pair_test.msh");
   }
   mesh.distribute();
 
   /// model creation
   SolidMechanicsModel model(mesh);
 
   /// creation of material selector
   auto && mat_selector = std::make_shared<MeshDataMaterialSelector<std::string>>("physical_names", model);
   model.setMaterialSelector(mat_selector);
 
   /// model initialization changed to use our material
   model.initFull();
 
   /// dump material index in paraview
   model.addDumpField("material_index");
   model.dump();
 
   /// compute the pairs by looping over all the quadrature points
   PairList pair_list[2];
   computePairs(model, pair_list);
 
   const PairList * pairs_mat_1 = model.getNonLocalManager().getNeighborhood("mat_1").getPairLists();
   const PairList * pairs_mat_2 = model.getNonLocalManager().getNeighborhood("mat_2").getPairLists();
 
   /// compare the number of pairs
   UInt nb_not_ghost_pairs_grid = pairs_mat_1[0].size() + pairs_mat_2[0].size();
   UInt nb_ghost_pairs_grid = pairs_mat_1[1].size() + pairs_mat_2[1].size();
   UInt nb_not_ghost_pairs_no_grid = pair_list[0].size();
   UInt nb_ghost_pairs_no_grid = pair_list[1].size();
 
   if ((nb_not_ghost_pairs_grid != nb_not_ghost_pairs_no_grid) ||
       (nb_ghost_pairs_grid != nb_ghost_pairs_no_grid)) {
     std::cout << "The number of pairs is not correct: TEST FAILED!!!"
               << std::endl;
     finalize();
     return EXIT_FAILURE;
   }
 
   for (UInt i = 0; i < pairs_mat_1[0].size(); ++i) {
     PairList::const_iterator it = std::find(
         pair_list[0].begin(), pair_list[0].end(), (pairs_mat_1[0])[i]);
     if (it == pair_list[0].end()) {
       std::cout << "The pairs are not correct" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   for (UInt i = 0; i < pairs_mat_2[0].size(); ++i) {
     PairList::const_iterator it = std::find(
         pair_list[0].begin(), pair_list[0].end(), (pairs_mat_2[0])[i]);
     if (it == pair_list[0].end()) {
       std::cout << "The pairs are not correct" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   for (UInt i = 0; i < pairs_mat_1[1].size(); ++i) {
     PairList::const_iterator it = std::find(
         pair_list[1].begin(), pair_list[1].end(), (pairs_mat_1[1])[i]);
     if (it == pair_list[1].end()) {
       std::cout << "The pairs are not correct" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   for (UInt i = 0; i < pairs_mat_2[1].size(); ++i) {
     PairList::const_iterator it = std::find(
         pair_list[1].begin(), pair_list[1].end(), (pairs_mat_2[1])[i]);
     if (it == pair_list[1].end()) {
       std::cout << "The pairs are not correct" << std::endl;
       finalize();
       return EXIT_FAILURE;
     }
   }
 
   finalize();
 
   return 0;
 }
 
 /* -------------------------------------------------------------------------- */
 void computePairs(SolidMechanicsModel & model, PairList * pair_list) {
   ElementKind kind = _ek_regular;
   Mesh & mesh = model.getMesh();
   UInt spatial_dimension = model.getSpatialDimension();
   /// compute the quadrature points
   ElementTypeMapReal quad_coords("quad_coords");
   quad_coords.initialize(mesh, _nb_component = spatial_dimension,
                          _spatial_dimension = spatial_dimension,
                          _with_nb_element = true);
   model.getFEEngine().computeIntegrationPointsCoordinates(quad_coords);
 
   /// loop in a n^2 way over all the quads to generate the pairs
   Real neighborhood_radius = 0.5;
   Mesh::type_iterator it_1 =
       mesh.firstType(spatial_dimension, _not_ghost, kind);
   Mesh::type_iterator last_type_1 =
       mesh.lastType(spatial_dimension, _not_ghost, kind);
   IntegrationPoint q1;
   IntegrationPoint q2;
   GhostType ghost_type_1 = _not_ghost;
   q1.ghost_type = ghost_type_1;
   Vector<Real> q1_coords(spatial_dimension);
   Vector<Real> q2_coords(spatial_dimension);
 
   for (; it_1 != last_type_1; ++it_1) {
     ElementType type_1 = *it_1;
     q1.type = type_1;
     UInt nb_elements_1 = mesh.getNbElement(type_1, ghost_type_1);
     UInt nb_quads_1 = model.getFEEngine().getNbIntegrationPoints(type_1);
     Array<Real> & quad_coords_1 = quad_coords(q1.type, q1.ghost_type);
-    Array<Real>::const_vector_iterator coord_it_1 =
+    auto coord_it_1 =
         quad_coords_1.begin(spatial_dimension);
     for (UInt e_1 = 0; e_1 < nb_elements_1; ++e_1) {
       q1.element = e_1;
       UInt mat_index_1 = model.getMaterialByElement(q1.type, q1.ghost_type)
                              .begin()[q1.element];
       for (UInt q_1 = 0; q_1 < nb_quads_1; ++q_1) {
         q1.global_num = nb_quads_1 * e_1 + q_1;
         q1.num_point = q_1;
         q1_coords = coord_it_1[q1.global_num];
         /// loop over all other quads and create pairs for this given quad
         for (ghost_type_t::iterator gt = ghost_type_t::begin();
              gt != ghost_type_t::end(); ++gt) {
           GhostType ghost_type_2 = *gt;
           q2.ghost_type = ghost_type_2;
           Mesh::type_iterator it_2 =
               mesh.firstType(spatial_dimension, ghost_type_2, kind);
           Mesh::type_iterator last_type_2 =
               mesh.lastType(spatial_dimension, ghost_type_2, kind);
           for (; it_2 != last_type_2; ++it_2) {
             ElementType type_2 = *it_2;
             q2.type = type_2;
             UInt nb_elements_2 = mesh.getNbElement(type_2, ghost_type_2);
             UInt nb_quads_2 =
                 model.getFEEngine().getNbIntegrationPoints(type_2);
             Array<Real> & quad_coords_2 = quad_coords(q2.type, q2.ghost_type);
-            Array<Real>::const_vector_iterator coord_it_2 =
+            auto coord_it_2 =
                 quad_coords_2.begin(spatial_dimension);
             for (UInt e_2 = 0; e_2 < nb_elements_2; ++e_2) {
               q2.element = e_2;
               UInt mat_index_2 =
                   model.getMaterialByElement(q2.type, q2.ghost_type)
                       .begin()[q2.element];
               for (UInt q_2 = 0; q_2 < nb_quads_2; ++q_2) {
                 q2.global_num = nb_quads_2 * e_2 + q_2;
                 q2.num_point = q_2;
                 q2_coords = coord_it_2[q2.global_num];
                 Real distance = q1_coords.distance(q2_coords);
                 if (mat_index_1 != mat_index_2)
                   continue;
                 else if (distance <=
                              neighborhood_radius + Math::getTolerance() &&
                          (q2.ghost_type == _ghost ||
                           (q2.ghost_type == _not_ghost &&
                            q1.global_num <=
                                q2.global_num))) { // storing only half lists
                   pair_list[q2.ghost_type].push_back(std::make_pair(q1, q2));
                 }
               }
             }
           }
         }
       }
     }
   }
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/data/cohesive_strait_3D.geo b/test/test_model/test_solid_mechanics_model/test_cohesive/data/cohesive_strait_3D.geo
index ad9490148..8f460dd2f 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/data/cohesive_strait_3D.geo
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/data/cohesive_strait_3D.geo
@@ -1,33 +1,33 @@
 h = 0.5;
 
-Point(1) = { 1, 1, -.5, h};
-Point(2) = {-1, 1, -.5, h};
-Point(3) = {-1,-1, -.5, h};
-Point(4) = { 1,-1, -.5, h};
+Point(1) = { 1, 1, -1, h};
+Point(2) = {-1, 1, -1, h};
+Point(3) = {-1,-1, -1, h};
+Point(4) = { 1,-1, -1, h};
 
-Point(5) = {-1, 0, -.5, h};
-Point(6) = { 1, 0, -.5, h};
+Point(5) = {-1, 0, -1, h};
+Point(6) = { 1, 0, -1, h};
 
 Line(1) = {1, 2};
 Line(2) = {2, 5};
 Line(3) = {5, 6};
 Line(4) = {6, 1};
 
 Line(5) = {5, 3};
 Line(6) = {3, 4};
 Line(7) = {4, 6};
 
 Line Loop(1) = {1, 2, 3, 4};
 Line Loop(2) = {-3, 5, 6, 7};
 Plane Surface(1) = {1};
 Plane Surface(2) = {2};
-Extrude {0, 0, 1} {
+Extrude {0, 0, 2} {
   Surface{1}; Surface{2};
 }
 
 Physical Surface("fixed") = {46};
 Physical Surface("insertion") = {24};
 Physical Surface("loading") = {16};
 Physical Surface("sides") = {1, 20, 29, 28, 50, 2, 51, 42};
 
 Physical Volume("body") = {1, 2};
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc
index 5817e0c22..f6e248d39 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_parallel_cohesive/test_cohesive_parallel_buildfragments/test_cohesive_parallel_buildfragments.cc
@@ -1,432 +1,432 @@
 /**
  * @file   test_cohesive_parallel_buildfragments.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  *
  * @brief  Test to build fragments in parallel
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <limits>
 #include <fstream>
 #include <iostream>
 #include <algorithm>
 #include <functional>
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model_cohesive.hh"
 #include "material_cohesive.hh"
 #include "fragment_manager.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 void verticalInsertionLimit(SolidMechanicsModelCohesive &);
 void displaceElements(SolidMechanicsModelCohesive &, const Real, const Real);
 bool isInertiaEqual(const Vector<Real> &, const Vector<Real> &);
 void rotateArray(Array<Real> & array, Real angle);
 UInt getNbBigFragments(FragmentManager &, UInt);
 
 const UInt spatial_dimension = 3;
 const UInt total_nb_fragment = 4;
 const Real rotation_angle = M_PI / 4.;
 const Real global_tolerance = 1.e-9;
 
 int main(int argc, char *argv[]) {
   initialize("material.dat", argc, argv);
 
   Math::setTolerance(global_tolerance);
 
   Mesh mesh(spatial_dimension);
 
   const auto & comm = Communicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   akantu::MeshPartition * partition = NULL;
   if(prank == 0) {
     // Read the mesh
     mesh.read("mesh.msh");
 
     /// partition the mesh
     MeshUtils::purifyMesh(mesh);
     partition = new MeshPartitionScotch(mesh, spatial_dimension);
     partition->partitionate(psize);
   }
 
   SolidMechanicsModelCohesive model(mesh);
   model.initParallel(partition, NULL, true);
 
   delete partition;
 
   /// model initialization
   model.initFull(SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
 
   mesh.computeBoundingBox();
   Real L = mesh.getUpperBounds()(0) - mesh.getLowerBounds()(0);
   Real h = mesh.getUpperBounds()(1) - mesh.getLowerBounds()(1);
   Real rho = model.getMaterial("bulk").getParam<Real>("rho");
 
   Real theoretical_mass = L * h * h * rho;
   Real frag_theo_mass = theoretical_mass / total_nb_fragment;
 
   UInt nb_element = mesh.getNbElement(spatial_dimension, _not_ghost, _ek_regular);
   comm.allReduce(&nb_element, 1, _so_sum);
   UInt nb_element_per_fragment = nb_element / total_nb_fragment;
 
   FragmentManager fragment_manager(model);
 
   fragment_manager.computeAllData();
   getNbBigFragments(fragment_manager, nb_element_per_fragment + 1);
 
   model.setBaseName("extrinsic");
   model.addDumpFieldVector("displacement");
   model.addDumpField("velocity");
   model.addDumpField("stress");
   model.addDumpField("partitions");
   model.addDumpField("fragments");
   model.addDumpField("fragments mass");
   model.addDumpField("moments of inertia");
   model.addDumpField("elements per fragment");
   model.dump();
 
   model.setBaseNameToDumper("cohesive elements", "cohesive_elements_test");
   model.addDumpFieldVectorToDumper("cohesive elements", "displacement");
   model.addDumpFieldToDumper("cohesive elements", "damage");
   model.dump("cohesive elements");
 
   /// set check facets
   verticalInsertionLimit(model);
 
   model.assembleMassLumped();
   model.synchronizeBoundaries();
 
   /// impose initial displacement
   Array<Real> & displacement = model.getDisplacement();
   Array<Real> & velocity = model.getVelocity();
   const Array<Real> & position = mesh.getNodes();
   UInt nb_nodes = mesh.getNbNodes();
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     displacement(n, 0) = position(n, 0) * 0.1;
     velocity(n, 0) = position(n, 0);
   }
 
   rotateArray(mesh.getNodes(), rotation_angle);
   //  rotateArray(displacement, rotation_angle);
   //  rotateArray(velocity, rotation_angle);
 
   model.updateResidual();
   model.checkCohesiveStress();
   model.dump();
   model.dump("cohesive elements");
 
   const Array<Real> & fragment_mass = fragment_manager.getMass();
   const Array<Real> & fragment_center = fragment_manager.getCenterOfMass();
 
   Real el_size = L / total_nb_fragment;
   Real lim = -L/2 + el_size * 0.99;
 
   /// define theoretical inertia moments
   Vector<Real> small_frag_inertia(spatial_dimension);
   small_frag_inertia(0) = frag_theo_mass * (h*h + h*h) / 12.;
   small_frag_inertia(1) = frag_theo_mass * (el_size*el_size + h*h) / 12.;
   small_frag_inertia(2) = frag_theo_mass * (el_size*el_size + h*h) / 12.;
 
   std::sort(small_frag_inertia.storage(),
 	    small_frag_inertia.storage() + spatial_dimension,
 	    std::greater<Real>());
 
   const Array<Real> & inertia_moments = fragment_manager.getMomentsOfInertia();
   Array<Real>::const_iterator< Vector<Real> > inertia_moments_begin
     = inertia_moments.begin(spatial_dimension);
 
   /// displace one fragment each time
   for (UInt frag = 1; frag <= total_nb_fragment; ++frag) {
     if (prank == 0)
       std::cout << "Generating fragment: " << frag << std::endl;
 
     fragment_manager.computeAllData();
 
     /// check number of big fragments
     UInt nb_big_fragment = getNbBigFragments(fragment_manager,
 					     nb_element_per_fragment + 1);
 
     model.dump();
     model.dump("cohesive elements");
 
 
     if (frag < total_nb_fragment) {
       if (nb_big_fragment != 1) {
 	AKANTU_ERROR("The number of big fragments is wrong: " << nb_big_fragment);
 	return EXIT_FAILURE;
       }
     }
     else {
       if (nb_big_fragment != 0) {
 	AKANTU_ERROR("The number of big fragments is wrong: " << nb_big_fragment);
 	return EXIT_FAILURE;
       }
     }
 
     /// check number of fragments
     UInt nb_fragment_num = fragment_manager.getNbFragment();
 
     if (nb_fragment_num != frag) {
       AKANTU_ERROR("The number of fragments is wrong! Numerical: " << nb_fragment_num << " Theoretical: " << frag);
       return EXIT_FAILURE;
     }
 
     /// check mass computation
     if (frag < total_nb_fragment) {
       Real total_mass = 0.;
       UInt small_fragments = 0;
 
       for (UInt f = 0; f < nb_fragment_num; ++f) {
 	const Vector<Real> & current_inertia = inertia_moments_begin[f];
 
 	if (Math::are_float_equal(fragment_mass(f, 0), frag_theo_mass)) {
 
 	  /// check center of mass
 	  if (fragment_center(f, 0) > (L * frag / total_nb_fragment - L / 2)) {
 	    AKANTU_ERROR("Fragment center is wrong!");
 	    return EXIT_FAILURE;
 	  }
 
 	  /// check moment of inertia
 	  if (!isInertiaEqual(current_inertia, small_frag_inertia)) {
 	    AKANTU_ERROR("Inertia moments are wrong");
 	    return EXIT_FAILURE;
 	  }
 
 	  ++small_fragments;
 	  total_mass += frag_theo_mass;
 	}
 	else {
 	  /// check the moment of inertia for the biggest fragment
 	  Real big_frag_mass = frag_theo_mass * (total_nb_fragment - frag + 1);
 	  Real big_frag_size = el_size * (total_nb_fragment - frag + 1);
 
 	  Vector<Real> big_frag_inertia(spatial_dimension);
 	  big_frag_inertia(0) = big_frag_mass * (h*h + h*h) / 12.;
 	  big_frag_inertia(1)
 	    = big_frag_mass * (big_frag_size*big_frag_size + h*h) / 12.;
 	  big_frag_inertia(2)
 	    = big_frag_mass * (big_frag_size*big_frag_size + h*h) / 12.;
 
 	  std::sort(big_frag_inertia.storage(),
 		    big_frag_inertia.storage() + spatial_dimension,
 		    std::greater<Real>());
 
 	  if (!isInertiaEqual(current_inertia, big_frag_inertia)) {
 	    AKANTU_ERROR("Inertia moments are wrong");
 	    return EXIT_FAILURE;
 	  }
 
 	}
       }
 
       if (small_fragments != nb_fragment_num - 1) {
 	AKANTU_ERROR("The number of small fragments is wrong!");
 	return EXIT_FAILURE;
       }
 
       if (!Math::are_float_equal(total_mass,
 				 small_fragments * frag_theo_mass)) {
 	AKANTU_ERROR("The mass of small fragments is wrong!");
 	return EXIT_FAILURE;
       }
     }
 
 
     /// displace fragments
     rotateArray(mesh.getNodes(), -rotation_angle);
     //    rotateArray(displacement, -rotation_angle);
     displaceElements(model, lim, el_size * 2);
     rotateArray(mesh.getNodes(), rotation_angle);
     //    rotateArray(displacement, rotation_angle);
 
     model.updateResidual();
 
     lim += el_size;
   }
 
   model.dump();
   model.dump("cohesive elements");
 
   /// check centers
   const Array<Real> & fragment_velocity = fragment_manager.getVelocity();
 
   Real initial_position = -L / 2. + el_size / 2.;
 
   for (UInt frag = 0; frag < total_nb_fragment; ++frag) {
     Real theoretical_center = initial_position + el_size * frag;
 
     UInt f_index = 0;
     while (f_index < total_nb_fragment &&
   	   !Math::are_float_equal(fragment_center(f_index, 0), theoretical_center))
       ++f_index;
 
     if (f_index == total_nb_fragment) {
       AKANTU_ERROR("The fragments' center is wrong!");
       return EXIT_FAILURE;
     }
 
     f_index = 0;
     while (f_index < total_nb_fragment &&
   	   !Math::are_float_equal(fragment_velocity(f_index, 0),
 				  theoretical_center))
       ++f_index;
 
     if (f_index == total_nb_fragment) {
       AKANTU_ERROR("The fragments' velocity is wrong!");
       return EXIT_FAILURE;
     }
   }
 
   finalize();
 
   if (prank == 0)
     std::cout << "OK: test_cohesive_buildfragments was passed!" << std::endl;
   return EXIT_SUCCESS;
 }
 
 void verticalInsertionLimit(SolidMechanicsModelCohesive & model) {
   UInt spatial_dimension = model.getSpatialDimension();
   const Mesh & mesh_facets = model.getMeshFacets();
   const Array<Real> & position = mesh_facets.getNodes();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end();
        ++gt) {
     GhostType ghost_type = *gt;
 
     Mesh::type_iterator it  = mesh_facets.firstType(spatial_dimension - 1, ghost_type);
     Mesh::type_iterator end = mesh_facets.lastType(spatial_dimension - 1, ghost_type);
     for(; it != end; ++it) {
       ElementType type = *it;
 
       Array<bool> & check_facets
 	= model.getElementInserter().getCheckFacets(type, ghost_type);
 
       const Array<UInt> & connectivity = mesh_facets.getConnectivity(type, ghost_type);
       UInt nb_nodes_per_facet = connectivity.getNbComponent();
 
       for (UInt f = 0; f < check_facets.getSize(); ++f) {
 	if (!check_facets(f)) continue;
 
 	UInt nb_aligned_nodes = 1;
 	Real first_node_pos = position(connectivity(f, 0), 0);
 
 	for (; nb_aligned_nodes < nb_nodes_per_facet; ++nb_aligned_nodes) {
 	  Real other_node_pos = position(connectivity(f, nb_aligned_nodes), 0);
 
 	  if (! Math::are_float_equal(first_node_pos, other_node_pos))
 	    break;
 	}
 
 	if (nb_aligned_nodes != nb_nodes_per_facet) {
 	  check_facets(f) = false;
 	}
       }
     }
   }
 }
 
 void displaceElements(SolidMechanicsModelCohesive & model,
 		      const Real lim,
 		      const Real amount) {
   UInt spatial_dimension = model.getSpatialDimension();
   Array<Real> & displacement = model.getDisplacement();
   Mesh & mesh = model.getMesh();
   UInt nb_nodes = mesh.getNbNodes();
   Array<bool> displaced(nb_nodes);
   displaced.clear();
   Vector<Real> barycenter(spatial_dimension);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end();
        ++gt) {
     GhostType ghost_type = *gt;
 
     Mesh::type_iterator it  = mesh.firstType(spatial_dimension, ghost_type);
     Mesh::type_iterator end = mesh.lastType(spatial_dimension, ghost_type);
     for(; it != end; ++it) {
       ElementType type = *it;
       const Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
       UInt nb_element = connectivity.getSize();
       UInt nb_nodes_per_element = connectivity.getNbComponent();
 
       Array<UInt>::const_vector_iterator conn_el
 	= connectivity.begin(nb_nodes_per_element);
 
       for (UInt el = 0; el < nb_element; ++el) {
 	mesh.getBarycenter(el, type, barycenter.storage(), ghost_type);
 
 	if (barycenter(0) < lim) {
 	  const Vector<UInt> & conn = conn_el[el];
 
 	  for (UInt n = 0; n < nb_nodes_per_element; ++n) {
 	    UInt node = conn(n);
 	    if (!displaced(node)) {
 	      displacement(node, 0) -= amount;
 	      displaced(node) = true;
 	    }
 	  }
 	}
       }
     }
   }
 }
 
 bool isInertiaEqual(const Vector<Real> & a, const Vector<Real> & b) {
   UInt nb_terms = a.size();
   UInt equal_terms = 0;
 
   while (equal_terms < nb_terms &&
 	 std::abs(a(equal_terms) - b(equal_terms)) / a(equal_terms) < Math::getTolerance())
     ++equal_terms;
 
   return equal_terms == nb_terms;
 }
 
 void rotateArray(Array<Real> & array, Real angle) {
   UInt spatial_dimension = array.getNbComponent();
 
   Real rotation_values[] = {std::cos(angle), std::sin(angle), 0,
 			    -std::sin(angle), std::cos(angle), 0,
 			    0, 0, 1};
   Matrix<Real> rotation(rotation_values, spatial_dimension, spatial_dimension);
 
   RVector displaced_node(spatial_dimension);
-  Array<Real>::vector_iterator node_it = array.begin(spatial_dimension);
-  Array<Real>::vector_iterator node_end = array.end(spatial_dimension);
+  auto node_it = array.begin(spatial_dimension);
+  auto node_end = array.end(spatial_dimension);
 
   for (; node_it != node_end; ++node_it) {
     displaced_node.mul<false>(rotation, *node_it);
     *node_it = displaced_node;
   }
 }
 
 UInt getNbBigFragments(FragmentManager & fragment_manager,
 		       UInt minimum_nb_elements) {
   fragment_manager.computeNbElementsPerFragment();
   const Array<UInt> & nb_elements_per_fragment
     = fragment_manager.getNbElementsPerFragment();
   UInt nb_fragment = fragment_manager.getNbFragment();
   UInt nb_big_fragment = 0;
 
   for (UInt frag = 0; frag < nb_fragment; ++frag) {
     if (nb_elements_per_fragment(frag) >= minimum_nb_elements) {
       ++nb_big_fragment;
     }
   }
 
   return nb_big_fragment;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
index 22ec062bd..e5b0f00ed 100644
--- a/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
+++ b/test/test_model/test_solid_mechanics_model/test_embedded_interface/test_embedded_interface_model_prestress.cc
@@ -1,224 +1,224 @@
 /**
  * @file   test_embedded_interface_model_prestress.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Tue Apr 28 2015
  * @date last modification: Thu Oct 15 2015
  *
  * @brief  Embedded model test for prestressing (bases on stress norm)
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #include "aka_common.hh"
 #include "embedded_interface_model.hh"
 
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 #define YG 0.483644859
 #define I_eq 0.012488874
 #define A_eq (1e-2 + 1. / 7. * 1.)
 
 /* -------------------------------------------------------------------------- */
 
 struct StressSolution : public BC::Neumann::FromHigherDim {
   Real M;
   Real I;
   Real yg;
   Real pre_stress;
 
   StressSolution(UInt dim, Real M, Real I, Real yg = 0, Real pre_stress = 0) :
     BC::Neumann::FromHigherDim(Matrix<Real>(dim, dim)),
     M(M), I(I), yg(yg), pre_stress(pre_stress)
   {}
 
   virtual ~StressSolution() {}
 
   void operator()(const IntegrationPoint & /*quad_point*/, Vector<Real> & dual,
                   const Vector<Real> & coord,
                   const Vector<Real> & normals) const {
     UInt dim = coord.size();
 
     if (dim < 2) AKANTU_ERROR("Solution not valid for 1D");
 
     Matrix<Real> stress(dim, dim); stress.clear();
     stress(0, 0) = this->stress(coord(1));
     dual.mul<false>(stress, normals);
   }
 
   inline Real stress(Real height) const {
     return -M / I * (height - yg) + pre_stress;
   }
 
   inline Real neutral_axis() const {
     return -I * pre_stress / M + yg;
   }
 };
 
 /* -------------------------------------------------------------------------- */
 
 int main (int argc, char * argv[]) {
   initialize("prestress.dat", argc, argv);
   debug::setDebugLevel(dblError);
 
   Math::setTolerance(1e-6);
 
   const UInt dim = 2;
 
 /* -------------------------------------------------------------------------- */
 
   Mesh mesh(dim);
   mesh.read("embedded_mesh_prestress.msh");
   // mesh.createGroupsFromMeshData<std::string>("physical_names");
 
   Mesh reinforcement_mesh(dim, "reinforcement_mesh");
   try {
     reinforcement_mesh.read("embedded_mesh_prestress_reinforcement.msh");
   } catch(debug::Exception & e) {}
 
   // reinforcement_mesh.createGroupsFromMeshData<std::string>("physical_names");
 
   EmbeddedInterfaceModel model(mesh, reinforcement_mesh, dim);
   model.initFull(EmbeddedInterfaceModelOptions(_static));
 
 /* -------------------------------------------------------------------------- */
 /* Computation of analytical residual                                         */
 /* -------------------------------------------------------------------------- */
 
   /*
    * q = 1000 N/m
    * L = 20 m
    * a = 1 m
    */
 
   Real steel_area = model.getMaterial("reinforcement").get("area");
   Real pre_stress = model.getMaterial("reinforcement").get("pre_stress");
   Real stress_norm = 0.;
 
   StressSolution * concrete_stress = nullptr, * steel_stress = nullptr;
 
   Real pre_force = pre_stress * steel_area;
   Real pre_moment = -pre_force * (YG - 0.25);
   Real neutral_axis = YG - I_eq / A_eq * pre_force / pre_moment;
 
   concrete_stress = new StressSolution(dim, pre_moment, 7. * I_eq, YG, -pre_force / (7. * A_eq));
   steel_stress = new StressSolution(dim, pre_moment, I_eq, YG, pre_stress - pre_force / A_eq);
 
   stress_norm = std::abs(concrete_stress->stress(1)) * (1 - neutral_axis) * 0.5
     + std::abs(concrete_stress->stress(0)) * neutral_axis * 0.5
     + std::abs(steel_stress->stress(0.25)) * steel_area;
 
   model.applyBC(*concrete_stress, "XBlocked");
   auto end_node = *mesh.getElementGroup("EndNode").getNodeGroup().begin();
 
   Vector<Real> end_node_force = model.getForce().begin(dim)[end_node];
   end_node_force(0) += steel_stress->stress(0.25) * steel_area; 
 
   Array<Real> analytical_residual(mesh.getNbNodes(), dim, "analytical_residual");
   analytical_residual.copy(model.getForce());
   model.getForce().clear();
 
   delete concrete_stress;
   delete steel_stress;
 
 /* -------------------------------------------------------------------------- */
 
   model.applyBC(BC::Dirichlet::FixedValue(0.0, _x), "XBlocked");
   model.applyBC(BC::Dirichlet::FixedValue(0.0, _y), "YBlocked");
 
   try {
     model.solveStep();
   } catch (debug::Exception e) {
     std::cerr << e.what() << std::endl;
     return EXIT_FAILURE;
   }
 
 /* -------------------------------------------------------------------------- */
 /* Computation of FEM residual norm                                           */
 /* -------------------------------------------------------------------------- */
 
   ElementGroup & xblocked = mesh.getElementGroup("XBlocked");
   NodeGroup & boundary_nodes = xblocked.getNodeGroup();
   NodeGroup::const_node_iterator
     nodes_it = boundary_nodes.begin(),
     nodes_end = boundary_nodes.end();
   model.assembleInternalForces();
   Array<Real> residual(mesh.getNbNodes(), dim, "my_residual");
   residual.copy(model.getInternalForce());
   residual -= model.getForce();
 
-  Array<Real>::vector_iterator com_res = residual.begin(dim);
-  Array<Real>::vector_iterator position = mesh.getNodes().begin(dim);
+  auto com_res = residual.begin(dim);
+  auto position = mesh.getNodes().begin(dim);
 
   Real res_sum = 0.;
   UInt lower_node = -1;
   UInt upper_node = -1;
   Real lower_dist = 1;
   Real upper_dist = 1;
 
   for (; nodes_it != nodes_end ; ++nodes_it) {
     UInt node_number = *nodes_it;
     const Vector<Real> res = com_res[node_number];
     const Vector<Real> pos = position[node_number];
 
     if (!Math::are_float_equal(pos(1), 0.25)) {
       if ((std::abs(pos(1) - 0.25) < lower_dist) && (pos(1) < 0.25)) {
         lower_dist = std::abs(pos(1) - 0.25);
         lower_node = node_number;
       }
 
       if ((std::abs(pos(1) - 0.25) < upper_dist) && (pos(1) > 0.25)) {
         upper_dist = std::abs(pos(1) - 0.25);
         upper_node = node_number;
       }
     }
 
     for (UInt i = 0 ; i < dim ; i++) {
       if (!Math::are_float_equal(pos(1), 0.25)) {
         res_sum += std::abs(res(i));
       }
     }
   }
 
   const Vector<Real> upper_res = com_res[upper_node], lower_res = com_res[lower_node];
   const Vector<Real> end_node_res = com_res[end_node];
   Vector<Real> delta = upper_res - lower_res;
   delta *= lower_dist / (upper_dist + lower_dist);
   Vector<Real> concrete_residual = lower_res + delta;
   Vector<Real> steel_residual = end_node_res - concrete_residual;
 
   for (UInt i = 0 ; i < dim ; i++) {
     res_sum += std::abs(concrete_residual(i));
     res_sum += std::abs(steel_residual(i));
   }
 
   Real relative_error = std::abs(res_sum - stress_norm) / stress_norm;
 
   if (relative_error > 1e-3) {
     std::cerr << "Relative error = " << relative_error << std::endl;
     return EXIT_FAILURE;
   }
 
   finalize();
   return 0;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_finite_def_materials.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_finite_def_materials.cc
index b1f0219b8..f1304ac25 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_finite_def_materials.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_finite_def_materials.cc
@@ -1,61 +1,61 @@
 /* -------------------------------------------------------------------------- */
 #include "material_neohookean.hh"
 #include "solid_mechanics_model.hh"
 #include "test_material_fixtures.hh"
 #include <gtest/gtest.h>
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 using types = ::testing::Types<
 
     Traits<MaterialNeohookean, 1>, Traits<MaterialNeohookean, 2>,
     Traits<MaterialNeohookean, 3>>;
 
 /*****************************************************************/
 
 template <> void FriendMaterial<MaterialNeohookean<3>>::testComputeStress() {
-  TO_IMPLEMENT;
+  AKANTU_TO_IMPLEMENT();
 }
 
 /*****************************************************************/
 template <>
 void FriendMaterial<MaterialNeohookean<3>>::testComputeTangentModuli() {
-  TO_IMPLEMENT;
+  AKANTU_TO_IMPLEMENT();
 }
 
 /*****************************************************************/
 
 template <> void FriendMaterial<MaterialNeohookean<3>>::testEnergyDensity() {
-  TO_IMPLEMENT;
+  AKANTU_TO_IMPLEMENT();
 }
 
 /*****************************************************************/
 
 namespace {
 
 template <typename T>
 class TestFiniteDefMaterialFixture : public ::TestMaterialFixture<T> {};
 
 TYPED_TEST_CASE(TestFiniteDefMaterialFixture, types);
 
 TYPED_TEST(TestFiniteDefMaterialFixture, FiniteDefComputeStress) {
   this->material->testComputeStress();
 }
 TYPED_TEST(TestFiniteDefMaterialFixture, FiniteDefEnergyDensity) {
   this->material->testEnergyDensity();
 }
 TYPED_TEST(TestFiniteDefMaterialFixture, FiniteDefComputeTangentModuli) {
   this->material->testComputeTangentModuli();
 }
 
 TYPED_TEST(TestFiniteDefMaterialFixture, FiniteDefComputePushWaveSpeed) {
   this->material->testPushWaveSpeed();
 }
 
 TYPED_TEST(TestFiniteDefMaterialFixture, FiniteDefComputeShearWaveSpeed) {
   this->material->testShearWaveSpeed();
 }
 }
 /*****************************************************************/
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_fixtures.hh b/test/test_model/test_solid_mechanics_model/test_materials/test_material_fixtures.hh
index d741bb226..f3fd93472 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_fixtures.hh
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_fixtures.hh
@@ -1,184 +1,184 @@
 /* -------------------------------------------------------------------------- */
 #include "material_elastic.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 #include <gtest/gtest.h>
 #include <random>
 #include <type_traits>
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 /* -------------------------------------------------------------------------- */
 template <typename T> class FriendMaterial : public T {
 public:
   ~FriendMaterial() = default;
 
   virtual void testComputeStress() { AKANTU_TO_IMPLEMENT(); };
   virtual void testComputeTangentModuli() { AKANTU_TO_IMPLEMENT(); };
   virtual void testEnergyDensity() { AKANTU_TO_IMPLEMENT(); };
   virtual void testPushWaveSpeed() { AKANTU_TO_IMPLEMENT(); }
   virtual void testShearWaveSpeed() { AKANTU_TO_IMPLEMENT(); }
 
   static inline Matrix<Real> getDeviatoricStrain(Real intensity);
 
   static inline Matrix<Real> getHydrostaticStrain(Real intensity);
 
   static inline const Matrix<Real>
   reverseRotation(Matrix<Real> mat, Matrix<Real> rotation_matrix) {
     Matrix<Real> R = rotation_matrix;
     Matrix<Real> m2 = mat * R;
     Matrix<Real> m1 = R.transpose();
     return m1 * m2;
   };
 
   static inline const Matrix<Real>
   applyRotation(Matrix<Real> mat, const Matrix<Real> rotation_matrix) {
     Matrix<Real> R = rotation_matrix;
     Matrix<Real> m2 = mat * R.transpose();
     Matrix<Real> m1 = R;
     return m1 * m2;
   };
 
   static inline Matrix<Real> getRandomRotation3d();
   static inline Matrix<Real> getRandomRotation2d();
 
   using T::T;
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 Matrix<Real> FriendMaterial<T>::getDeviatoricStrain(Real intensity) {
   Matrix<Real> dev = {{0., 1., 2.}, {1., 0., 3.}, {2., 3., 0.}};
   dev *= intensity;
   return dev;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 Matrix<Real> FriendMaterial<T>::getHydrostaticStrain(Real intensity) {
   Matrix<Real> dev = {{1., 0., 0.}, {0., 2., 0.}, {0., 0., 3.}};
   dev *= intensity;
   return dev;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> Matrix<Real> FriendMaterial<T>::getRandomRotation3d() {
   constexpr UInt Dim = 3;
   // Seed with a real random value, if available
   std::random_device rd;
   std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
   std::uniform_real_distribution<> dis;
 
   Vector<Real> v1(Dim);
   Vector<Real> v2(Dim);
   Vector<Real> v3(Dim);
 
   for (UInt i = 0; i < Dim; ++i) {
     v1(i) = dis(gen);
     v2(i) = dis(gen);
   }
 
   v1.normalize();
   v2.normalize();
 
   auto d = v1.dot(v2);
   v2 -= v1 * d;
   v2.normalize();
 
   d = v1.dot(v2);
   v2 -= v1 * d;
   v2.normalize();
 
   v3.crossProduct(v1, v2);
 
   Vector<Real> test_axis(3);
   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() << ".");
   }
 
   Matrix<Real> mat(Dim, Dim);
   for (UInt i = 0; i < Dim; ++i) {
     mat(0, i) = v1[i];
     mat(1, i) = v2[i];
     mat(2, i) = v3[i];
   }
 
   return mat;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T> Matrix<Real> FriendMaterial<T>::getRandomRotation2d() {
   constexpr UInt Dim = 2;
   // Seed with a real random value, if available
   std::random_device rd;
   std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
   std::uniform_real_distribution<> dis;
 
   // v1 and v2 are such that they form a right-hand basis with prescribed v3,
   // it's need (at least) for 2d linear elastic anisotropic and (orthotropic)
   // materials to rotate the tangent stiffness
 
   Vector<Real> v1(3);
   Vector<Real> v2(3);
   Vector<Real> v3 = {0, 0, 1};
 
   for (UInt i = 0; i < Dim; ++i) {
     v1(i) = dis(gen);
     // v2(i) = dis(gen);
   }
 
   v1.normalize();
   v2.crossProduct(v3, v1);
 
   Matrix<Real> mat(Dim, Dim);
   for (UInt i = 0; i < Dim; ++i) {
     mat(0, i) = v1[i];
     mat(1, i) = v2[i];
   }
 
   return mat;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, class Model>
 class TestMaterialBaseFixture : public ::testing::Test {
 public:
   using mat_class = typename T::mat_class;
 
   void SetUp() override {
     constexpr auto spatial_dimension = T::Dim;
     mesh = std::make_unique<Mesh>(spatial_dimension);
     model = std::make_unique<Model>(*mesh);
     material = std::make_unique<friend_class>(*model);
   }
 
   void TearDown() override {
     material.reset(nullptr);
     model.reset(nullptr);
     mesh.reset(nullptr);
   }
 
   using friend_class = FriendMaterial<mat_class>;
 
 protected:
   std::unique_ptr<Mesh> mesh;
   std::unique_ptr<Model> model;
   std::unique_ptr<friend_class> material;
 };
 
 /* -------------------------------------------------------------------------- */
 template <template <UInt> class T, UInt _Dim> struct Traits {
   using mat_class = T<_Dim>;
   static constexpr UInt Dim = _Dim;
 };
 
 /* -------------------------------------------------------------------------- */
-template <typename T, class Model>
+template <typename T>
 using TestMaterialFixture = TestMaterialBaseFixture<T, SolidMechanicsModel>;
 
 /* -------------------------------------------------------------------------- */