diff --git a/packages/core.cmake b/packages/core.cmake
index e362dc234..0261b1224 100644
--- a/packages/core.cmake
+++ b/packages/core.cmake
@@ -1,584 +1,585 @@
 #===============================================================================
 # @file   core.cmake
 #
 # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date creation: Mon Nov 21 2011
 # @date last modification: Mon Jan 18 2016
 #
 # @brief  package description for core
 #
 # @section 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/>.
 #
 #===============================================================================
 
 package_declare(core NOT_OPTIONAL
   DESCRIPTION "core package for Akantu"
   FEATURES_PUBLIC cxx_strong_enums cxx_defaulted_functions cxx_deleted_functions
   cxx_auto_type cxx_decltype_auto
   FEATURES_PRIVATE cxx_lambdas cxx_nullptr cxx_delegated_constructors
   cxx_range_for )
 
 package_declare_sources(core
   common/aka_array.cc
   common/aka_array.hh
   common/aka_array_tmpl.hh
   common/aka_blas_lapack.hh
   common/aka_circular_array.hh
   common/aka_circular_array_inline_impl.cc
   common/aka_common.cc
   common/aka_common.hh
   common/aka_common_inline_impl.cc
   common/aka_csr.hh
   common/aka_element_classes_info_inline_impl.cc
   common/aka_error.cc
   common/aka_error.hh
   common/aka_event_handler_manager.hh
   common/aka_extern.cc
   common/aka_factory.hh
   common/aka_fwd.hh
   common/aka_grid_dynamic.hh
   common/aka_math.cc
   common/aka_math.hh
   common/aka_math_tmpl.hh
   common/aka_memory.cc
   common/aka_memory.hh
   common/aka_memory_inline_impl.cc
   common/aka_named_argument.hh
   common/aka_random_generator.hh
   common/aka_safe_enum.hh
   common/aka_static_memory.cc
   common/aka_static_memory.hh
   common/aka_static_memory_inline_impl.cc
   common/aka_static_memory_tmpl.hh
   common/aka_typelist.hh
   common/aka_types.hh
   common/aka_visitor.hh
   common/aka_voigthelper.hh
   common/aka_voigthelper_tmpl.hh
   common/aka_voigthelper.cc
   common/aka_warning.hh
   common/aka_warning_restore.hh
   common/aka_zip.hh
 
   fe_engine/element_class.cc
   fe_engine/element_class.hh
   fe_engine/element_class_tmpl.hh
   fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
   fe_engine/element_classes/element_class_hexahedron_20_inline_impl.cc
   fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
   fe_engine/element_classes/element_class_pentahedron_15_inline_impl.cc
   fe_engine/element_classes/element_class_point_1_inline_impl.cc
   fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
   fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
   fe_engine/element_classes/element_class_segment_2_inline_impl.cc
   fe_engine/element_classes/element_class_segment_3_inline_impl.cc
   fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
   fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
   fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
   fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
 
   fe_engine/fe_engine.cc
   fe_engine/fe_engine.hh
   fe_engine/fe_engine_inline_impl.cc
   fe_engine/fe_engine_template.hh
   fe_engine/fe_engine_template_tmpl.hh
   fe_engine/geometrical_element.cc
   fe_engine/gauss_integration.cc
   fe_engine/gauss_integration_tmpl.hh
   fe_engine/integrator.hh
   fe_engine/integrator_gauss.hh
   fe_engine/integrator_gauss_inline_impl.cc
   fe_engine/interpolation_element.cc
   fe_engine/interpolation_element_tmpl.hh
   fe_engine/integration_point.hh
   fe_engine/shape_functions.hh
   fe_engine/shape_functions_inline_impl.cc
   fe_engine/shape_lagrange.cc
   fe_engine/shape_lagrange.hh
   fe_engine/shape_lagrange_inline_impl.cc
   fe_engine/shape_linked.cc
   fe_engine/shape_linked.hh
   fe_engine/shape_linked_inline_impl.cc
   fe_engine/element.hh
 
   io/dumper/dumpable.hh
   io/dumper/dumpable.cc
   io/dumper/dumpable_dummy.hh
   io/dumper/dumpable_inline_impl.hh
   io/dumper/dumper_field.hh
   io/dumper/dumper_material_padders.hh
   io/dumper/dumper_filtered_connectivity.hh
   io/dumper/dumper_element_partition.hh
 
   io/mesh_io.cc
   io/mesh_io.hh
   io/mesh_io/mesh_io_abaqus.cc
   io/mesh_io/mesh_io_abaqus.hh
   io/mesh_io/mesh_io_diana.cc
   io/mesh_io/mesh_io_diana.hh
   io/mesh_io/mesh_io_msh.cc
   io/mesh_io/mesh_io_msh.hh
   io/model_io.cc
   io/model_io.hh
 
   io/parser/algebraic_parser.hh
   io/parser/input_file_parser.hh
   io/parser/parsable.cc
   io/parser/parsable.hh
   io/parser/parsable_tmpl.hh
   io/parser/parser.cc
   io/parser/parser_real.cc
   io/parser/parser_random.cc
   io/parser/parser_types.cc
   io/parser/parser_input_files.cc
   io/parser/parser.hh
   io/parser/parser_tmpl.hh
   io/parser/parser_grammar_tmpl.hh
   io/parser/cppargparse/cppargparse.hh
   io/parser/cppargparse/cppargparse.cc
   io/parser/cppargparse/cppargparse_tmpl.hh
 
   io/parser/parameter_registry.cc
   io/parser/parameter_registry.hh
   io/parser/parameter_registry_tmpl.hh
 
   mesh/element_group.cc
   mesh/element_group.hh
   mesh/element_group_inline_impl.cc
   mesh/element_type_map.cc
   mesh/element_type_map.hh
   mesh/element_type_map_tmpl.hh
   mesh/element_type_map_filter.hh
   mesh/group_manager.cc
   mesh/group_manager.hh
   mesh/group_manager_inline_impl.cc
   mesh/mesh.cc
   mesh/mesh.hh
   mesh/mesh_accessor.hh
   mesh/mesh_accessor.cc
   mesh/mesh_events.hh
   mesh/mesh_filter.hh
   mesh/mesh_data.cc
   mesh/mesh_data.hh
   mesh/mesh_data_tmpl.hh
   mesh/mesh_inline_impl.cc
   mesh/node_group.cc
   mesh/node_group.hh
   mesh/node_group_inline_impl.cc
+  mesh/mesh_iterators.hh
 
   mesh_utils/mesh_partition.cc
   mesh_utils/mesh_partition.hh
   mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
   mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
   mesh_utils/mesh_partition/mesh_partition_scotch.hh
   mesh_utils/mesh_utils_pbc.cc
   mesh_utils/mesh_utils.cc
   mesh_utils/mesh_utils.hh
   mesh_utils/mesh_utils_distribution.cc
   mesh_utils/mesh_utils_distribution.hh
   mesh_utils/mesh_utils.hh
   mesh_utils/mesh_utils_inline_impl.cc
   mesh_utils/global_ids_updater.hh
   mesh_utils/global_ids_updater.cc
   mesh_utils/global_ids_updater_inline_impl.cc
 
   model/boundary_condition.hh
   model/boundary_condition_functor.hh
   model/boundary_condition_functor_inline_impl.cc
   model/boundary_condition_tmpl.hh
 
   model/common/neighborhood_base.hh
   model/common/neighborhood_base.cc
   model/common/neighborhood_base_inline_impl.cc
   model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.hh
   model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion.cc
   model/common/neighborhoods_criterion_evaluation/neighborhood_max_criterion_inline_impl.cc
   model/common/non_local_toolbox/non_local_manager.hh
   model/common/non_local_toolbox/non_local_manager.cc
   model/common/non_local_toolbox/non_local_manager_inline_impl.cc
   model/common/non_local_toolbox/non_local_neighborhood_base.hh
   model/common/non_local_toolbox/non_local_neighborhood_base.cc
   model/common/non_local_toolbox/non_local_neighborhood.hh
   model/common/non_local_toolbox/non_local_neighborhood_tmpl.hh
   model/common/non_local_toolbox/non_local_neighborhood_inline_impl.cc
 
   model/dof_manager.cc
   model/dof_manager.hh
   model/dof_manager_default.cc
   model/dof_manager_default.hh
   model/dof_manager_default_inline_impl.cc
   model/dof_manager_inline_impl.cc
   model/model_solver.cc
   model/model_solver.hh
   model/model_solver_tmpl.hh
   model/non_linear_solver.cc
   model/non_linear_solver.hh
   model/non_linear_solver_default.hh
   model/non_linear_solver_lumped.cc
   model/non_linear_solver_lumped.hh
   model/solver_callback.hh
   model/solver_callback.cc
   model/time_step_solver.hh
   model/time_step_solvers/time_step_solver.cc
   model/time_step_solvers/time_step_solver_default.cc
   model/time_step_solvers/time_step_solver_default.hh
   model/time_step_solvers/time_step_solver_default_explicit.hh
   model/non_linear_solver_callback.hh
   model/time_step_solvers/time_step_solver_default_solver_callback.hh
 
   model/integration_scheme/generalized_trapezoidal.cc
   model/integration_scheme/generalized_trapezoidal.hh
   model/integration_scheme/integration_scheme.cc
   model/integration_scheme/integration_scheme.hh
   model/integration_scheme/integration_scheme_1st_order.cc
   model/integration_scheme/integration_scheme_1st_order.hh
   model/integration_scheme/integration_scheme_2nd_order.cc
   model/integration_scheme/integration_scheme_2nd_order.hh
   model/integration_scheme/newmark-beta.cc
   model/integration_scheme/newmark-beta.hh
   model/integration_scheme/pseudo_time.cc
   model/integration_scheme/pseudo_time.hh
   model/model.cc
   model/model.hh
   model/model_inline_impl.cc
 
   model/solid_mechanics/material.cc
   model/solid_mechanics/material.hh
   model/solid_mechanics/material_inline_impl.cc
   model/solid_mechanics/material_selector.hh
   model/solid_mechanics/material_selector_tmpl.hh
   model/solid_mechanics/materials/internal_field.hh
   model/solid_mechanics/materials/internal_field_tmpl.hh
   model/solid_mechanics/materials/random_internal_field.hh
   model/solid_mechanics/materials/random_internal_field_tmpl.hh
   model/solid_mechanics/solid_mechanics_model.cc
   model/solid_mechanics/solid_mechanics_model.hh
   model/solid_mechanics/solid_mechanics_model_inline_impl.cc
   model/solid_mechanics/solid_mechanics_model_io.cc
   model/solid_mechanics/solid_mechanics_model_mass.cc
   model/solid_mechanics/solid_mechanics_model_material.cc
   model/solid_mechanics/solid_mechanics_model_tmpl.hh
   model/solid_mechanics/solid_mechanics_model_event_handler.hh
   model/solid_mechanics/materials/plane_stress_toolbox.hh
   model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
 
 
   model/solid_mechanics/materials/material_core_includes.hh
   model/solid_mechanics/materials/material_elastic.cc
   model/solid_mechanics/materials/material_elastic.hh
   model/solid_mechanics/materials/material_elastic_inline_impl.cc
   model/solid_mechanics/materials/material_thermal.cc
   model/solid_mechanics/materials/material_thermal.hh
   model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
   model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
   model/solid_mechanics/materials/material_elastic_orthotropic.cc
   model/solid_mechanics/materials/material_elastic_orthotropic.hh
   model/solid_mechanics/materials/material_damage/material_damage.hh
   model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
   model/solid_mechanics/materials/material_damage/material_marigo.cc
   model/solid_mechanics/materials/material_damage/material_marigo.hh
   model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
   model/solid_mechanics/materials/material_damage/material_mazars.cc
   model/solid_mechanics/materials/material_damage/material_mazars.hh
   model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
   model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
   model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
   model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
   model/solid_mechanics/materials/material_plastic/material_plastic.cc
   model/solid_mechanics/materials/material_plastic/material_plastic.hh
   model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
   model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
   model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
   model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
   model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
   model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
 
   model/solid_mechanics/materials/material_non_local.hh
   model/solid_mechanics/materials/material_non_local_tmpl.hh
   model/solid_mechanics/materials/material_non_local_includes.hh
   model/solid_mechanics/materials/material_non_local_inline_impl.cc
 
   solver/sparse_solver.cc
   solver/sparse_solver.hh
   solver/sparse_solver_inline_impl.cc
   solver/sparse_matrix.cc
   solver/sparse_matrix.hh
   solver/sparse_matrix_inline_impl.cc
   solver/sparse_matrix_aij.cc
   solver/sparse_matrix_aij.hh
   solver/sparse_matrix_aij_inline_impl.cc
   solver/terms_to_assemble.hh
 
   synchronizer/communication_descriptor_tmpl.hh
   synchronizer/communications_tmpl.hh
   synchronizer/communication_buffer.hh
   synchronizer/communication_buffer_inline_impl.cc
   synchronizer/communication_descriptor.hh
   synchronizer/communication_tag.hh
   synchronizer/communications.hh
   synchronizer/data_accessor.cc
   synchronizer/data_accessor.hh
   synchronizer/element_synchronizer.cc
   synchronizer/element_synchronizer.hh
   synchronizer/node_synchronizer.cc
   synchronizer/node_synchronizer.hh
   synchronizer/dof_synchronizer.cc
   synchronizer/dof_synchronizer.hh
   synchronizer/dof_synchronizer_inline_impl.cc
   synchronizer/element_info_per_processor.cc
   synchronizer/element_info_per_processor.hh
   synchronizer/element_info_per_processor_tmpl.hh
   synchronizer/filtered_synchronizer.cc
   synchronizer/filtered_synchronizer.hh
   synchronizer/grid_synchronizer.cc
   synchronizer/grid_synchronizer.hh
   synchronizer/grid_synchronizer_tmpl.hh
   synchronizer/master_element_info_per_processor.cc
   synchronizer/node_info_per_processor.cc
   synchronizer/node_info_per_processor.hh
   synchronizer/real_static_communicator.hh
   synchronizer/slave_element_info_per_processor.cc
   synchronizer/static_communicator.cc
   synchronizer/static_communicator.hh
   synchronizer/static_communicator_dummy.hh
   synchronizer/static_communicator_inline_impl.hh
   synchronizer/synchronizer.cc
   synchronizer/synchronizer.hh
   synchronizer/synchronizer_impl.hh
   synchronizer/synchronizer_impl_tmpl.hh
   synchronizer/synchronizer_registry.cc
   synchronizer/synchronizer_registry.hh
   synchronizer/synchronizer_tmpl.hh
   )
 
 package_declare_elements(core
   ELEMENT_TYPES
   _point_1
   _segment_2
   _segment_3
   _triangle_3
   _triangle_6
   _quadrangle_4
   _quadrangle_8
   _tetrahedron_4
   _tetrahedron_10
   _pentahedron_6
   _pentahedron_15
   _hexahedron_8
   _hexahedron_20
   KIND regular
   GEOMETRICAL_TYPES
   _gt_point
   _gt_segment_2
   _gt_segment_3
   _gt_triangle_3
   _gt_triangle_6
   _gt_quadrangle_4
   _gt_quadrangle_8
   _gt_tetrahedron_4
   _gt_tetrahedron_10
   _gt_hexahedron_8
   _gt_hexahedron_20
   _gt_pentahedron_6
   _gt_pentahedron_15
   INTERPOLATION_TYPES
   _itp_lagrange_point_1
   _itp_lagrange_segment_2
   _itp_lagrange_segment_3
   _itp_lagrange_triangle_3
   _itp_lagrange_triangle_6
   _itp_lagrange_quadrangle_4
   _itp_serendip_quadrangle_8
   _itp_lagrange_tetrahedron_4
   _itp_lagrange_tetrahedron_10
   _itp_lagrange_hexahedron_8
   _itp_serendip_hexahedron_20
   _itp_lagrange_pentahedron_6
   _itp_lagrange_pentahedron_15
   GEOMETRICAL_SHAPES
   _gst_point
   _gst_triangle
   _gst_square
   _gst_prism
   GAUSS_INTEGRATION_TYPES
   _git_point
   _git_segment
   _git_triangle
   _git_tetrahedron
   _git_pentahedron
   INTERPOLATION_KIND _itk_lagrangian
   FE_ENGINE_LISTS
   gradient_on_integration_points
   interpolate_on_integration_points
   interpolate
   compute_normals_on_integration_points
   inverse_map
   contains
   compute_shapes
   compute_shapes_derivatives
   get_shapes_derivatives
   )
 
 package_declare_material_infos(core
   LIST AKANTU_CORE_MATERIAL_LIST
   INCLUDE material_core_includes.hh
   )
 
 package_declare_documentation_files(core
   manual.sty
   manual.cls
   manual.tex
   manual-macros.sty
   manual-titlepages.tex
   manual-authors.tex
   manual-introduction.tex
   manual-gettingstarted.tex
   manual-io.tex
   manual-feengine.tex
   manual-solidmechanicsmodel.tex
   manual-constitutive-laws.tex
   manual-lumping.tex
   manual-elements.tex
   manual-appendix-elements.tex
   manual-appendix-materials.tex
   manual-appendix-packages.tex
   manual-backmatter.tex
   manual-bibliography.bib
   manual-bibliographystyle.bst
 
   figures/bc_and_ic_example.pdf
   figures/boundary.pdf
   figures/boundary.svg
   figures/dirichlet.pdf
   figures/dirichlet.svg
   figures/doc_wheel.pdf
   figures/doc_wheel.svg
   figures/dynamic_analysis.png
   figures/explicit_dynamic.pdf
   figures/explicit_dynamic.svg
   figures/static.pdf
   figures/static.svg
   figures/hooke_law.pdf
   figures/hot-point-1.png
   figures/hot-point-2.png
   figures/implicit_dynamic.pdf
   figures/implicit_dynamic.svg
   figures/insertion.pdf
   figures/interpolate.pdf
   figures/interpolate.svg
   figures/problemDomain.pdf_tex
   figures/problemDomain.pdf
   figures/static_analysis.png
   figures/stress_strain_el.pdf
   figures/tangent.pdf
   figures/tangent.svg
   figures/vectors.pdf
   figures/vectors.svg
 
   figures/stress_strain_neo.pdf
   figures/visco_elastic_law.pdf
   figures/isotropic_hardening_plasticity.pdf
   figures/stress_strain_visco.pdf
 
   figures/elements/hexahedron_8.pdf
   figures/elements/hexahedron_8.svg
   figures/elements/quadrangle_4.pdf
   figures/elements/quadrangle_4.svg
   figures/elements/quadrangle_8.pdf
   figures/elements/quadrangle_8.svg
   figures/elements/segment_2.pdf
   figures/elements/segment_2.svg
   figures/elements/segment_3.pdf
   figures/elements/segment_3.svg
   figures/elements/tetrahedron_10.pdf
   figures/elements/tetrahedron_10.svg
   figures/elements/tetrahedron_4.pdf
   figures/elements/tetrahedron_4.svg
   figures/elements/triangle_3.pdf
   figures/elements/triangle_3.svg
   figures/elements/triangle_6.pdf
   figures/elements/triangle_6.svg
   figures/elements/xtemp.pdf
   )
 
 package_declare_documentation(core
   "This package is the core engine of \\akantu. It depends on:"
   "\\begin{itemize}"
   "\\item A C++ compiler (\\href{http://gcc.gnu.org/}{GCC} >= 4, or \\href{https://software.intel.com/en-us/intel-compilers}{Intel})."
   "\\item The cross-platform, open-source \\href{http://www.cmake.org/}{CMake} build system."
   "\\item The \\href{http://www.boost.org/}{Boost} C++ portable libraries."
   "\\item The \\href{http://www.zlib.net/}{zlib} compression library."
   "\\end{itemize}"
   ""
   "Under Ubuntu (14.04 LTS) the installation can be performed using the commands:"
   "\\begin{command}"
   "  > sudo apt-get install cmake libboost-dev zlib1g-dev g++"
   "\\end{command}"
   ""
   "Under Mac OS X the installation requires the following steps:"
   "\\begin{itemize}"
   "\\item Install Xcode"
   "\\item Install the command line tools."
   "\\item Install the MacPorts project which allows to automatically"
   "download and install opensource packages."
   "\\end{itemize}"
   "Then the following commands should be typed in a terminal:"
   "\\begin{command}"
   "  > sudo port install cmake gcc48 boost"
   "\\end{command}"
   )
 
 find_program(READLINK_COMMAND readlink)
 find_program(ADDR2LINE_COMMAND addr2line)
 find_program(PATCH_COMMAND patch)
 mark_as_advanced(READLINK_COMMAND)
 mark_as_advanced(ADDR2LINE_COMMAND)
 
 package_declare_extra_files_to_package(core
   SOURCES
     common/aka_element_classes_info.hh.in
     common/aka_config.hh.in
     model/solid_mechanics/material_list.hh.in
   )
 
 if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9))
   package_set_compile_flags(core CXX "-Wno-undefined-var-template")
 endif()
 
 if(DEFINED AKANTU_CXX11_FLAGS)
   package_declare(core_cxx11 NOT_OPTIONAL
     DESCRIPTION "C++ 11 additions for Akantu core"
     COMPILE_FLAGS CXX "${AKANTU_CXX11_FLAGS}")
 
   if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
     if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.6")
       set(AKANTU_CORE_CXX11 OFF CACHE BOOL "C++ 11 additions for Akantu core - not supported by the selected compiler" FORCE)
     endif()
   endif()
 
   package_declare_documentation(core_cxx11
     "This option activates some features of the C++11 standard. This is usable with GCC>=4.7 or Intel>=13.")
 else()
   if(CMAKE_VERSION VERSION_LESS 3.1)
     message(FATAL_ERROR "Since version 3.0 Akantu requires at least c++11 capable compiler")
   endif()
 endif()
diff --git a/src/common/aka_grid_dynamic.hh b/src/common/aka_grid_dynamic.hh
index 8de0a6a78..ccc2bf128 100644
--- a/src/common/aka_grid_dynamic.hh
+++ b/src/common/aka_grid_dynamic.hh
@@ -1,494 +1,472 @@
 /**
  * @file   aka_grid_dynamic.hh
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Feb 21 2013
  * @date last modification: Sat Sep 26 2015
  *
  * @brief  Grid that is auto balanced
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_array.hh"
 #include "aka_types.hh"
 
 #include <iostream>
 
 /* -------------------------------------------------------------------------- */
 #include <map>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_GRID_DYNAMIC_HH__
 #define __AKANTU_AKA_GRID_DYNAMIC_HH__
 
 namespace akantu {
 
 class Mesh;
 
 template<typename T>
 class SpatialGrid {
 public:
   SpatialGrid(UInt dimension) : dimension(dimension),
                                 spacing(dimension),
                                 center(dimension),
                                 lower(dimension),
                                 upper(dimension),
                                 empty_cell() {}
 
   SpatialGrid(UInt dimension,
               const Vector<Real> & spacing,
               const Vector<Real> & center) : dimension(dimension),
                                                     spacing(spacing),
                                                     center(center),
                                                     lower(dimension),
                                                     upper(dimension),
                                                     empty_cell() {
     for (UInt i = 0; i < dimension; ++i) {
       lower(i) =   std::numeric_limits<Real>::max();
       upper(i) = - std::numeric_limits<Real>::max();
     }
   }
 
   virtual ~SpatialGrid() {};
 
   class neighbor_cells_iterator;
   class cells_iterator;
 
   class CellID {
   public:
     CellID() : ids() {}
     CellID(UInt dimention) : ids(dimention) {}
     void setID(UInt dir, Int id) { ids(dir) = id; }
     Int getID(UInt dir) const { return ids(dir); }
 
     bool operator<(const CellID & id) const {
       return std::lexicographical_compare(ids.storage(), ids.storage() + ids.size(),
                                           id.ids.storage(), id.ids.storage() + id.ids.size());
     }
 
     bool operator==(const CellID & id) const {
       return std::equal(ids.storage(), ids.storage() + ids.size(),
                         id.ids.storage());
     }
 
     bool operator!=(const CellID & id) const {
       return !(operator==(id));
     }
 
   private:
     friend class neighbor_cells_iterator;
     friend class cells_iterator;
     Vector<Int> ids;
   };
 
   /* -------------------------------------------------------------------------- */
   class Cell {
   public:
     typedef typename std::vector<T>::iterator iterator;
     typedef typename std::vector<T>::const_iterator const_iterator;
 
     Cell() : id(), data() { }
 
     Cell(const CellID &cell_id) : id(cell_id), data() { }
 
     bool operator==(const Cell & cell) const { return id == cell.id; }
     bool operator!=(const Cell & cell) const { return id != cell.id; }
 
     Cell & add(const T & d) { data.push_back(d); return *this; }
 
     iterator begin() { return data.begin(); }
     const_iterator begin() const { return data.begin(); }
 
     iterator end() { return data.end(); }
     const_iterator end() const { return data.end(); }
   private:
     CellID id;
     std::vector<T> data;
   };
 
 private:
   typedef std::map<CellID, Cell> cells_container;
 
 public:
 
   const Cell & getCell(const CellID & cell_id) const {
     typename cells_container::const_iterator it = cells.find(cell_id);
     if(it != cells.end()) return it->second;
     else return empty_cell;
   }
   
   typename Cell::iterator beginCell(const CellID & cell_id) {
     typename cells_container::iterator it = cells.find(cell_id);
     if(it != cells.end()) return it->second.begin();
     else return empty_cell.begin();
   }
 
   typename Cell::iterator endCell(const CellID & cell_id) {
     typename cells_container::iterator it = cells.find(cell_id);
     if(it != cells.end()) return it->second.end();
     else return empty_cell.end();
   }
 
   typename Cell::const_iterator beginCell(const CellID & cell_id) const {
     typename cells_container::const_iterator it = cells.find(cell_id);
     if(it != cells.end()) return it->second.begin();
     else return empty_cell.begin();
   }
 
   typename Cell::const_iterator endCell(const CellID & cell_id) const {
     typename cells_container::const_iterator it = cells.find(cell_id);
     if(it != cells.end()) return it->second.end();
     else return empty_cell.end();
   }
 
 
   class neighbor_cells_iterator : private std::iterator<std::forward_iterator_tag, UInt> {
   public:
     neighbor_cells_iterator(const CellID & cell_id, bool end) :
       cell_id(cell_id),
       position(cell_id.ids.size(), end ? 1 : -1) {
 
       this->updateIt();
       if(end) this->it++;
     }
 
     neighbor_cells_iterator& operator++() {
       UInt i = 0;
       for (; i < position.size() && position(i) == 1; ++i);
 
       if(i == position.size()) ++it;
       else {
         for (UInt j = 0; j < i; ++j) position(j) = -1;
         position(i)++;
         updateIt();
       }
 
       return *this;
     }
 
     neighbor_cells_iterator operator++(int) { neighbor_cells_iterator tmp(*this); operator++(); return tmp; };
 
     bool operator==(const neighbor_cells_iterator& rhs) const { return cell_id == rhs.cell_id && it == rhs.it; };
     bool operator!=(const neighbor_cells_iterator& rhs) const { return ! operator==(rhs); };
 
     CellID operator*() const {
       CellID cur_cell_id(cell_id);
       cur_cell_id.ids += position;
       return cur_cell_id;
     };
 
   private:
     void updateIt() {
       it = 0;
       for (UInt i = 0; i < position.size(); ++i) it = it * 3 + (position(i) + 1);
     }
 
   private:
     /// central cell id
     const CellID & cell_id;
 
     // number representing the current neighbor in base 3;
     UInt it;
 
     Vector<Int> position;
   };
 
 
   class cells_iterator : private std::iterator<std::forward_iterator_tag, CellID> {
   public:
     cells_iterator(typename std::map<CellID, Cell>::const_iterator it) :
       it(it) { }
 
     cells_iterator & operator++() {
       this->it++;
       return *this;
     }
 
 
     cells_iterator operator++(int) {cells_iterator tmp(*this); operator++(); return tmp; };
 
     bool operator==(const cells_iterator& rhs) const { return it == rhs.it; };
     bool operator!=(const cells_iterator& rhs) const { return ! operator==(rhs); };
 
     CellID operator*() const {
       CellID cur_cell_id(this->it->first);
       return cur_cell_id;
     };
 
   private:
 
     /// map iterator
     typename std::map<CellID, Cell>::const_iterator it;
 
   };
 
 
 
 
 public:
   template<class vector_type>
   Cell & insert(const T & d, const vector_type & position) {
     CellID cell_id = getCellID(position);
 
     typename cells_container::iterator it = cells.find(cell_id);
 
     if(it == cells.end()) {
       Cell cell(cell_id);
 // #if defined(AKANTU_NDEBUG)
       Cell & tmp = (cells[cell_id] = cell).add(d);
 // #else
 //       Cell & tmp = (cells[cell_id] = cell).add(d, position);
 // #endif
 
       for (UInt i = 0; i < dimension; ++i) {
         Real posl = center(i) + cell_id.getID(i) * spacing(i);
         Real posu = posl + spacing(i);
         if(posl < lower(i)) lower(i) = posl;
         if(posu > upper(i)) upper(i) = posu;
       }
       return tmp;
     } else {
 // #if defined(AKANTU_NDEBUG)
       return it->second.add(d);
 // #else
 //       return it->second.add(d, position);
 // #endif
     }
   }
 
 
   inline neighbor_cells_iterator beginNeighborCells(const CellID & cell_id) const {
     return neighbor_cells_iterator(cell_id, false);
   }
 
   inline neighbor_cells_iterator endNeighborCells(const CellID & cell_id) const {
     return neighbor_cells_iterator(cell_id, true);
   }
 
   inline cells_iterator beginCells() const {
     typename std::map<CellID, Cell>::const_iterator begin = this->cells.begin();
     return cells_iterator(begin);
   }
 
   inline cells_iterator endCells() const {
     typename std::map<CellID, Cell>::const_iterator end = this->cells.end();
     return cells_iterator(end);
   }
 
 
 
 
 
   template<class vector_type>
   CellID getCellID(const vector_type & position) const {
     CellID cell_id(dimension);
     for (UInt i = 0; i < dimension; ++i) {
       cell_id.setID(i, getCellID(position(i), i));
     }
     return cell_id;
   }
 
 
   void printself(std::ostream & stream, int indent = 0) const {
     std::string space;
     for(Int i = 0; i < indent; i++, space += AKANTU_INDENT);
 
     std::streamsize prec        = stream.precision();
     std::ios_base::fmtflags ff  = stream.flags();
 
     stream.setf (std::ios_base::showbase);
     stream.precision(5);
 
     stream << space << "SpatialGrid<" << debug::demangle(typeid(T).name()) << "> [" << std::endl;
     stream << space << " + dimension    : " << this->dimension << std::endl;
     stream << space << " + lower bounds : {";
     for (UInt i = 0; i < lower.size(); ++i) { if(i != 0) stream << ", "; stream << lower(i); };
     stream << "}" << std::endl;
     stream << space << " + upper bounds : {";
     for (UInt i = 0; i < upper.size(); ++i) { if(i != 0) stream << ", "; stream << upper(i); };
     stream << "}" << std::endl;
     stream << space << " + spacing : {";
     for (UInt i = 0; i < spacing.size(); ++i) { if(i != 0) stream << ", "; stream << spacing(i); };
     stream << "}" << std::endl;
     stream << space << " + center : {";
     for (UInt i = 0; i < center.size(); ++i) { if(i != 0) stream << ", "; stream << center(i); };
     stream << "}" << std::endl;
 
     stream << space << " + nb_cells     : " << this->cells.size() << "/";
     Vector<Real> dist(this->dimension);
     dist = upper;
     dist -= lower;
     for (UInt i = 0; i < this->dimension; ++i) {
       dist(i) /= spacing(i); 
     }
     UInt nb_cells = std::ceil(dist(0));
     for (UInt i = 1; i < this->dimension; ++i) {
       nb_cells *= std::ceil(dist(i));
     }
     stream << nb_cells << std::endl;
     stream << space << "]" << std::endl;
 
     stream.precision(prec);
     stream.flags(ff);
   }
 
   void saveAsMesh(Mesh & mesh) const;
 
 private:
   /* -------------------------------------------------------------------------- */
   inline UInt getCellID(Real position, UInt direction) const {
     AKANTU_DEBUG_ASSERT(direction < center.size(), "The direction asked ("
                         << direction << ") is out of range " << center.size());
     Real dist_center = position - center(direction);
     Int id = std::floor(dist_center / spacing(direction));
     //if(dist_center < 0) id--;
     return id;
   }
 
   friend class GridSynchronizer;
 public:
   AKANTU_GET_MACRO(LowerBounds, lower, const Vector<Real> &);
   AKANTU_GET_MACRO(UpperBounds, upper, const Vector<Real> &);
   AKANTU_GET_MACRO(Spacing, spacing, const Vector<Real> &);
 
 protected:
   UInt dimension;
 
   cells_container cells;
 
   Vector<Real> spacing;
   Vector<Real> center;
 
   Vector<Real> lower;
   Vector<Real> upper;
 
   Cell empty_cell;
 };
 
 /// standard output stream operator
 template<typename T>
 inline std::ostream & operator <<(std::ostream & stream, const SpatialGrid<T> & _this)
 {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 #include "mesh.hh"
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 template<typename T>
 void SpatialGrid<T>::saveAsMesh(Mesh & mesh) const {
   Array<Real> & nodes = const_cast<Array<Real> &>(mesh.getNodes());
 
   ElementType type;
   switch(dimension) {
   case 1: type = _segment_2; break;
   case 2: type = _quadrangle_4; break;
   case 3: type = _hexahedron_8; break;
   }
 
   mesh.addConnectivityType(type);
-  Array<UInt> & connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(type));
-  Array<UInt> & uint_data = *mesh.getDataPointer<UInt>("tag_1", type);
-
-  typename cells_container::const_iterator it  = cells.begin();
-  typename cells_container::const_iterator end = cells.end();
+  auto & connectivity = const_cast<Array<UInt> &>(mesh.getConnectivity(type));
+  auto & uint_data = mesh.getDataPointer<UInt>("tag_1", type);
 
   Vector<Real> pos(dimension);
 
   UInt global_id = 0;
-  for (;it != end; ++it, ++global_id) {
+  for (auto & cell_pair : cells) {
     UInt cur_node = nodes.getSize();
     UInt cur_elem = connectivity.getSize();
-    const CellID & cell_id = it->first;
+    const CellID & cell_id = cell_pair.first;
 
     for (UInt i = 0; i < dimension; ++i)  pos(i) = center(i) + cell_id.getID(i) * spacing(i);
     nodes.push_back(pos);
     for (UInt i = 0; i < dimension; ++i)  pos(i) += spacing(i);
     nodes.push_back(pos);
 
     connectivity.push_back(cur_node);
     switch(dimension) {
     case 1:
       connectivity(cur_elem, 1) = cur_node + 1;
       break;
     case 2:
       pos(0) -= spacing(0); nodes.push_back(pos);
       pos(0) += spacing(0); pos(1) -= spacing(1); nodes.push_back(pos);
       connectivity(cur_elem, 1) = cur_node + 3;
       connectivity(cur_elem, 2) = cur_node + 1;
       connectivity(cur_elem, 3) = cur_node + 2;
       break;
     case 3:
                             pos(1) -= spacing(1); pos(2) -= spacing(2); nodes.push_back(pos);
                             pos(1) += spacing(1);                       nodes.push_back(pos);
       pos(0) -= spacing(0);                                             nodes.push_back(pos);
 
                             pos(1) -= spacing(1); pos(2) += spacing(2); nodes.push_back(pos);
       pos(0) += spacing(0);                                             nodes.push_back(pos);
       pos(0) -= spacing(0); pos(1) += spacing(1);                       nodes.push_back(pos);
 
 
       connectivity(cur_elem, 1) = cur_node + 2;
       connectivity(cur_elem, 2) = cur_node + 3;
       connectivity(cur_elem, 3) = cur_node + 4;
       connectivity(cur_elem, 4) = cur_node + 5;
       connectivity(cur_elem, 5) = cur_node + 6;
       connectivity(cur_elem, 6) = cur_node + 1;
       connectivity(cur_elem, 7) = cur_node + 7;
       break;
     }
     uint_data.push_back(global_id);
-  }
 
-// #if not defined(AKANTU_NDEBUG)
-//   mesh.addConnectivityType(_point_1);
-//   Array<UInt> & connectivity_pos = const_cast<Array<UInt> &>(mesh.getConnectivity(_point_1));
-//   Array<UInt> & uint_data_pos = *mesh.getDataPointer<UInt>( "tag_1", _point_1);
-//   Array<UInt> & uint_data_pos_ghost = *mesh.getDataPointer<UInt>("tag_0", _point_1);
-
-//   it  = cells.begin();
-//   global_id = 0;
-//   for (;it != end; ++it, ++global_id) {
-//     typename Cell::position_iterator cell_it  = it->second.begin_pos();
-//     typename Cell::const_iterator    cell_it_cont  = it->second.begin();
-//     typename Cell::position_iterator cell_end = it->second.end_pos();
-//     for (;cell_it != cell_end; ++cell_it, ++cell_it_cont) {
-//       nodes.push_back(*cell_it);
-//       connectivity_pos.push_back(nodes.getSize()-1);
-//       uint_data_pos.push_back(global_id);
-//       uint_data_pos_ghost.push_back(cell_it_cont->ghost_type==_ghost);
-//     }
-//   }
-// #endif
+    ++global_id;
+  }
 }
 
 } // akantu
 
 
 
 #endif /* __AKANTU_AKA_GRID_DYNAMIC_HH__ */
diff --git a/src/fe_engine/element.hh b/src/fe_engine/element.hh
index 3541a12e7..4ec8329b0 100644
--- a/src/fe_engine/element.hh
+++ b/src/fe_engine/element.hh
@@ -1,127 +1,117 @@
 /**
  * @file   element.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Sep 02 2014
  * @date last modification: Sat Jul 11 2015
  *
  * @brief  Element helper class
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
+/* -------------------------------------------------------------------------- */
+#include "aka_common.hh"
+/* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_HH__
 #define __AKANTU_ELEMENT_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Element                                                                    */
 /* -------------------------------------------------------------------------- */
 class Element;
 extern const Element ElementNull;
 
 class Element {
-
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
-
 public:
   explicit Element(ElementType type = _not_defined, UInt element = 0,
           GhostType ghost_type = _not_ghost, ElementKind kind = _ek_regular) :
     type(type), element(element),
     ghost_type(ghost_type), kind(kind) {};
 
   Element(const Element & element) {
     this->type    = element.type;
     this->element = element.element;
     this->ghost_type = element.ghost_type;
     this->kind = element.kind;
   }
 
-  virtual ~Element() {};
+  virtual ~Element() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
-
 public:
-
   inline bool operator==(const Element & elem) const {
     return ((element == elem.element)
             && (type == elem.type)
             && (ghost_type == elem.ghost_type)
             && (kind == elem.kind));
   }
 
   inline bool operator!=(const Element & elem) const {
     return ((element != elem.element)
             || (type != elem.type)
             || (ghost_type != elem.ghost_type)
             || (kind != elem.kind));
   }
 
-  bool operator<(const Element& rhs) const {
+  bool operator<(const Element & rhs) const {
     bool res = (rhs == ElementNull) || ((this->kind < rhs.kind) ||
                                         ((this->kind == rhs.kind) &&
                                          ((this->ghost_type < rhs.ghost_type) ||
                                           ((this->ghost_type == rhs.ghost_type) &&
                                            ((this->type < rhs.type) ||
                                             ((this->type == rhs.type) &&
                                              (this->element < rhs.element)))))));
     return res;
   }
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
-  
 public:
-
   const ElementType & getType(){return type;}
   const UInt & getIndex(){return element;};
   const GhostType & getGhostType(){return ghost_type;}
   const ElementKind & getElementKind(){return kind;}
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
-
 public:
   ElementType type;
   UInt element;
   GhostType ghost_type;
   ElementKind kind;
 };
 
-struct CompElementLess {
-  bool operator() (const Element& lhs, const Element& rhs) const {
-    return lhs < rhs;
-  }
-};
-
 } // akantu
 
 #endif /* __AKANTU_ELEMENT_HH__ */
diff --git a/src/io/mesh_io.cc b/src/io/mesh_io.cc
index e4ed84cca..d2aee2f94 100644
--- a/src/io/mesh_io.cc
+++ b/src/io/mesh_io.cc
@@ -1,156 +1,148 @@
 /**
  * @file   mesh_io.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Mon Jun 01 2015
  *
  * @brief  common part for all mesh io classes
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
-#include "aka_common.hh"
 #include "mesh_io.hh"
-
+#include "aka_common.hh"
+#include "aka_zip.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MeshIO::MeshIO() {
   canReadSurface = false;
   canReadExtendedData = false;
 }
 
 /* -------------------------------------------------------------------------- */
 MeshIO::~MeshIO() {}
 
 /* -------------------------------------------------------------------------- */
-MeshIO * MeshIO::getMeshIO(const std::string & filename,
-                           const MeshIOType & type) {
+std::unique_ptr<MeshIO> MeshIO::getMeshIO(const std::string & filename,
+                                          const MeshIOType & type) {
   MeshIOType t = type;
   if (type == _miot_auto) {
     std::string::size_type idx = filename.rfind('.');
     std::string ext;
     if (idx != std::string::npos) {
       ext = filename.substr(idx + 1);
     }
 
     if (ext == "msh") {
       t = _miot_gmsh;
     } else if (ext == "diana") {
       t = _miot_diana;
     } else if (ext == "inp") {
       t = _miot_abaqus;
     } else
       AKANTU_EXCEPTION("Cannot guess the type of file of "
                        << filename << " (ext " << ext << "). "
                        << "Please provide the MeshIOType to the read function");
   }
 
   switch (t) {
   case _miot_gmsh:
-    return new MeshIOMSH();
+    return std::make_unique<MeshIOMSH>();
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
   case _miot_gmsh_struct:
-    return new MeshIOMSHStruct();
+    return std::make_unique<MeshIOMSHStruct>();
 #endif
   case _miot_diana:
-    return new MeshIODiana();
+    return std::make_unique<MeshIODiana>();
   case _miot_abaqus:
-    return new MeshIOAbaqus();
+    return std::make_unique<MeshIOAbaqus>();
   default:
-    return NULL;
+    return nullptr;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIO::read(const std::string & filename, Mesh & mesh,
                   const MeshIOType & type) {
-  MeshIO * mesh_io = getMeshIO(filename, type);
+  std::unique_ptr<MeshIO> mesh_io = getMeshIO(filename, type);
   mesh_io->read(filename, mesh);
-  delete mesh_io;
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIO::write(const std::string & filename, Mesh & mesh,
                    const MeshIOType & type) {
-  MeshIO * mesh_io = getMeshIO(filename, type);
+  std::unique_ptr<MeshIO> mesh_io = getMeshIO(filename, type);
   mesh_io->write(filename, mesh);
-  delete mesh_io;
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIO::constructPhysicalNames(const std::string & tag_name, Mesh & mesh) {
-
   if (!phys_name_map.empty()) {
     for (Mesh::type_iterator type_it = mesh.firstType();
          type_it != mesh.lastType(); ++type_it) {
 
-      Array<std::string> * name_vec =
+      auto & name_vec =
           mesh.getDataPointer<std::string>("physical_names", *type_it);
 
-      const Array<UInt> & tags_vec = mesh.getData<UInt>(tag_name, *type_it);
+      const auto & tags_vec = mesh.getData<UInt>(tag_name, *type_it);
 
-      for (UInt i(0); i < tags_vec.getSize(); i++) {
-        std::map<UInt, std::string>::const_iterator map_it =
-            phys_name_map.find(tags_vec(i));
+      for (auto pair : zip(tags_vec, name_vec)) {
+        auto tag = std::get<0>(pair);
+        auto & name = std::get<1>(pair);
+        auto map_it = phys_name_map.find(tag);
 
         if (map_it == phys_name_map.end()) {
           std::stringstream sstm;
-          sstm << tags_vec(i);
-          name_vec->operator()(i) = sstm.str();
+          sstm << tag;
+
+          name = sstm.str();
         } else {
-          name_vec->operator()(i) = map_it->second;
+          name = map_it->second;
         }
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
-
 void MeshIO::printself(std::ostream & stream, int indent) const {
-
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   if (phys_name_map.size()) {
-
     stream << space << "Physical map:" << std::endl;
-
-    std::map<UInt, std::string>::const_iterator it = phys_name_map.begin();
-    std::map<UInt, std::string>::const_iterator end = phys_name_map.end();
-
-    for (; it != end; ++it) {
-      stream << space << it->first << ": " << it->second << std::endl;
+    for (auto & pair : phys_name_map) {
+      stream << space << pair.first << ": " << pair.second << std::endl;
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 
-} // akantu
+} // namespace akantu
diff --git a/src/io/mesh_io.hh b/src/io/mesh_io.hh
index 680d7d418..5e4860613 100644
--- a/src/io/mesh_io.hh
+++ b/src/io/mesh_io.hh
@@ -1,118 +1,118 @@
 /**
  * @file   mesh_io.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Mon Jun 01 2015
  *
  * @brief  interface of a mesh io class, reader and writer
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MESH_IO_HH__
 #define __AKANTU_MESH_IO_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_accessor.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshIO {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MeshIO();
 
   virtual ~MeshIO();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void read(const std::string & filename, Mesh & mesh, const MeshIOType & type);
   void write(const std::string & filename, Mesh & mesh,
              const MeshIOType & type);
 
   /// read a mesh from the file
   virtual void read(__attribute__((unused)) const std::string & filename,
                     __attribute__((unused)) Mesh & mesh) {}
 
   /// write a mesh to a file
   virtual void write(__attribute__((unused)) const std::string & filename,
                      __attribute__((unused)) const Mesh & mesh) {}
 
   /// function to request the manual construction of the physical names maps
   virtual void constructPhysicalNames(const std::string & tag_name,
                                       Mesh & mesh);
 
   /// method to permit to be printed to a generic stream
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// static contruction of a meshio object
-  static MeshIO * getMeshIO(const std::string & filename,
-                            const MeshIOType & type);
+  static std::unique_ptr<MeshIO> getMeshIO(const std::string & filename,
+                                           const MeshIOType & type);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   std::map<UInt, std::string> & getPhysicalNameMap() { return phys_name_map; }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   bool canReadSurface;
 
   bool canReadExtendedData;
 
   /// correspondance between a tag and physical names (if applicable)
   std::map<UInt, std::string> phys_name_map;
 };
 
 /* -------------------------------------------------------------------------- */
 
 inline std::ostream & operator<<(std::ostream & stream, const MeshIO & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 
-} // akantu
+} // namespace akantu
 
-#include "mesh_io_msh.hh"
-#include "mesh_io_diana.hh"
 #include "mesh_io_abaqus.hh"
+#include "mesh_io_diana.hh"
+#include "mesh_io_msh.hh"
 
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
 #include "mesh_io_msh_struct.hh"
 #endif
 
 #endif /* __AKANTU_MESH_IO_HH__ */
diff --git a/src/io/mesh_io/mesh_io_abaqus.cc b/src/io/mesh_io/mesh_io_abaqus.cc
index 2caf717c8..7c3461a79 100644
--- a/src/io/mesh_io/mesh_io_abaqus.cc
+++ b/src/io/mesh_io/mesh_io_abaqus.cc
@@ -1,483 +1,475 @@
 /**
  * @file   mesh_io_abaqus.cc
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jan 04 2013
  * @date last modification: Fri Dec 11 2015
  *
  * @brief  read a mesh from an abaqus input file
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 // std library header files
 #include <fstream>
 
 // akantu header files
 #include "mesh_io_abaqus.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 
 #include "element_group.hh"
 #include "node_group.hh"
 
 
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #  define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #  if GCC_VERSION > 40600
 #    pragma GCC diagnostic push
 #  endif
 #  pragma GCC diagnostic ignored "-Wunused-local-typedefs"
 #endif
 
 /* -------------------------------------------------------------------------- */
 #include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix.hpp>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MeshIOAbaqus::MeshIOAbaqus() {}
 
 /* -------------------------------------------------------------------------- */
 MeshIOAbaqus::~MeshIOAbaqus() {}
 
 /* -------------------------------------------------------------------------- */
 namespace spirit = boost::spirit;
 namespace qi = boost::spirit::qi;
 namespace ascii = boost::spirit::ascii;
 namespace lbs = boost::spirit::qi::labels;
 namespace phx = boost::phoenix;
 
 /* -------------------------------------------------------------------------- */
 void element_read(Mesh & mesh, const ElementType & type, UInt id, const std::vector<Int> & conn,
                   const std::map<UInt, UInt> & nodes_mapping,
                   std::map<UInt, Element> & elements_mapping) {
   Vector<UInt> tmp_conn(Mesh::getNbNodesPerElement(type));
 
   AKANTU_DEBUG_ASSERT(conn.size() == tmp_conn.size(),
 		      "The nodes in the Abaqus file have too many coordinates"
 		      << " for the mesh you try to fill.");
 
   mesh.addConnectivityType(type);
   Array<UInt> & connectivity = mesh.getConnectivity(type);
 
   UInt i = 0;
   for (std::vector<Int>::const_iterator it = conn.begin(); it != conn.end(); ++it) {
     std::map<UInt, UInt>::const_iterator nit = nodes_mapping.find(*it);
     AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
 			"There is an unknown node in the connectivity.");
     tmp_conn[i++] = nit->second;
   }
   Element el(type, connectivity.getSize());
   elements_mapping[id] = el;
   connectivity.push_back(tmp_conn);
 }
 
 
 void node_read(Mesh & mesh, UInt id, const std::vector<Real> & pos,
 	       std::map<UInt, UInt> & nodes_mapping) {
   Vector<Real> tmp_pos(mesh.getSpatialDimension());
   UInt i = 0;
   for (std::vector<Real>::const_iterator it = pos.begin();
        it != pos.end() || i < mesh.getSpatialDimension(); ++it)
     tmp_pos[i++] = *it;
 
   nodes_mapping[id] = mesh.getNbNodes();
   mesh.getNodes().push_back(tmp_pos);
 }
 
 
 /* ------------------------------------------------------------------------ */
 void add_element_to_group(ElementGroup * el_grp, UInt element,
 			  const std::map<UInt, Element> & elements_mapping) {
   std::map<UInt, Element>::const_iterator eit = elements_mapping.find(element);
   AKANTU_DEBUG_ASSERT(eit != elements_mapping.end(),
 		      "There is an unknown element ("
 		      << element << ") in the in the ELSET "
 		      << el_grp->getName() << ".");
 
   el_grp->add(eit->second, true, false);
 }
 
 ElementGroup * element_group_create(Mesh & mesh, const ID & name) {
   Mesh::element_group_iterator eg_it = mesh.element_group_find(name);
   if (eg_it != mesh.element_group_end()) {
     return eg_it->second;
   } else {
     return &mesh.createElementGroup(name, _all_dimensions);
   }
 }
 
 NodeGroup * node_group_create(Mesh & mesh, const ID & name) {
   Mesh::node_group_iterator ng_it = mesh.node_group_find(name);
   if (ng_it != mesh.node_group_end()) {
     return ng_it->second;
   } else {
     return &mesh.createNodeGroup(name, mesh.getSpatialDimension());
   }
 }
 
 void add_node_to_group(NodeGroup * node_grp, UInt node,
 		       const std::map<UInt, UInt> & nodes_mapping) {
   std::map<UInt, UInt>::const_iterator nit = nodes_mapping.find(node);
 
   AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
 		      "There is an unknown node in the in the NSET "
 		      << node_grp->getName() << ".");
   
   node_grp->add(nit->second, false);
 }
 
 void optimize_group(NodeGroup * grp) { grp->optimize(); }
 void optimize_element_group(ElementGroup * grp) { grp->optimize(); }
 
 /* -------------------------------------------------------------------------- */
 template <class Iterator> struct AbaqusSkipper : qi::grammar<Iterator> {
   AbaqusSkipper() : AbaqusSkipper::base_type(skip, "abaqus_skipper") {
     /* clang-format off */
     skip
       =   (ascii::space - spirit::eol)
       |   "**" >> *(qi::char_ - spirit::eol) >> spirit::eol
       ;
     /* clang-format on */
   }
   qi::rule<Iterator> skip;
 };
 
 /* -------------------------------------------------------------------------- */
 template <class Iterator, typename Skipper = AbaqusSkipper<Iterator> >
 struct AbaqusMeshGrammar : qi::grammar<Iterator, void(), Skipper> {
 public:
   AbaqusMeshGrammar(Mesh & mesh)
       : AbaqusMeshGrammar::base_type(start, "abaqus_mesh_reader"), mesh(mesh) {
 
     /* clang-format off */
     start
       =  *(
              (qi::char_('*')
                 >  (   (qi::no_case[ qi::lit("node output")    ] > any_section)
                    |   (qi::no_case[ qi::lit("element output") ] > any_section)
                    |   (qi::no_case[ qi::lit("node")           ] > nodes)
                    |   (qi::no_case[ qi::lit("element")        ] > elements)
                    |   (qi::no_case[ qi::lit("heading")        ] > header)
                    |   (qi::no_case[ qi::lit("elset")          ] > elements_set)
                    |   (qi::no_case[ qi::lit("nset")           ] > nodes_set)
                    |   (qi::no_case[ qi::lit("material")       ] > material)
                    |   (keyword > any_section)
                    )
              )
           |  spirit::eol
           )
       ;
 
     header
       =   spirit::eol
       >   *any_line
       ;
 
     nodes
       =   *(qi::char_(',') >> option)
            >> spirit::eol
            >> *( (qi::int_
                   > node_position) [ phx::bind(&node_read,
 						 phx::ref(mesh),
 						 lbs::_1,
 						 lbs::_2,
 						 phx::ref(abaqus_nodes_to_akantu)) ]
                   >> spirit::eol
                )
       ;
 
     elements
       =   (
              (  qi::char_(',') >> qi::no_case[qi::lit("type")] >> '='
                 >> abaqus_element_type  [ lbs::_a = lbs::_1 ]
              )
           ^  *(qi::char_(',') >> option)
           )
           >> spirit::eol
           >> *(  (qi::int_
                   > connectivity) [ phx::bind(&element_read,
 						phx::ref(mesh),
 						lbs::_a,
 						lbs::_1,
 						lbs::_2,
 						phx::cref(abaqus_nodes_to_akantu),
 						phx::ref(abaqus_elements_to_akantu)) ]
                  >> spirit::eol
                )
       ;
 
     elements_set
       =   (
              (
                 (  qi::char_(',') >> qi::no_case[ qi::lit("elset") ] >> '='
                    >> value [ lbs::_a = phx::bind<ElementGroup *>(&element_group_create,
 								    phx::ref(mesh),
 								    lbs::_1) ]
                 )
              ^  *(qi::char_(',') >> option)
              )
              >> spirit::eol
              >> qi::skip
                   (qi::char_(',') | qi::space)
 	     [ +(qi::int_ [ phx::bind(&add_element_to_group,
 					lbs::_a,
 					lbs::_1,
 					phx::cref(abaqus_elements_to_akantu)
 					)
                                ]
                      )
                  ]
 	   ) [ phx::bind(&optimize_element_group, lbs::_a) ]
       ;
 
     nodes_set
       =   (
              (
                 (  qi::char_(',')
                    >> qi::no_case[ qi::lit("nset") ] >> '='
                    >> value [ lbs::_a = phx::bind<NodeGroup *>(&node_group_create, phx::ref(mesh), lbs::_1) ]
                 )
              ^  *(qi::char_(',') >> option)
              )
              >> spirit::eol
              >> qi::skip
                  (qi::char_(',') | qi::space)
 	         [ +(qi::int_ [ phx::bind(&add_node_to_group,
 					    lbs::_a,
 					    lbs::_1,
 					    phx::cref(abaqus_nodes_to_akantu)
 					   )
                               ]
                     )
                  ]
            ) [ phx::bind(&optimize_group, lbs::_a) ]
       ;
 
     material
       =   (
              (  qi::char_(',') >> qi::no_case[ qi::lit("name") ] >> '='
                 >> value  [ phx::push_back(phx::ref(material_names), lbs::_1) ]
              )
           ^  *(qi::char_(',') >> option)
           ) >> spirit::eol;
       ;
 
     node_position
       =   +(qi::char_(',') > real [ phx::push_back(lbs::_val, lbs::_1) ])
       ;
 
     connectivity
       = +(qi::char_(',') > qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ])
       ;
 
 
     any_section
       =   *(qi::char_(',') >> option) > spirit::eol
       >   *any_line
       ;
 
     any_line
       =   *(qi::char_ - spirit::eol - qi::char_('*')) >> spirit::eol
       ;
 
     keyword
       =   qi::lexeme[ +(qi::char_ - (qi::char_('*') | spirit::eol)) ]
       ;
 
     option
       = key > -( '=' >> value );
 
     key
       =   qi::char_("a-zA-Z_") >> *(qi::char_("a-zA-Z_0-9") | qi::char_('-'))
       ;
 
     value
       =   key.alias()
       ;
 
     BOOST_SPIRIT_DEBUG_NODE(start);
 
     abaqus_element_type.add
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
       ("BE21"  , _bernoulli_beam_2)
       ("BE31"  , _bernoulli_beam_3)
 #endif
       ("T3D2"  , _segment_2) // Gmsh generates this elements
       ("T3D3"  , _segment_3) // Gmsh generates this elements
       ("CPE3"  , _triangle_3)
       ("CPS3"  , _triangle_3)
       ("DC2D3" , _triangle_3)
       ("CPE6"  , _triangle_6)
       ("CPS6"  , _triangle_6)
       ("DC2D6" , _triangle_6)
       ("CPE4"  , _quadrangle_4)
       ("CPS4"  , _quadrangle_4)
       ("DC2D4" , _quadrangle_4)
       ("CPE8"  , _quadrangle_8)
       ("CPS8"  , _quadrangle_8)
       ("DC2D8" , _quadrangle_8)
       ("C3D4"  , _tetrahedron_4)
       ("DC3D4" , _tetrahedron_4)
       ("C3D8"  , _hexahedron_8)
       ("C3D8R" , _hexahedron_8)
       ("DC3D8" , _hexahedron_8)
       ("C3D10" , _tetrahedron_10)
       ("DC3D10", _tetrahedron_10);
 
 #if !defined(AKANTU_NDEBUG) && defined(AKANTU_CORE_CXX_11)
     qi::on_error<qi::fail>(start, error_handler(lbs::_4, lbs::_3, lbs::_2));
 #endif
     
     start              .name("abaqus-start-rule");
     connectivity       .name("abaqus-connectivity");
     node_position      .name("abaqus-nodes-position");
     nodes              .name("abaqus-nodes");
     any_section        .name("abaqus-any_section");
     header             .name("abaqus-header");
     material           .name("abaqus-material");
     elements           .name("abaqus-elements");
     elements_set       .name("abaqus-elements-set");
     nodes_set          .name("abaqus-nodes-set");
     key                .name("abaqus-key");
     value              .name("abaqus-value");
     option             .name("abaqus-option");
     keyword            .name("abaqus-keyword");
     any_line           .name("abaqus-any-line");
     abaqus_element_type.name("abaqus-element-type");
 
     /* clang-format on */
   }
 
 public:
   AKANTU_GET_MACRO(MaterialNames, material_names,
                    const std::vector<std::string> &);
 
   /* ------------------------------------------------------------------------ */
   /* Rules                                                                    */
   /* ------------------------------------------------------------------------ */
 private:
   qi::rule<Iterator, void(), Skipper> start;
   qi::rule<Iterator, std::vector<int>(), Skipper> connectivity;
   qi::rule<Iterator, std::vector<Real>(), Skipper> node_position;
   qi::rule<Iterator, void(), Skipper> nodes, any_section, header, material;
   qi::rule<Iterator, void(), qi::locals<ElementType>, Skipper> elements;
   qi::rule<Iterator, void(), qi::locals<ElementGroup *>, Skipper> elements_set;
   qi::rule<Iterator, void(), qi::locals<NodeGroup *>, Skipper> nodes_set;
 
   qi::rule<Iterator, std::string(), Skipper> key, value, option, keyword,
       any_line;
 
   qi::real_parser<Real, qi::real_policies<Real> > real;
 
   qi::symbols<char, ElementType> abaqus_element_type;
 
   /* ------------------------------------------------------------------------ */
   /* Mambers                                                                  */
   /* ------------------------------------------------------------------------ */
 private:
   /// reference to the mesh to read
   Mesh & mesh;
 
   /// correspondance between the numbering of nodes in the abaqus file and in
   /// the akantu mesh
   std::map<UInt, UInt> abaqus_nodes_to_akantu;
 
   /// correspondance between the element number in the abaqus file and the
   /// Element in the akantu mesh
   std::map<UInt, Element> abaqus_elements_to_akantu;
 
   /// list of the material names
   std::vector<std::string> material_names;
 };
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 void MeshIOAbaqus::read(const std::string & filename, Mesh & mesh) {
   namespace spirit = boost::spirit;
   namespace qi = boost::spirit::qi;
   namespace lbs = boost::spirit::qi::labels;
   namespace ascii = boost::spirit::ascii;
   namespace phx = boost::phoenix;
 
   std::ifstream infile;
   infile.open(filename.c_str());
 
   if (!infile.good()) {
     AKANTU_DEBUG_ERROR("Cannot open file " << filename);
   }
 
   std::string storage;             // We will read the contents here.
   infile.unsetf(std::ios::skipws); // No white space skipping!
   std::copy(std::istream_iterator<char>(infile), std::istream_iterator<char>(),
             std::back_inserter(storage));
 
   typedef std::string::const_iterator iterator_t;
   typedef AbaqusSkipper<iterator_t> skipper;
   typedef AbaqusMeshGrammar<iterator_t, skipper> grammar;
 
   grammar g(mesh);
   skipper ws;
 
   iterator_t iter = storage.begin();
   iterator_t end = storage.end();
 
   qi::phrase_parse(iter, end, g, ws);
 
-  std::vector<std::string>::const_iterator mnit = g.getMaterialNames().begin();
-  std::vector<std::string>::const_iterator mnend = g.getMaterialNames().end();
-
   MeshAccessor mesh_accessor(mesh);
 
-  for (; mnit != mnend; ++mnit) {
-    Mesh::element_group_iterator eg_it = mesh.element_group_find(*mnit);
-    ElementGroup & eg = *eg_it->second;
+  for (auto & mat_name : g.getMaterialNames()) {
+    auto eg_it = mesh.element_group_find(mat_name);
+    auto & eg = *eg_it->second;
     if (eg_it != mesh.element_group_end()) {
-      ElementGroup::type_iterator tit = eg.firstType();
-      ElementGroup::type_iterator tend = eg.lastType();
-
-      for (; tit != tend; ++tit) {
+      for (auto & type : eg.elementTypes()) {
         Array<std::string> & abaqus_material =
-            mesh_accessor.getData<std::string>("abaqus_material", *tit);
+            mesh_accessor.getData<std::string>("abaqus_material", type);
 
-        ElementGroup::const_element_iterator eit = eg.element_begin(*tit);
-        ElementGroup::const_element_iterator eend = eg.element_end(*tit);
-        for (; eit != eend; ++eit) {
-          abaqus_material(*eit) = *mnit;
+        for (auto elem : eg.getElements(type)) {
+          abaqus_material(elem) = mat_name;
         }
       }
     }
   }
 
   mesh_accessor.setNbGlobalNodes(mesh.getNodes().getSize());
   MeshUtils::fillElementToSubElementsData(mesh);
 }
 
 } // akantu
diff --git a/src/io/mesh_io/mesh_io_diana.cc b/src/io/mesh_io/mesh_io_diana.cc
index 2014b6b92..b75e511fd 100644
--- a/src/io/mesh_io/mesh_io_diana.cc
+++ b/src/io/mesh_io/mesh_io_diana.cc
@@ -1,587 +1,604 @@
 /**
  * @file   mesh_io_diana.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Alodie Schneuwly <alodie.schneuwly@epfl.ch>
  *
  * @date creation: Sat Mar 26 2011
  * @date last modification: Thu Jan 21 2016
  *
  * @brief  handles diana meshes
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 #include <iostream>
 
 /* -------------------------------------------------------------------------- */
+#include "element_group.hh"
 #include "mesh_io_diana.hh"
 #include "mesh_utils.hh"
-#include "element_group.hh"
 /* -------------------------------------------------------------------------- */
 #include <string.h>
 /* -------------------------------------------------------------------------- */
 #include <stdio.h>
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /*   Methods Implentations                                                    */
 /* -------------------------------------------------------------------------- */
 
 MeshIODiana::MeshIODiana() {
   canReadSurface = true;
   canReadExtendedData = true;
   _diana_to_akantu_element_types["T9TM"] = _triangle_3;
   _diana_to_akantu_element_types["CT6CM"] = _triangle_6;
   _diana_to_akantu_element_types["Q12TM"] = _quadrangle_4;
   _diana_to_akantu_element_types["CQ8CM"] = _quadrangle_8;
   _diana_to_akantu_element_types["TP18L"] = _pentahedron_6;
   _diana_to_akantu_element_types["CTP45"] = _pentahedron_15;
   _diana_to_akantu_element_types["TE12L"] = _tetrahedron_4;
   _diana_to_akantu_element_types["HX24L"] = _hexahedron_8;
   _diana_to_akantu_element_types["CHX60"] = _hexahedron_20;
   _diana_to_akantu_mat_prop["YOUNG"] = "E";
   _diana_to_akantu_mat_prop["DENSIT"] = "rho";
   _diana_to_akantu_mat_prop["POISON"] = "nu";
 
   std::map<std::string, ElementType>::iterator it;
   for (it = _diana_to_akantu_element_types.begin();
        it != _diana_to_akantu_element_types.end(); ++it) {
     UInt nb_nodes = Mesh::getNbNodesPerElement(it->second);
 
     UInt * tmp = new UInt[nb_nodes];
     for (UInt i = 0; i < nb_nodes; ++i) {
       tmp[i] = i;
     }
 
     switch (it->second) {
     case _tetrahedron_10:
       tmp[8] = 9;
       tmp[9] = 8;
       break;
     case _pentahedron_15:
       tmp[0] = 2;
       tmp[1] = 8;
       tmp[2] = 0;
       tmp[3] = 6;
       tmp[4] = 1;
       tmp[5] = 7;
       tmp[6] = 11;
       tmp[7] = 9;
       tmp[8] = 10;
       tmp[9] = 5;
       tmp[10] = 14;
       tmp[11] = 3;
       tmp[12] = 12;
       tmp[13] = 4;
       tmp[14] = 13;
       break;
     case _hexahedron_20:
       tmp[0] = 5;
       tmp[1] = 16;
       tmp[2] = 4;
       tmp[3] = 19;
       tmp[4] = 7;
       tmp[5] = 18;
       tmp[6] = 6;
       tmp[7] = 17;
       tmp[8] = 13;
       tmp[9] = 12;
       tmp[10] = 15;
       tmp[11] = 14;
       tmp[12] = 1;
       tmp[13] = 8;
       tmp[14] = 0;
       tmp[15] = 11;
       tmp[16] = 3;
       tmp[17] = 10;
       tmp[18] = 2;
       tmp[19] = 9;
       break;
     default:
       // nothing to change
       break;
     }
     _read_order[it->second] = tmp;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 MeshIODiana::~MeshIODiana() {}
 
 /* -------------------------------------------------------------------------- */
 inline void my_getline(std::ifstream & infile, std::string & line) {
   std::getline(infile, line);   // read the line
   size_t pos = line.find("\r"); /// remove the extra \r if needed
   line = line.substr(0, pos);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIODiana::read(const std::string & filename, Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   MeshAccessor mesh_accessor(mesh);
 
   std::ifstream infile;
   infile.open(filename.c_str());
 
   std::string line;
   UInt first_node_number = std::numeric_limits<UInt>::max();
   diana_element_number_to_elements.clear();
 
-  if (!infile.good()) { AKANTU_DEBUG_ERROR("Cannot open file " << filename); }
+  if (!infile.good()) {
+    AKANTU_DEBUG_ERROR("Cannot open file " << filename);
+  }
 
   while (infile.good()) {
     my_getline(infile, line);
 
     /// read all nodes
     if (line == "'COORDINATES'") {
       line = readCoordinates(infile, mesh, first_node_number);
     }
 
     /// read all elements
     if (line == "'ELEMENTS'") {
       line = readElements(infile, mesh, first_node_number);
     }
 
     /// read the material properties and write a .dat file
-    if (line == "'MATERIALS'") { line = readMaterial(infile, filename); }
+    if (line == "'MATERIALS'") {
+      line = readMaterial(infile, filename);
+    }
 
     /// read the material properties and write a .dat file
     if (line == "'GROUPS'") {
       line = readGroups(infile, mesh, first_node_number);
     }
   }
   infile.close();
 
   mesh_accessor.setNbGlobalNodes(mesh.getNbNodes());
 
   MeshUtils::fillElementToSubElementsData(mesh);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIODiana::write(__attribute__((unused)) const std::string & filename,
                         __attribute__((unused)) const Mesh & mesh) {
   AKANTU_DEBUG_TO_IMPLEMENT();
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readCoordinates(std::ifstream & infile, Mesh & mesh,
                                          UInt & first_node_number) {
   AKANTU_DEBUG_IN();
 
   MeshAccessor mesh_accessor(mesh);
 
   Array<Real> & nodes = mesh_accessor.getNodes();
 
   std::string line;
 
   UInt index;
   Vector<Real> coord(3);
 
   do {
     my_getline(infile, line);
-    if ("'ELEMENTS'" == line) break;
+    if ("'ELEMENTS'" == line)
+      break;
 
     std::stringstream sstr_node(line);
     sstr_node >> index >> coord(0) >> coord(1) >> coord(2);
 
     first_node_number = first_node_number < index ? first_node_number : index;
 
     nodes.push_back(coord);
   } while (true);
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 UInt MeshIODiana::readInterval(std::stringstream & line,
                                std::set<UInt> & interval) {
   UInt first;
   line >> first;
-  if (line.fail()) { return 0; }
+  if (line.fail()) {
+    return 0;
+  }
   interval.insert(first);
 
   UInt second;
   int dash;
   dash = line.get();
   if (dash == '-') {
     line >> second;
     interval.insert(second);
     return 2;
   }
 
   if (line.fail())
     line.clear(std::ios::eofbit); // in case of get at end of the line
   else
     line.unget();
   return 1;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readGroups(std::ifstream & infile, Mesh & mesh,
                                     UInt first_node_number) {
   AKANTU_DEBUG_IN();
 
   std::string line;
   my_getline(infile, line);
 
   bool reading_nodes_group = false;
 
   while (line != "'SUPPORTS'") {
     if (line == "NODES") {
       reading_nodes_group = true;
       my_getline(infile, line);
     }
 
     if (line == "ELEMEN") {
       reading_nodes_group = false;
       my_getline(infile, line);
     }
 
     std::stringstream * str = new std::stringstream(line);
 
     UInt id;
     std::string name;
     char c;
     *str >> id >> name >> c;
 
     Array<UInt> * list_ids = new Array<UInt>(0, 1, name);
 
     UInt s = 1;
     bool end = false;
     while (!end) {
       while (!str->eof() && s != 0) {
         std::set<UInt> interval;
         s = readInterval(*str, interval);
         std::set<UInt>::iterator it = interval.begin();
-        if (s == 1) list_ids->push_back(*it);
+        if (s == 1)
+          list_ids->push_back(*it);
         if (s == 2) {
           UInt first = *it;
           ++it;
           UInt second = *it;
           for (UInt i = first; i <= second; ++i) {
             list_ids->push_back(i);
           }
         }
       }
       if (str->fail())
         end = true;
       else {
         my_getline(infile, line);
         delete str;
         str = new std::stringstream(line);
       }
     }
 
     delete str;
 
     if (reading_nodes_group) {
       NodeGroup & ng = mesh.createNodeGroup(name);
       for (UInt i = 0; i < list_ids->getSize(); ++i) {
-        UInt node = (*list_ids)(i) - first_node_number;
+        UInt node = (*list_ids)(i)-first_node_number;
         ng.add(node, false);
       }
       delete list_ids;
 
     } else {
       ElementGroup & eg = mesh.createElementGroup(name);
       for (UInt i = 0; i < list_ids->getSize(); ++i) {
-        Element & elem = diana_element_number_to_elements[ (*list_ids)(i)];
-        if (elem.type != _not_defined) eg.add(elem, false, false);
+        Element & elem = diana_element_number_to_elements[(*list_ids)(i)];
+        if (elem.type != _not_defined)
+          eg.add(elem, false, false);
       }
 
       eg.optimize();
       delete list_ids;
     }
 
     my_getline(infile, line);
   }
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readElements(std::ifstream & infile, Mesh & mesh,
                                       UInt first_node_number) {
   AKANTU_DEBUG_IN();
 
   std::string line;
   my_getline(infile, line);
 
   if ("CONNECTIVITY" == line) {
     line = readConnectivity(infile, mesh, first_node_number);
   }
 
   /// read the line corresponding to the materials
-  if ("MATERIALS" == line) { line = readMaterialElement(infile, mesh); }
+  if ("MATERIALS" == line) {
+    line = readMaterialElement(infile, mesh);
+  }
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readConnectivity(std::ifstream & infile, Mesh & mesh,
                                           UInt first_node_number) {
   AKANTU_DEBUG_IN();
 
   MeshAccessor mesh_accessor(mesh);
   Int index;
   std::string lline;
 
   std::string diana_type;
   ElementType akantu_type, akantu_type_old = _not_defined;
   Array<UInt> * connectivity = NULL;
   UInt node_per_element = 0;
   Element elem;
   UInt * read_order = NULL;
 
   while (1) {
     my_getline(infile, lline);
     //    std::cerr << lline << std::endl;
     std::stringstream sstr_elem(lline);
-    if (lline == "MATERIALS") break;
+    if (lline == "MATERIALS")
+      break;
 
     /// traiter les coordonnees
     sstr_elem >> index;
     sstr_elem >> diana_type;
 
     akantu_type = _diana_to_akantu_element_types[diana_type];
 
-    if (akantu_type == _not_defined) continue;
+    if (akantu_type == _not_defined)
+      continue;
 
     if (akantu_type != akantu_type_old) {
       connectivity = &(mesh_accessor.getConnectivity(akantu_type));
 
       node_per_element = connectivity->getNbComponent();
       akantu_type_old = akantu_type;
       read_order = _read_order[akantu_type];
     }
 
     Vector<UInt> local_connect(node_per_element);
 
     // used if element is written on two lines
     UInt j_last = 0;
 
     for (UInt j = 0; j < node_per_element; ++j) {
       UInt node_index;
       sstr_elem >> node_index;
 
       // check s'il y a pas plus rien après un certain point
 
       if (sstr_elem.fail()) {
         sstr_elem.clear();
         sstr_elem.ignore();
         break;
       }
 
       node_index -= first_node_number;
       local_connect(read_order[j]) = node_index;
       j_last = j;
     }
 
     // check if element is written in two lines
     if (j_last != (node_per_element - 1)) {
 
       // if this is the case, read on more line
       my_getline(infile, lline);
       std::stringstream sstr_elem(lline);
 
       for (UInt j = (j_last + 1); j < node_per_element; ++j) {
 
         UInt node_index;
         sstr_elem >> node_index;
 
         node_index -= first_node_number;
         local_connect(read_order[j]) = node_index;
       }
     }
 
     connectivity->push_back(local_connect);
 
     elem.type = akantu_type;
     elem.element = connectivity->getSize() - 1;
 
     diana_element_number_to_elements[index] = elem;
     akantu_number_to_diana_number[elem] = index;
   }
 
   AKANTU_DEBUG_OUT();
   return lline;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readMaterialElement(std::ifstream & infile,
                                              Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   std::string line;
   std::stringstream sstr_tag_name;
   sstr_tag_name << "tag_" << 0;
 
   Mesh::type_iterator it = mesh.firstType();
   Mesh::type_iterator end = mesh.lastType();
   for (; it != end; ++it) {
     UInt nb_element = mesh.getNbElement(*it);
     mesh.getDataPointer<UInt>("material", *it, _not_ghost, 1)
-        ->resize(nb_element);
+        .resize(nb_element);
   }
 
   my_getline(infile, line);
   while (line != "'MATERIALS'") {
     line =
         line.substr(line.find('/') + 1,
                     std::string::npos); // erase the first slash / of the line
     char tutu[250];
     strcpy(tutu, line.c_str());
 
     AKANTU_DEBUG_WARNING("reading line " << line);
     Array<UInt> temp_id(0, 2);
     UInt mat;
     while (true) {
       std::stringstream sstr_intervals_elements(line);
       Vector<UInt> id(2);
       char temp;
       while (sstr_intervals_elements.good()) {
         sstr_intervals_elements >> id(0) >> temp >> id(1); // >> "/" >> mat;
-        if (!sstr_intervals_elements.fail()) temp_id.push_back(id);
+        if (!sstr_intervals_elements.fail())
+          temp_id.push_back(id);
       }
       if (sstr_intervals_elements.fail()) {
         sstr_intervals_elements.clear();
         sstr_intervals_elements.ignore();
         sstr_intervals_elements >> mat;
         break;
       }
       my_getline(infile, line);
     }
 
     // loop over elements
     //    UInt * temp_id_val = temp_id.storage();
     for (UInt i = 0; i < temp_id.getSize(); ++i)
       for (UInt j = temp_id(i, 0); j <= temp_id(i, 1); ++j) {
         Element & element = diana_element_number_to_elements[j];
-        if (element.type == _not_defined) continue;
+        if (element.type == _not_defined)
+          continue;
         UInt elem = element.element;
         ElementType type = element.type;
         Array<UInt> & data =
-            *(mesh.getDataPointer<UInt>("material", type, _not_ghost));
+            mesh.getDataPointer<UInt>("material", type, _not_ghost);
         data(elem) = mat;
       }
 
     my_getline(infile, line);
   }
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 std::string MeshIODiana::readMaterial(std::ifstream & infile,
                                       const std::string & filename) {
   AKANTU_DEBUG_IN();
 
   std::stringstream mat_file_name;
 
   mat_file_name << "material_" << filename;
 
   std::ofstream material_file;
   material_file.open(mat_file_name.str().c_str()); // mat_file_name.str());
 
   UInt mat_index;
   std::string line;
 
   bool first_mat = true;
   bool end = false;
 
   UInt mat_id = 0;
 
   typedef std::map<std::string, Real> MatProp;
   MatProp mat_prop;
   do {
     my_getline(infile, line);
     std::stringstream sstr_material(line);
     if (("'GROUPS'" == line) || ("'END'" == line)) {
       if (!mat_prop.empty()) {
         material_file << "material elastic [" << std::endl;
         material_file << "\tname = material" << ++mat_id << std::endl;
         for (MatProp::iterator it = mat_prop.begin(); it != mat_prop.end();
              ++it)
           material_file << "\t" << it->first << " = " << it->second
                         << std::endl;
         material_file << "]" << std::endl;
         mat_prop.clear();
       }
       end = true;
     } else {
       /// traiter les caractéristiques des matériaux
       sstr_material >> mat_index;
 
       if (!sstr_material.fail()) {
         if (!first_mat) {
           if (!mat_prop.empty()) {
             material_file << "material elastic [" << std::endl;
             material_file << "\tname = material" << ++mat_id << std::endl;
             for (MatProp::iterator it = mat_prop.begin(); it != mat_prop.end();
                  ++it)
               material_file << "\t" << it->first << " = " << it->second
                             << std::endl;
             material_file << "]" << std::endl;
             mat_prop.clear();
           }
         }
         first_mat = false;
-      } else { sstr_material.clear(); }
+      } else {
+        sstr_material.clear();
+      }
 
       std::string prop_name;
       sstr_material >> prop_name;
 
       std::map<std::string, std::string>::iterator it;
       it = _diana_to_akantu_mat_prop.find(prop_name);
 
       if (it != _diana_to_akantu_mat_prop.end()) {
         Real value;
         sstr_material >> value;
         mat_prop[it->second] = value;
       } else {
         AKANTU_DEBUG_INFO("In material reader, property " << prop_name
                                                           << "not recognized");
       }
     }
   } while (!end);
 
   AKANTU_DEBUG_OUT();
   return line;
 }
 
 /* -------------------------------------------------------------------------- */
 
-} // akantu
+} // namespace akantu
diff --git a/src/io/mesh_io/mesh_io_msh.cc b/src/io/mesh_io/mesh_io_msh.cc
index 44990b5b2..a2efe333e 100644
--- a/src/io/mesh_io/mesh_io_msh.cc
+++ b/src/io/mesh_io/mesh_io_msh.cc
@@ -1,981 +1,981 @@
 /**
  * @file   mesh_io_msh.cc
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Jan 21 2016
  *
  * @brief  Read/Write for MSH files generated by gmsh
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -----------------------------------------------------------------------------
    Version (Legacy) 1.0
 
    $NOD
    number-of-nodes
    node-number x-coord y-coord z-coord
    ...
    $ENDNOD
    $ELM
    number-of-elements
    elm-number elm-type reg-phys reg-elem number-of-nodes node-number-list
    ...
    $ENDELM
    -----------------------------------------------------------------------------
    Version 2.1
 
    $MeshFormat
    version-number file-type data-size
    $EndMeshFormat
    $Nodes
    number-of-nodes
    node-number x-coord y-coord z-coord
    ...
    $EndNodes
    $Elements
    number-of-elements
    elm-number elm-type number-of-tags < tag > ... node-number-list
    ...
    $EndElements
    $PhysicalNames
    number-of-names
    physical-dimension physical-number "physical-name"
    ...
    $EndPhysicalNames
    $NodeData
    number-of-string-tags
    < "string-tag" >
    ...
    number-of-real-tags
    < real-tag >
    ...
    number-of-integer-tags
    < integer-tag >
    ...
    node-number value ...
    ...
    $EndNodeData
    $ElementData
    number-of-string-tags
    < "string-tag" >
    ...
    number-of-real-tags
    < real-tag >
    ...
    number-of-integer-tags
    < integer-tag >
    ...
    elm-number value ...
    ...
    $EndElementData
    $ElementNodeData
    number-of-string-tags
    < "string-tag" >
    ...
    number-of-real-tags
    < real-tag >
    ...
    number-of-integer-tags
    < integer-tag >
    ...
    elm-number number-of-nodes-per-element value ...
    ...
    $ElementEndNodeData
 
    -----------------------------------------------------------------------------
    elem-type
 
    1:  2-node line.
    2:  3-node triangle.
    3:  4-node quadrangle.
    4:  4-node tetrahedron.
    5:  8-node hexahedron.
    6:  6-node prism.
    7:  5-node pyramid.
    8:  3-node second order line
    9:  6-node second order triangle
    10: 9-node second order quadrangle
    11: 10-node second order tetrahedron
    12: 27-node second order hexahedron
    13: 18-node second order prism
    14: 14-node second order pyramid
    15: 1-node point.
    16: 8-node second order quadrangle
    17: 20-node second order hexahedron
    18: 15-node second order prism
    19: 13-node second order pyramid
    20: 9-node third order incomplete triangle
    21: 10-node third order triangle
    22: 12-node fourth order incomplete triangle
    23: 15-node fourth order triangle
    24: 15-node fifth order incomplete triangle
    25: 21-node fifth order complete triangle
    26: 4-node third order edge
    27: 5-node fourth order edge
    28: 6-node fifth order edge
    29: 20-node third order tetrahedron
    30: 35-node fourth order tetrahedron
    31: 56-node fifth order tetrahedron
    -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "mesh_io.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 // The boost spirit is a work on the way it does not compile so I kept the
 // current code. The current code does not handle files generated on Windows
 // <CRLF>
 
 // #include <boost/config/warning_disable.hpp>
 // #include <boost/spirit/include/qi.hpp>
 // #include <boost/spirit/include/phoenix_core.hpp>
 // #include <boost/spirit/include/phoenix_fusion.hpp>
 // #include <boost/spirit/include/phoenix_object.hpp>
 // #include <boost/spirit/include/phoenix_container.hpp>
 // #include <boost/spirit/include/phoenix_operator.hpp>
 // #include <boost/spirit/include/phoenix_bind.hpp>
 // #include <boost/spirit/include/phoenix_stl.hpp>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /*   Methods Implentations                                                    */
 /* -------------------------------------------------------------------------- */
 MeshIOMSH::MeshIOMSH() {
   canReadSurface = true;
   canReadExtendedData = true;
 
   _msh_nodes_per_elem[_msh_not_defined] = 0;
   _msh_nodes_per_elem[_msh_segment_2] = 2;
   _msh_nodes_per_elem[_msh_triangle_3] = 3;
   _msh_nodes_per_elem[_msh_quadrangle_4] = 4;
   _msh_nodes_per_elem[_msh_tetrahedron_4] = 4;
   _msh_nodes_per_elem[_msh_hexahedron_8] = 8;
   _msh_nodes_per_elem[_msh_prism_1] = 6;
   _msh_nodes_per_elem[_msh_pyramid_1] = 1;
   _msh_nodes_per_elem[_msh_segment_3] = 3;
   _msh_nodes_per_elem[_msh_triangle_6] = 6;
   _msh_nodes_per_elem[_msh_quadrangle_9] = 9;
   _msh_nodes_per_elem[_msh_tetrahedron_10] = 10;
   _msh_nodes_per_elem[_msh_hexahedron_27] = 27;
   _msh_nodes_per_elem[_msh_hexahedron_20] = 20;
   _msh_nodes_per_elem[_msh_prism_18] = 18;
   _msh_nodes_per_elem[_msh_prism_15] = 15;
   _msh_nodes_per_elem[_msh_pyramid_14] = 14;
   _msh_nodes_per_elem[_msh_point] = 1;
   _msh_nodes_per_elem[_msh_quadrangle_8] = 8;
 
   _msh_to_akantu_element_types[_msh_not_defined] = _not_defined;
   _msh_to_akantu_element_types[_msh_segment_2] = _segment_2;
   _msh_to_akantu_element_types[_msh_triangle_3] = _triangle_3;
   _msh_to_akantu_element_types[_msh_quadrangle_4] = _quadrangle_4;
   _msh_to_akantu_element_types[_msh_tetrahedron_4] = _tetrahedron_4;
   _msh_to_akantu_element_types[_msh_hexahedron_8] = _hexahedron_8;
   _msh_to_akantu_element_types[_msh_prism_1] = _pentahedron_6;
   _msh_to_akantu_element_types[_msh_pyramid_1] = _not_defined;
   _msh_to_akantu_element_types[_msh_segment_3] = _segment_3;
   _msh_to_akantu_element_types[_msh_triangle_6] = _triangle_6;
   _msh_to_akantu_element_types[_msh_quadrangle_9] = _not_defined;
   _msh_to_akantu_element_types[_msh_tetrahedron_10] = _tetrahedron_10;
   _msh_to_akantu_element_types[_msh_hexahedron_27] = _not_defined;
   _msh_to_akantu_element_types[_msh_hexahedron_20] = _hexahedron_20;
   _msh_to_akantu_element_types[_msh_prism_18] = _not_defined;
   _msh_to_akantu_element_types[_msh_prism_15] = _pentahedron_15;
   _msh_to_akantu_element_types[_msh_pyramid_14] = _not_defined;
   _msh_to_akantu_element_types[_msh_point] = _point_1;
   _msh_to_akantu_element_types[_msh_quadrangle_8] = _quadrangle_8;
 
   _akantu_to_msh_element_types[_not_defined] = _msh_not_defined;
   _akantu_to_msh_element_types[_segment_2] = _msh_segment_2;
   _akantu_to_msh_element_types[_segment_3] = _msh_segment_3;
   _akantu_to_msh_element_types[_triangle_3] = _msh_triangle_3;
   _akantu_to_msh_element_types[_triangle_6] = _msh_triangle_6;
   _akantu_to_msh_element_types[_tetrahedron_4] = _msh_tetrahedron_4;
   _akantu_to_msh_element_types[_tetrahedron_10] = _msh_tetrahedron_10;
   _akantu_to_msh_element_types[_quadrangle_4] = _msh_quadrangle_4;
   _akantu_to_msh_element_types[_quadrangle_8] = _msh_quadrangle_8;
   _akantu_to_msh_element_types[_hexahedron_8] = _msh_hexahedron_8;
   _akantu_to_msh_element_types[_hexahedron_20] = _msh_hexahedron_20;
   _akantu_to_msh_element_types[_pentahedron_6] = _msh_prism_1;
   _akantu_to_msh_element_types[_pentahedron_15] = _msh_prism_15;
   _akantu_to_msh_element_types[_point_1] = _msh_point;
 
 #if defined(AKANTU_STRUCTURAL_MECHANICS)
   _akantu_to_msh_element_types[_bernoulli_beam_2] = _msh_segment_2;
   _akantu_to_msh_element_types[_bernoulli_beam_3] = _msh_segment_2;
   _akantu_to_msh_element_types[_kirchhoff_shell] = _msh_triangle_3;
 #endif
 
   std::map<ElementType, MSHElementType>::iterator it;
   for (it = _akantu_to_msh_element_types.begin();
        it != _akantu_to_msh_element_types.end(); ++it) {
     UInt nb_nodes = _msh_nodes_per_elem[it->second];
 
     std::vector<UInt> tmp(nb_nodes);
     for (UInt i = 0; i < nb_nodes; ++i) {
       tmp[i] = i;
     }
 
     switch (it->first) {
     case _tetrahedron_10:
       tmp[8] = 9;
       tmp[9] = 8;
       break;
     case _pentahedron_6:
       tmp[0] = 2;
       tmp[1] = 0;
       tmp[2] = 1;
       tmp[3] = 5;
       tmp[4] = 3;
       tmp[5] = 4;
       break;
     case _pentahedron_15:
       tmp[0] = 2;
       tmp[1] = 0;
       tmp[2] = 1;
       tmp[3] = 5;
       tmp[4] = 3;
       tmp[5] = 4;
       tmp[6] = 8;
       tmp[8] = 11;
       tmp[9] = 6;
       tmp[10] = 9;
       tmp[11] = 10;
       tmp[12] = 14;
       tmp[14] = 12;
       break;
     case _hexahedron_20:
       tmp[9] = 11;
       tmp[10] = 12;
       tmp[11] = 9;
       tmp[12] = 13;
       tmp[13] = 10;
       tmp[17] = 19;
       tmp[18] = 17;
       tmp[19] = 18;
       break;
     default:
       // nothing to change
       break;
     }
     _read_order[it->first] = tmp;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 MeshIOMSH::~MeshIOMSH() {}
 
 /* -------------------------------------------------------------------------- */
 /* Spirit stuff                                                               */
 /* -------------------------------------------------------------------------- */
 // namespace _parser {
 //   namespace spirit  = ::boost::spirit;
 //   namespace qi      = ::boost::spirit::qi;
 //   namespace ascii   = ::boost::spirit::ascii;
 //   namespace lbs     = ::boost::spirit::qi::labels;
 //   namespace phx     = ::boost::phoenix;
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   /* Lazy functors */
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct _Element {
 //     int index;
 //     std::vector<int> tags;
 //     std::vector<int> connectivity;
 //     ElementType type;
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_get_nb_nodes_ {
 //     template <class elem_type> struct result { typedef int type; };
 //     template <class elem_type> bool operator()(elem_type et) {
 //       return MeshIOMSH::_msh_nodes_per_elem[et];
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_element_ {
 //     template <class id_t, class tags_t, class elem_type, class conn_t>
 //     struct result {
 //       typedef _Element type;
 //     };
 //     template <class id_t, class tags_t, class elem_type, class conn_t>
 //     _Element operator()(id_t id, const elem_type & et, const tags_t & t,
 //                        const conn_t & c) {
 //       _Element tmp_el;
 //       tmp_el.index = id;
 //       tmp_el.tags = t;
 //       tmp_el.connectivity = c;
 //       tmp_el.type = et;
 //       return tmp_el;
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_check_value_ {
 //     template <class T> struct result { typedef void type; };
 //     template <class T> void operator()(T v1, T v2) {
 //       if (v1 != v2) {
 //         AKANTU_EXCEPTION("The msh parser expected a "
 //                          << v2 << " in the header bug got a " << v1);
 //       }
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_node_read_ {
 //     template <class Mesh, class ID, class V, class size, class Map>
 //     struct result {
 //       typedef bool type;
 //     };
 //     template <class Mesh, class ID, class V, class size, class Map>
 //     bool operator()(Mesh & mesh, const ID & id, const V & pos, size max,
 //                     Map & nodes_mapping) const {
 //       Vector<Real> tmp_pos(mesh.getSpatialDimension());
 //       UInt i = 0;
 //       for (typename V::const_iterator it = pos.begin();
 //            it != pos.end() || i < mesh.getSpatialDimension(); ++it)
 //         tmp_pos[i++] = *it;
 
 //       nodes_mapping[id] = mesh.getNbNodes();
 //       mesh.getNodes().push_back(tmp_pos);
 //       return (mesh.getNbNodes() < UInt(max));
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   struct lazy_element_read_ {
 //     template <class Mesh, class EL, class size, class NodeMap, class ElemMap>
 //     struct result {
 //       typedef bool type;
 //     };
 
 //     template <class Mesh, class EL, class size, class NodeMap, class ElemMap>
 //     bool operator()(Mesh & mesh, const EL & element, size max,
 //                     const NodeMap & nodes_mapping,
 //                     ElemMap & elements_mapping) const {
 //       Vector<UInt> tmp_conn(Mesh::getNbNodesPerElement(element.type));
 
 //       AKANTU_DEBUG_ASSERT(element.connectivity.size() == tmp_conn.size(),
 //                           "The element "
 //                               << element.index
 //                               << "in the MSH file has too many nodes.");
 
 //       mesh.addConnectivityType(element.type);
 //       Array<UInt> & connectivity = mesh.getConnectivity(element.type);
 
 //       UInt i = 0;
 //       for (std::vector<int>::const_iterator it =
 //       element.connectivity.begin();
 //            it != element.connectivity.end(); ++it) {
 //         typename NodeMap::const_iterator nit = nodes_mapping.find(*it);
 //         AKANTU_DEBUG_ASSERT(nit != nodes_mapping.end(),
 //                             "There is an unknown node in the connectivity.");
 //         tmp_conn[i++] = nit->second;
 //       }
 
 //       ::akantu::Element el(element.type, connectivity.getSize());
 //       elements_mapping[element.index] = el;
 
 //       connectivity.push_back(tmp_conn);
 
 //       for (UInt i = 0; i < element.tags.size(); ++i) {
 //         std::stringstream tag_sstr;
 //         tag_sstr << "tag_" << i;
 //         Array<UInt> * data =
 //             mesh.template getDataPointer<UInt>(tag_sstr.str(), element.type,
 //             _not_ghost);
 //         data->push_back(element.tags[i]);
 //       }
 
 //       return (mesh.getNbElement() < UInt(max));
 //     }
 //   };
 
 //   /* ------------------------------------------------------------------------
 //   */
 //   template <class Iterator, typename Skipper = ascii::space_type>
 //   struct MshMeshGrammar : qi::grammar<Iterator, void(), Skipper> {
 //   public:
 //     MshMeshGrammar(Mesh & mesh)
 //         : MshMeshGrammar::base_type(start, "msh_mesh_reader"), mesh(mesh) {
 //       phx::function<lazy_element_> lazy_element;
 //       phx::function<lazy_get_nb_nodes_> lazy_get_nb_nodes;
 //       phx::function<lazy_check_value_> lazy_check_value;
 //       phx::function<lazy_node_read_> lazy_node_read;
 //       phx::function<lazy_element_read_> lazy_element_read;
 
 // clang-format off
 
 //       start
 //         =  *( known_section | unknown_section
 //             )
 //        ;
 
 //       known_section
 //         =  qi::char_("$")
 //            >> sections            [ lbs::_a = lbs::_1 ]
 //            >> qi::lazy(*lbs::_a)
 //            >> qi::lit("$End")
 //           //>> qi::lit(phx::ref(lbs::_a))
 //         ;
 
 //       unknown_section
 //         =  qi::char_("$")
 //            >> qi::char_("")     [ lbs::_a = lbs::_1 ]
 //            >> ignore_section
 //            >> qi::lit("$End")
 //            >> qi::lit(phx::val(lbs::_a))
 //         ;
 
 //       mesh_format // version followed by 0 or 1 for ascii or binary
 //         =  version >> (
 //                         ( qi::char_("0")
 //                           >> qi::int_       [ lazy_check_value(lbs::_1, 8) ]
 //                         )
 //                         | ( qi::char_("1")
 //                             >> qi::int_     [ lazy_check_value(lbs::_1, 8) ]
 //                             >> qi::dword    [ lazy_check_value(lbs::_1, 1) ]
 //                           )
 //                         )
 //         ;
 
 //       nodes
 //         =  nodes_
 //         ;
 
 //       nodes_
 //         =  qi::int_                      [ lbs::_a = lbs::_1 ]
 //            > *(
 //                 ( qi::int_ >> position ) [ lazy_node_read(phx::ref(mesh),
 //                                                           lbs::_1,
 //                                                           phx::cref(lbs::_2),
 //                                                           lbs::_a,
 //                                                           phx::ref(this->msh_nodes_to_akantu)) ]
 //               )
 //         ;
 
 //       element
 //         =  elements_
 //         ;
 
 //       elements_
 //         =  qi::int_                                 [ lbs::_a = lbs::_1 ]
 //            > qi::repeat(phx::ref(lbs::_a))[ element [ lazy_element_read(phx::ref(mesh),
 //                                                                         lbs::_1,
 //                                                                         phx::cref(lbs::_a),
 //                                                                         phx::cref(this->msh_nodes_to_akantu),
 //                                                                         phx::ref(this->msh_elemt_to_akantu)) ]]
 //         ;
 
 //       ignore_section
 //         =  *(qi::char_ - qi::char_('$'))
 //         ;
 
 //       interpolation_scheme = ignore_section;
 //       element_data         = ignore_section;
 //       node_data            = ignore_section;
 
 //       version
 //         =  qi::int_                         [ phx::push_back(lbs::_val, lbs::_1) ]
 //            >> *( qi::char_(".") >> qi::int_ [ phx::push_back(lbs::_val, lbs::_1) ] )
 //         ;
 
 //       position
 //         =  real   [ phx::push_back(lbs::_val, lbs::_1) ]
 //            > real [ phx::push_back(lbs::_val, lbs::_1) ]
 //            > real [ phx::push_back(lbs::_val, lbs::_1) ]
 //         ;
 
 //       tags
 //         =  qi::int_      [ lbs::_a = lbs::_1 ]
 //           > qi::repeat(phx::val(lbs::_a))[ qi::int_ [ phx::push_back(lbs::_val,
 //                                                                      lbs::_1) ] ]
 //         ;
 
 //       element
 //         =  ( qi::int_                [ lbs::_a = lbs::_1 ]
 //              > msh_element_type      [ lbs::_b = lazy_get_nb_nodes(lbs::_1) ]
 //              > tags                  [ lbs::_c = lbs::_1 ]
 //              > connectivity(lbs::_a) [ lbs::_d = lbs::_1 ]
 //            )                         [ lbs::_val = lazy_element(lbs::_a,
 //                                                                 phx::cref(lbs::_b),
 //                                                                 phx::cref(lbs::_c),
 //                                                                 phx::cref(lbs::_d)) ]
 //         ;
 //       connectivity
 //         =  qi::repeat(lbs::_r1)[ qi::int_ [ phx::push_back(lbs::_val,
 //                                                            lbs::_1) ] ]
 //         ;
 
 //       sections.add
 //           ("MeshFormat", &mesh_format)
 //           ("Nodes", &nodes)
 //           ("Elements", &elements)
 //           ("PhysicalNames", &physical_names)
 //           ("InterpolationScheme", &interpolation_scheme)
 //           ("ElementData", &element_data)
 //           ("NodeData", &node_data);
 
 //       msh_element_type.add
 //           ("0" , _not_defined   )
 //           ("1" , _segment_2     )
 //           ("2" , _triangle_3    )
 //           ("3" , _quadrangle_4  )
 //           ("4" , _tetrahedron_4 )
 //           ("5" , _hexahedron_8  )
 //           ("6" , _pentahedron_6 )
 //           ("7" , _not_defined   )
 //           ("8" , _segment_3     )
 //           ("9" , _triangle_6    )
 //           ("10", _not_defined   )
 //           ("11", _tetrahedron_10)
 //           ("12", _not_defined   )
 //           ("13", _not_defined   )
 //           ("14", _hexahedron_20 )
 //           ("15", _pentahedron_15)
 //           ("16", _not_defined   )
 //           ("17", _point_1       )
 //           ("18", _quadrangle_8  );
 
 //       mesh_format         .name("MeshFormat"         );
 //       nodes               .name("Nodes"              );
 //       elements            .name("Elements"           );
 //       physical_names      .name("PhysicalNames"      );
 //       interpolation_scheme.name("InterpolationScheme");
 //       element_data        .name("ElementData"        );
 //       node_data           .name("NodeData"           );
 
 // clang-format on
 //     }
 
 //     /* ----------------------------------------------------------------------
 //     */
 //     /* Rules */
 //     /* ----------------------------------------------------------------------
 //     */
 //   private:
 //     qi::symbols<char, ElementType> msh_element_type;
 //     qi::symbols<char, qi::rule<Iterator, void(), Skipper> *> sections;
 //     qi::rule<Iterator, void(), Skipper> start;
 //     qi::rule<Iterator, void(), Skipper, qi::locals<std::string> >
 //     unknown_section;
 //     qi::rule<Iterator, void(), Skipper, qi::locals<qi::rule<Iterator,
 //     Skipper> *> > known_section;
 //     qi::rule<Iterator, void(), Skipper> mesh_format, nodes, elements,
 //     physical_names, ignore_section,
 //         interpolation_scheme, element_data, node_data, any_line;
 //     qi::rule<Iterator, void(), Skipper, qi::locals<int> > nodes_;
 //     qi::rule<Iterator, void(), Skipper, qi::locals< int, int, vector<int>,
 //     vector<int> > > elements_;
 
 //     qi::rule<Iterator, std::vector<int>(), Skipper> version;
 //     qi::rule<Iterator, _Element(), Skipper, qi::locals<ElementType> >
 //     element;
 //     qi::rule<Iterator, std::vector<int>(), Skipper, qi::locals<int> > tags;
 //     qi::rule<Iterator, std::vector<int>(int), Skipper> connectivity;
 //     qi::rule<Iterator, std::vector<Real>(), Skipper> position;
 
 //     qi::real_parser<Real, qi::real_policies<Real> > real;
 
 //     /* ----------------------------------------------------------------------
 //     */
 //     /* Members */
 //     /* ----------------------------------------------------------------------
 //     */
 //   private:
 //     /// reference to the mesh to read
 //     Mesh & mesh;
 
 //     /// correspondance between the numbering of nodes in the abaqus file and
 //     in
 //     /// the akantu mesh
 //     std::map<UInt, UInt> msh_nodes_to_akantu;
 
 //     /// correspondance between the element number in the abaqus file and the
 //     /// Element in the akantu mesh
 //     std::map<UInt, Element> msh_elemt_to_akantu;
 //   };
 // }
 
 // /* --------------------------------------------------------------------------
 // */
 // void MeshIOAbaqus::read(const std::string& filename, Mesh& mesh) {
 //   namespace qi      = boost::spirit::qi;
 //   namespace ascii   = boost::spirit::ascii;
 
 //   std::ifstream infile;
 //   infile.open(filename.c_str());
 
 //   if(!infile.good()) {
 //     AKANTU_DEBUG_ERROR("Cannot open file " << filename);
 //   }
 
 //   std::string storage; // We will read the contents here.
 //   infile.unsetf(std::ios::skipws); // No white space skipping!
 //   std::copy(std::istream_iterator<char>(infile),
 //             std::istream_iterator<char>(),
 //             std::back_inserter(storage));
 
 //   typedef std::string::const_iterator iterator_t;
 //   typedef ascii::space_type skipper;
 //   typedef _parser::MshMeshGrammar<iterator_t, skipper> grammar;
 
 //   grammar g(mesh);
 //   skipper ws;
 
 //   iterator_t iter = storage.begin();
 //   iterator_t end  = storage.end();
 
 //   qi::phrase_parse(iter, end, g, ws);
 
 //   this->setNbGlobalNodes(mesh, mesh.getNodes().getSize());
 //   MeshUtils::fillElementToSubElementsData(mesh);
 // }
 
 static void my_getline(std::ifstream & infile, std::string & str) {
   std::string tmp_str;
   std::getline(infile, tmp_str);
   str = trim(tmp_str);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIOMSH::read(const std::string & filename, Mesh & mesh) {
 
   MeshAccessor mesh_accessor(mesh);
 
   std::ifstream infile;
   infile.open(filename.c_str());
 
   std::string line;
   UInt first_node_number = std::numeric_limits<UInt>::max(),
        last_node_number = 0, file_format = 1, current_line = 0;
   bool has_physical_names = false;
 
   if (!infile.good()) {
     AKANTU_DEBUG_ERROR("Cannot open file " << filename);
   }
 
   while (infile.good()) {
     my_getline(infile, line);
     current_line++;
 
     /// read the header
     if (line == "$MeshFormat") {
       my_getline(infile, line); /// the format line
       std::stringstream sstr(line);
       std::string version;
       sstr >> version;
       Int format;
       sstr >> format;
       if (format != 0)
         AKANTU_DEBUG_ERROR("This reader can only read ASCII files.");
       my_getline(infile, line); /// the end of block line
       current_line += 2;
       file_format = 2;
     }
 
     /// read the physical names
     if (line == "$PhysicalNames") {
       has_physical_names = true;
       my_getline(infile, line); /// the format line
       std::stringstream sstr(line);
 
       UInt num_of_phys_names;
       sstr >> num_of_phys_names;
 
       for (UInt k(0); k < num_of_phys_names; k++) {
         my_getline(infile, line);
         std::stringstream sstr_phys_name(line);
         UInt phys_name_id;
         UInt phys_dim;
 
         sstr_phys_name >> phys_dim >> phys_name_id;
 
         std::size_t b = line.find("\"");
         std::size_t e = line.rfind("\"");
         std::string phys_name = line.substr(b + 1, e - b - 1);
 
         phys_name_map[phys_name_id] = phys_name;
       }
     }
 
     /// read all nodes
     if (line == "$Nodes" || line == "$NOD") {
       UInt nb_nodes;
 
       my_getline(infile, line);
       std::stringstream sstr(line);
       sstr >> nb_nodes;
       current_line++;
 
       Array<Real> & nodes = mesh_accessor.getNodes();
       nodes.resize(nb_nodes);
       mesh_accessor.setNbGlobalNodes(nb_nodes);
 
       UInt index;
       Real coord[3];
       UInt spatial_dimension = nodes.getNbComponent();
       /// for each node, read the coordinates
       for (UInt i = 0; i < nb_nodes; ++i) {
         UInt offset = i * spatial_dimension;
 
         my_getline(infile, line);
         std::stringstream sstr_node(line);
         sstr_node >> index >> coord[0] >> coord[1] >> coord[2];
         current_line++;
 
         first_node_number = std::min(first_node_number, index);
         last_node_number = std::max(last_node_number, index);
 
         /// read the coordinates
         for (UInt j = 0; j < spatial_dimension; ++j)
           nodes.storage()[offset + j] = coord[j];
       }
       my_getline(infile, line); /// the end of block line
     }
 
     /// read all elements
     if (line == "$Elements" || line == "$ELM") {
       UInt nb_elements;
 
       std::vector<UInt> read_order;
 
       my_getline(infile, line);
       std::stringstream sstr(line);
       sstr >> nb_elements;
       current_line++;
 
       Int index;
       UInt msh_type;
       ElementType akantu_type, akantu_type_old = _not_defined;
       Array<UInt> * connectivity = NULL;
       UInt node_per_element = 0;
 
       for (UInt i = 0; i < nb_elements; ++i) {
         my_getline(infile, line);
         std::stringstream sstr_elem(line);
         current_line++;
 
         sstr_elem >> index;
         sstr_elem >> msh_type;
 
         /// get the connectivity vector depending on the element type
         akantu_type = this->_msh_to_akantu_element_types[(MSHElementType)msh_type];
 
         if (akantu_type == _not_defined) {
           AKANTU_DEBUG_WARNING("Unsuported element kind "
                                << msh_type << " at line " << current_line);
           continue;
         }
 
         if (akantu_type != akantu_type_old) {
           connectivity = &mesh_accessor.getConnectivity(akantu_type);
           //          connectivity->resize(0);
 
           node_per_element = connectivity->getNbComponent();
           akantu_type_old = akantu_type;
           read_order = this->_read_order[akantu_type];
         }
 
         /// read tags informations
         if (file_format == 2) {
           UInt nb_tags;
           sstr_elem >> nb_tags;
           for (UInt j = 0; j < nb_tags; ++j) {
             Int tag;
             sstr_elem >> tag;
             std::stringstream sstr_tag_name;
             sstr_tag_name << "tag_" << j;
-            Array<UInt> * data = mesh.getDataPointer<UInt>(
+            Array<UInt> & data = mesh.getDataPointer<UInt>(
                 sstr_tag_name.str(), akantu_type, _not_ghost);
-            data->push_back(tag);
+            data.push_back(tag);
           }
         } else if (file_format == 1) {
           Int tag;
           sstr_elem >> tag; // reg-phys
           std::string tag_name = "tag_0";
           Array<UInt> * data =
-              mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
+              &mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
           data->push_back(tag);
 
           sstr_elem >> tag; // reg-elem
           tag_name = "tag_1";
-          data = mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
+          data = &mesh.getDataPointer<UInt>(tag_name, akantu_type, _not_ghost);
           data->push_back(tag);
 
           sstr_elem >> tag; // number-of-nodes
         }
 
         Vector<UInt> local_connect(node_per_element);
         for (UInt j = 0; j < node_per_element; ++j) {
           UInt node_index;
           sstr_elem >> node_index;
 
           AKANTU_DEBUG_ASSERT(node_index <= last_node_number,
                               "Node number not in range : line "
                               << current_line);
 
           node_index -= first_node_number;
           local_connect(read_order[j]) = node_index;
         }
         connectivity->push_back(local_connect);
       }
       my_getline(infile, line); /// the end of block line
     }
 
     if ((line[0] == '$') && (line.find("End") == std::string::npos)) {
       AKANTU_DEBUG_WARNING("Unsuported block_kind " << line << " at line "
                                                     << current_line);
     }
   }
 
-  mesh.updateTypesOffsets(_not_ghost);
+  //mesh.updateTypesOffsets(_not_ghost);
 
   infile.close();
 
   this->constructPhysicalNames("tag_0", mesh);
 
   if (has_physical_names)
     mesh.createGroupsFromMeshData<std::string>("physical_names");
 
   MeshUtils::fillElementToSubElementsData(mesh);
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshIOMSH::write(const std::string & filename, const Mesh & mesh) {
   std::ofstream outfile;
   const Array<Real> & nodes = mesh.getNodes();
 
   outfile.open(filename.c_str());
 
   outfile << "$MeshFormat" << std::endl;
   outfile << "2.1 0 8" << std::endl;
   outfile << "$EndMeshFormat" << std::endl;
 
   outfile << std::setprecision(std::numeric_limits<Real>::digits10);
   outfile << "$Nodes" << std::endl;
 
   outfile << nodes.getSize() << std::endl;
 
   outfile << std::uppercase;
   for (UInt i = 0; i < nodes.getSize(); ++i) {
     Int offset = i * nodes.getNbComponent();
     outfile << i + 1;
     for (UInt j = 0; j < nodes.getNbComponent(); ++j) {
       outfile << " " << nodes.storage()[offset + j];
     }
 
     for (UInt p = nodes.getNbComponent(); p < 3; ++p)
       outfile << " " << 0.;
     outfile << std::endl;
     ;
   }
   outfile << std::nouppercase;
   outfile << "$EndNodes" << std::endl;
   ;
 
   outfile << "$Elements" << std::endl;
   ;
 
   Mesh::type_iterator it =
       mesh.firstType(_all_dimensions, _not_ghost, _ek_not_defined);
   Mesh::type_iterator end =
       mesh.lastType(_all_dimensions, _not_ghost, _ek_not_defined);
 
   Int nb_elements = 0;
   for (; it != end; ++it) {
     const Array<UInt> & connectivity = mesh.getConnectivity(*it, _not_ghost);
     nb_elements += connectivity.getSize();
   }
   outfile << nb_elements << std::endl;
 
   UInt element_idx = 1;
   for (it = mesh.firstType(_all_dimensions, _not_ghost, _ek_not_defined);
        it != end; ++it) {
     ElementType type = *it;
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     UInt * tag[2] = {NULL, NULL};
     try {
       const Array<UInt> & data_tag_0 =
           mesh.getData<UInt>("tag_0", type, _not_ghost);
       tag[0] = data_tag_0.storage();
     } catch (...) {
       tag[0] = NULL;
     }
 
     try {
       const Array<UInt> & data_tag_1 =
           mesh.getData<UInt>("tag_1", type, _not_ghost);
       tag[1] = data_tag_1.storage();
     } catch (...) {
       tag[1] = NULL;
     }
 
     for (UInt i = 0; i < connectivity.getSize(); ++i) {
       UInt offset = i * connectivity.getNbComponent();
       outfile << element_idx << " " << _akantu_to_msh_element_types[type]
               << " 2";
 
       /// \todo write the real data in the file
       for (UInt t = 0; t < 2; ++t)
         if (tag[t])
           outfile << " " << tag[t][i];
         else
           outfile << " 0";
 
       for (UInt j = 0; j < connectivity.getNbComponent(); ++j) {
         outfile << " " << connectivity.storage()[offset + j] + 1;
       }
       outfile << std::endl;
       element_idx++;
     }
   }
 
   outfile << "$EndElements" << std::endl;
   ;
 
   outfile.close();
 }
 
 /* -------------------------------------------------------------------------- */
 
 } // akantu
diff --git a/src/mesh/element_group.hh b/src/mesh/element_group.hh
index be5a6ab5c..181d9c3d6 100644
--- a/src/mesh/element_group.hh
+++ b/src/mesh/element_group.hh
@@ -1,188 +1,187 @@
 /**
  * @file   element_group.hh
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri May 03 2013
  * @date last modification: Tue Aug 18 2015
  *
  * @brief  Stores information relevent to the notion of domain boundary and
  * surfaces.
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_memory.hh"
 #include "dumpable.hh"
 #include "element_type_map.hh"
 #include "node_group.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_GROUP_HH__
 #define __AKANTU_ELEMENT_GROUP_HH__
 
 namespace akantu {
 class Mesh;
 class Element;
-}  // akantu
+} // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class ElementGroup : private Memory, public Dumpable {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ElementGroup(const std::string & name, const Mesh & mesh,
                NodeGroup & node_group, UInt dimension = _all_dimensions,
                const std::string & id = "element_group",
                const MemoryID & memory_id = 0);
 
   /* ------------------------------------------------------------------------ */
   /* Type definitions                                                         */
   /* ------------------------------------------------------------------------ */
 public:
-  typedef ElementTypeMapArray<UInt> ElementList;
-  typedef Array<UInt> NodeList;
-
-  /* ------------------------------------------------------------------------ */
-  /* Node iterator                                                            */
-  /* ------------------------------------------------------------------------ */
-  typedef NodeGroup::const_node_iterator const_node_iterator;
-  inline const_node_iterator node_begin() const;
-  inline const_node_iterator node_end() const;
+  using ElementList = ElementTypeMapArray<UInt>;
+  using NodeList = Array<UInt>;
 
   /* ------------------------------------------------------------------------ */
   /* Element iterator                                                         */
   /* ------------------------------------------------------------------------ */
-  typedef ElementList::type_iterator type_iterator;
+  using type_iterator = ElementList::type_iterator;
   inline type_iterator firstType(UInt dim = _all_dimensions,
                                  const GhostType & ghost_type = _not_ghost,
                                  const ElementKind & kind = _ek_regular) const;
 
   inline type_iterator lastType(UInt dim = _all_dimensions,
                                 const GhostType & ghost_type = _not_ghost,
                                 const ElementKind & kind = _ek_regular) const;
 
-  typedef Array<UInt>::const_iterator<UInt> const_element_iterator;
+  inline auto elementTypes(UInt dim = _all_dimensions,
+                           const GhostType & ghost_type = _not_ghost,
+                           const ElementKind & kind = _ek_regular) const {
+    return elements.elementTypes(dim, ghost_type, kind);
+  }
+
+  using const_element_iterator = Array<UInt>::const_iterator<UInt>;
   inline const_element_iterator
-  element_begin(const ElementType & type,
-                const GhostType & ghost_type = _not_ghost) const;
+  begin(const ElementType & type,
+        const GhostType & ghost_type = _not_ghost) const;
   inline const_element_iterator
-  element_end(const ElementType & type,
-              const GhostType & ghost_type = _not_ghost) const;
+  end(const ElementType & type,
+      const GhostType & ghost_type = _not_ghost) const;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// empty the element group
   void empty();
 
   /// append another group to this group
   /// BE CAREFUL: it doesn't conserve the element order
   void append(const ElementGroup & other_group);
 
   /// add an element to the group. By default the it does not add the nodes to
   /// the group
   inline void add(const Element & el, bool add_nodes = false,
                   bool check_for_duplicate = true);
 
   /// \todo fix the default for add_nodes : make it coherent with the other
   /// method
   inline void add(const ElementType & type, UInt element,
                   const GhostType & ghost_type = _not_ghost,
                   bool add_nodes = true, bool check_for_duplicate = true);
 
   inline void addNode(UInt node_id, bool check_for_duplicate = true);
 
   inline void removeNode(UInt node_id);
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// fill the elements based on the underlying node group.
   virtual void fillFromNodeGroup();
 
   // sort and remove duplicated values
   void optimize();
 
 private:
   inline void addElement(const ElementType & elem_type, UInt elem_id,
                          const GhostType & ghost_type);
 
   friend class GroupManager;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Elements, elements, UInt);
   AKANTU_GET_MACRO(Elements, elements, const ElementTypeMapArray<UInt> &);
   AKANTU_GET_MACRO(Nodes, node_group.getNodes(), const Array<UInt> &);
   AKANTU_GET_MACRO(NodeGroup, node_group, const NodeGroup &);
   AKANTU_GET_MACRO_NOT_CONST(NodeGroup, node_group, NodeGroup &);
   AKANTU_GET_MACRO(Dimension, dimension, UInt);
   AKANTU_GET_MACRO(Name, name, std::string);
   inline UInt getNbNodes() const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// Mesh to which this group belongs
   const Mesh & mesh;
 
   /// name of the group
   std::string name;
 
   /// list of elements composing the group
   ElementList elements;
 
   /// sub list of nodes which are composing the elements
   NodeGroup & node_group;
 
   /// group dimension
   UInt dimension;
 
   /// empty arry for the iterator to work when an element type not present
   Array<UInt> empty_elements;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const ElementGroup & _this) {
   _this.printself(stream);
   return stream;
 }
 
-} // akantu
+} // namespace akantu
 
 #include "element.hh"
 #include "element_group_inline_impl.cc"
 
 #endif /* __AKANTU_ELEMENT_GROUP_HH__ */
diff --git a/src/mesh/element_group_inline_impl.cc b/src/mesh/element_group_inline_impl.cc
index ba16ea036..7ff809849 100644
--- a/src/mesh/element_group_inline_impl.cc
+++ b/src/mesh/element_group_inline_impl.cc
@@ -1,137 +1,135 @@
 /**
  * @file   element_group_inline_impl.cc
  *
  * @author Dana Christen <dana.christen@gmail.com>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
  * @date last modification: Tue Aug 18 2015
  *
  * @brief Stores information relevent to the notion of domain boundary and
  * surfaces.
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "mesh.hh"
+#include "element_group.hh"
+
 /* -------------------------------------------------------------------------- */
 
+#ifndef __AKANTU_ELEMENT_GROUP_INLINE_IMPL_CC__
+#define __AKANTU_ELEMENT_GROUP_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-inline void ElementGroup::add(const Element & el, bool add_nodes, 
-			      bool check_for_duplicate) {
-  this->add(el.type,el.element,el.ghost_type,add_nodes,check_for_duplicate);
+inline void ElementGroup::add(const Element & el, bool add_nodes,
+                              bool check_for_duplicate) {
+  this->add(el.type, el.element, el.ghost_type, add_nodes, check_for_duplicate);
 }
 
-
 /* -------------------------------------------------------------------------- */
 
-inline void ElementGroup::add(const ElementType & type, UInt element, 
-			      const GhostType & ghost_type,bool add_nodes, 
-			      bool check_for_duplicate) {
+inline void ElementGroup::add(const ElementType & type, UInt element,
+                              const GhostType & ghost_type, bool add_nodes,
+                              bool check_for_duplicate) {
 
   addElement(type, element, ghost_type);
 
-  if(add_nodes) {
+  if (add_nodes) {
     Array<UInt>::const_vector_iterator it =
-      mesh.getConnectivity(type, ghost_type).begin(mesh.getNbNodesPerElement(type)) + element;
+        mesh.getConnectivity(type, ghost_type)
+            .begin(mesh.getNbNodesPerElement(type)) +
+        element;
     const Vector<UInt> & conn = *it;
-    for (UInt i = 0; i < conn.size(); ++i) addNode(conn[i], check_for_duplicate);
+    for (UInt i = 0; i < conn.size(); ++i)
+      addNode(conn[i], check_for_duplicate);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ElementGroup::addNode(UInt node_id, bool check_for_duplicate) {
   node_group.add(node_id, check_for_duplicate);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ElementGroup::removeNode(UInt node_id) {
   node_group.remove(node_id);
 }
 
 /* -------------------------------------------------------------------------- */
 inline void ElementGroup::addElement(const ElementType & elem_type,
-				    UInt elem_id,
-				    const GhostType & ghost_type) {
-  if(!(elements.exists(elem_type, ghost_type))) {
+                                     UInt elem_id,
+                                     const GhostType & ghost_type) {
+  if (!(elements.exists(elem_type, ghost_type))) {
     elements.alloc(0, 1, elem_type, ghost_type);
   }
 
   elements(elem_type, ghost_type).push_back(elem_id);
-  this->dimension = UInt(std::max(Int(this->dimension), Int(mesh.getSpatialDimension(elem_type))));
-}
-
-/* -------------------------------------------------------------------------- */
-inline UInt ElementGroup::getNbNodes() const {
-  return node_group.getSize();
+  this->dimension = UInt(
+      std::max(Int(this->dimension), Int(mesh.getSpatialDimension(elem_type))));
 }
 
 /* -------------------------------------------------------------------------- */
-inline ElementGroup::const_node_iterator ElementGroup::node_begin() const {
-  return node_group.begin();
-}
+inline UInt ElementGroup::getNbNodes() const { return node_group.getSize(); }
 
 /* -------------------------------------------------------------------------- */
-inline ElementGroup::const_node_iterator ElementGroup::node_end() const {
-  return node_group.end();
-}
-
-/* -------------------------------------------------------------------------- */
-inline ElementGroup::type_iterator ElementGroup::firstType(UInt dim,
-                                                           const GhostType & ghost_type,
-                                                           const ElementKind & kind) const {
+inline ElementGroup::type_iterator
+ElementGroup::firstType(UInt dim, const GhostType & ghost_type,
+                        const ElementKind & kind) const {
   return elements.firstType(dim, ghost_type, kind);
 }
 
 /* -------------------------------------------------------------------------- */
-inline ElementGroup::type_iterator  ElementGroup::lastType(UInt dim,
-                                                           const GhostType & ghost_type,
-                                                           const ElementKind & kind) const {
+inline ElementGroup::type_iterator
+ElementGroup::lastType(UInt dim, const GhostType & ghost_type,
+                       const ElementKind & kind) const {
   return elements.lastType(dim, ghost_type, kind);
 }
 
 /* -------------------------------------------------------------------------- */
-inline ElementGroup::const_element_iterator ElementGroup::element_begin(const ElementType & type,
-                                                                        const GhostType & ghost_type) const {
-  if(elements.exists(type, ghost_type)) {
+inline ElementGroup::const_element_iterator
+ElementGroup::begin(const ElementType & type,
+                            const GhostType & ghost_type) const {
+  if (elements.exists(type, ghost_type)) {
     return elements(type, ghost_type).begin();
   } else {
     return empty_elements.begin();
   }
 }
 
 /* -------------------------------------------------------------------------- */
-inline ElementGroup::const_element_iterator ElementGroup::element_end(const ElementType & type,
-                                                                      const GhostType & ghost_type) const {
-  if(elements.exists(type, ghost_type)) {
+inline ElementGroup::const_element_iterator
+ElementGroup::end(const ElementType & type,
+                          const GhostType & ghost_type) const {
+  if (elements.exists(type, ghost_type)) {
     return elements(type, ghost_type).end();
   } else {
     return empty_elements.end();
   }
-
 }
 
 /* -------------------------------------------------------------------------- */
 
-} // akantu
+} // namespace akantu
+
+#endif /* __AKANTU_ELEMENT_GROUP_INLINE_IMPL_CC__ */
diff --git a/src/mesh/element_type_map.cc b/src/mesh/element_type_map.cc
index 3aad70e2e..10ed4c342 100644
--- a/src/mesh/element_type_map.cc
+++ b/src/mesh/element_type_map.cc
@@ -1,50 +1,59 @@
 /**
  * @file   element_type_map.cc
  *
  * @author Nicolas Richart
  *
  * @date creation  Tue Jun 27 2017
  *
  * @brief A Documented file.
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
-#include "mesh.hh"
 #include "fe_engine.hh"
+#include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 FEEngineElementTypeMapArrayInializer::FEEngineElementTypeMapArrayInializer(
-      const FEEngine & fe_engine, UInt spatial_dimension,
-      UInt nb_component, const GhostType & ghost_type,
-      const ElementKind & element_kind)
-      : MeshElementTypeMapArrayInializer(fe_engine.getMesh(), spatial_dimension,
-                                         nb_component, ghost_type, element_kind,
-                                         true, false),
-        fe_engine(fe_engine) {}
+    const FEEngine & fe_engine, UInt nb_component, UInt spatial_dimension,
+    const GhostType & ghost_type, const ElementKind & element_kind)
+    : MeshElementTypeMapArrayInializer(
+          fe_engine.getMesh(),
+          nb_component,
+          spatial_dimension == UInt(-2)
+              ? fe_engine.getMesh().getSpatialDimension()
+              : spatial_dimension,
+          ghost_type, element_kind, true, false),
+      fe_engine(fe_engine) {}
 
-UInt FEEngineElementTypeMapArrayInializer::size(const ElementType & type) const {
+UInt FEEngineElementTypeMapArrayInializer::size(
+    const ElementType & type) const {
   return MeshElementTypeMapArrayInializer::size(type) *
-    fe_engine.getNbIntegrationPoints(type, this->ghost_type);
+         fe_engine.getNbIntegrationPoints(type, this->ghost_type);
 }
 
-}  // akantu
+FEEngineElementTypeMapArrayInializer::ElementTypesIteratorHelper
+FEEngineElementTypeMapArrayInializer::elementTypes() const {
+  return this->fe_engine.elementTypes(spatial_dimension, ghost_type,
+                                      element_kind);
+}
+} // namespace akantu
diff --git a/src/mesh/element_type_map.hh b/src/mesh/element_type_map.hh
index 141edba25..438683f5c 100644
--- a/src/mesh/element_type_map.hh
+++ b/src/mesh/element_type_map.hh
@@ -1,394 +1,391 @@
 /**
  * @file   element_type_map.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 31 2011
  * @date last modification: Fri Oct 02 2015
  *
  * @brief  storage class by element type
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_memory.hh"
 #include "aka_named_argument.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_TYPE_MAP_HH__
 #define __AKANTU_ELEMENT_TYPE_MAP_HH__
 
 namespace akantu {
 class FEEngine;
 } // namespace akantu
 
 namespace akantu {
 
 template <class Stored, typename SupportType = ElementType>
 class ElementTypeMap;
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMapBase */
 /* -------------------------------------------------------------------------- */
 /// Common non templated base class for the ElementTypeMap class
 class ElementTypeMapBase {
 public:
   virtual ~ElementTypeMapBase(){};
 };
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMap */
 /* -------------------------------------------------------------------------- */
 
 template <class Stored, typename SupportType>
 class ElementTypeMap : public ElementTypeMapBase {
 
 public:
   ElementTypeMap();
   ~ElementTypeMap();
 
   inline static std::string printType(const SupportType & type,
                                       const GhostType & ghost_type);
 
   /*! Tests whether a type is present in the object
    *  @param type the type to check for
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @return true if the type is present. */
   inline bool exists(const SupportType & type,
                      const GhostType & ghost_type = _not_ghost) const;
 
   /*! get the stored data corresponding to a type
    *  @param type the type to check for
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @return stored data corresponding to type. */
   inline const Stored &
   operator()(const SupportType & type,
              const GhostType & ghost_type = _not_ghost) const;
 
   /*! get the stored data corresponding to a type
    *  @param type the type to check for
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @return stored data corresponding to type. */
   inline Stored & operator()(const SupportType & type,
                              const GhostType & ghost_type = _not_ghost);
 
   /*! insert data of a new type (not yet present) into the map. THIS METHOD IS
    *  NOT ARRAY SAFE, when using ElementTypeMapArray, use setArray instead
    *  @param data to insert
    *  @param type type of data (if this type is already present in the map,
    *         an exception is thrown).
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @return stored data corresponding to type. */
   inline Stored & operator()(const Stored & insert, const SupportType & type,
                              const GhostType & ghost_type = _not_ghost);
 
   /// print helper
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Element type Iterator                                                    */
   /* ------------------------------------------------------------------------ */
   /*! iterator allows to iterate over type-data pairs of the map. The interface
    *  expects the SupportType to be ElementType. */
   typedef std::map<SupportType, Stored> DataMap;
   class type_iterator
       : private std::iterator<std::forward_iterator_tag, const SupportType> {
   public:
     typedef const SupportType value_type;
     typedef const SupportType * pointer;
     typedef const SupportType & reference;
 
   protected:
     typedef typename ElementTypeMap<Stored>::DataMap::const_iterator
         DataMapIterator;
 
   public:
     type_iterator(DataMapIterator & list_begin, DataMapIterator & list_end,
                   UInt dim, ElementKind ek);
 
     type_iterator(const type_iterator & it);
     type_iterator() {}
 
     inline reference operator*();
     inline reference operator*() const;
     inline type_iterator & operator++();
     type_iterator operator++(int);
     inline bool operator==(const type_iterator & other) const;
     inline bool operator!=(const type_iterator & other) const;
     type_iterator & operator=(const type_iterator & other);
 
   private:
     DataMapIterator list_begin;
     DataMapIterator list_end;
     UInt dim;
     ElementKind kind;
   };
 
   /// helper class to use in range for constructions
   class ElementTypesIteratorHelper {
   public:
     using Container = ElementTypeMap<Stored, SupportType>;
     using iterator = typename Container::type_iterator;
 
     ElementTypesIteratorHelper(const Container & container,
                                UInt dim = _all_dimensions,
                                GhostType ghost_type = _not_ghost,
                                ElementKind kind = _ek_regular)
         : container(std::cref(container)), dim(dim), ghost_type(ghost_type),
           kind(kind) {}
 
     ElementTypesIteratorHelper(const ElementTypesIteratorHelper &) = default;
     ElementTypesIteratorHelper &
     operator=(const ElementTypesIteratorHelper &) = default;
     ElementTypesIteratorHelper &
     operator=(ElementTypesIteratorHelper &&) = default;
 
     iterator begin() {
       return container.get().firstType(dim, ghost_type, kind);
     }
     iterator end() { return container.get().lastType(dim, ghost_type, kind); }
 
   private:
     std::reference_wrapper<const Container> container;
     UInt dim;
     GhostType ghost_type;
     ElementKind kind;
   };
 
   /// method to create the helper class to use in range for constructs
   ElementTypesIteratorHelper elementTypes(UInt dim = _all_dimensions,
                                           GhostType ghost_type = _not_ghost,
                                           ElementKind kind = _ek_regular) const;
 
   /*! Get an iterator to the beginning of a subset datamap. This method expects
    *  the SupportType to be ElementType.
    *  @param dim optional: iterate over data of dimension dim (e.g. when
    *         iterating over (surface) facets of a 3D mesh, dim would be 2).
    *         by default, all dimensions are considered.
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is iterated over.
    *  @param kind optional: the kind of element to search for (see
    *         aka_common.hh), by default all kinds are considered
    *  @return an iterator to the first stored data matching the filters
    *          or an iterator to the end of the map if none match*/
   inline type_iterator firstType(UInt dim = _all_dimensions,
                                  GhostType ghost_type = _not_ghost,
                                  ElementKind kind = _ek_not_defined) const;
   /*! Get an iterator to the end of a subset datamap. This method expects
    *  the SupportType to be ElementType.
    *  @param dim optional: iterate over data of dimension dim (e.g. when
    *         iterating over (surface) facets of a 3D mesh, dim would be 2).
    *         by default, all dimensions are considered.
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is iterated over.
    *  @param kind optional: the kind of element to search for (see
    *         aka_common.hh), by default all kinds are considered
    *  @return an iterator to the last stored data matching the filters
    *          or an iterator to the end of the map if none match */
   inline type_iterator lastType(UInt dim = _all_dimensions,
                                 GhostType ghost_type = _not_ghost,
                                 ElementKind kind = _ek_not_defined) const;
 
 protected:
   /*! Direct access to the underlying data map. for internal use by daughter
    *  classes only
    *  @param ghost_type whether to return the data map or the ghost_data map
    *  @return the raw map */
   inline DataMap & getData(GhostType ghost_type);
   /*! Direct access to the underlying data map. for internal use by daughter
    *  classes only
    *  @param ghost_type whether to return the data map or the ghost_data map
    *  @return the raw map */
   inline const DataMap & getData(GhostType ghost_type) const;
 
   /* ------------------------------------------------------------------------ */
 protected:
   DataMap data;
   DataMap ghost_data;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Some typedefs                                                              */
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 class ElementTypeMapArray : public ElementTypeMap<Array<T> *, SupportType>,
                             public Memory {
 public:
   typedef T type;
   typedef Array<T> array_type;
 
 protected:
   typedef ElementTypeMap<Array<T> *, SupportType> parent;
   typedef typename parent::DataMap DataMap;
 
 private:
 private:
   /// standard assigment (copy) operator
   void operator=(const ElementTypeMap<T, SupportType> &){};
 
 public:
-  typedef typename parent::type_iterator type_iterator;
+  using type_iterator = typename parent::type_iterator;
 
   /*! Constructor
    *  @param id optional: identifier (string)
    *  @param parent_id optional: parent identifier. for organizational purposes
    *         only
    *  @param memory_id optional: choose a specific memory, defaults to memory 0
    */
   ElementTypeMapArray(const ID & id = "by_element_type_array",
                       const ID & parent_id = "no_parent",
                       const MemoryID & memory_id = 0)
       : parent(), Memory(parent_id + ":" + id, memory_id), name(id){};
 
   /*! allocate memory for a new array
    *  @param size number of tuples of the new array
    *  @param nb_component tuple size
    *  @param type the type under which the array is indexed in the map
    *  @param ghost_type whether to add the field to the data map or the
    *         ghost_data map
    *  @return a reference to the allocated array */
   inline Array<T> & alloc(UInt size, UInt nb_component,
                           const SupportType & type,
                           const GhostType & ghost_type,
                           const T & default_value = T());
 
   /*! allocate memory for a new array in both the data and the ghost_data map
    *  @param size number of tuples of the new array
    *  @param nb_component tuple size
    *  @param type the type under which the array is indexed in the map*/
   inline void alloc(UInt size, UInt nb_component, const SupportType & type,
                     const T & default_value = T());
 
   /* get a reference to the array of certain type
    * @param type data filed under type is returned
    * @param ghost_type optional: by default the non-ghost map is searched
    * @return a reference to the array */
   inline const Array<T> &
   operator()(const SupportType & type,
              const GhostType & ghost_type = _not_ghost) const;
 
   /* get a reference to the array of certain type
    * @param type data filed under type is returned
    * @param ghost_type optional: by default the non-ghost map is searched
    * @return a const reference to the array */
   inline Array<T> & operator()(const SupportType & type,
                                const GhostType & ghost_type = _not_ghost);
 
   /*! insert data of a new type (not yet present) into the map.
    *  @param type type of data (if this type is already present in the map,
    *         an exception is thrown).
    *  @param ghost_type optional: by default, the data map for non-ghost
    *         elements is searched
    *  @param vect the vector to include into the map
    *  @return stored data corresponding to type. */
   inline void setArray(const SupportType & type, const GhostType & ghost_type,
                        const Array<T> & vect);
   /*! frees all memory related to the data*/
   inline void free();
 
   /*! set all values in the ElementTypeMap to zero*/
   inline void clear();
 
   /*! deletes and reorders entries in the stored arrays
    *  @param new_numbering a ElementTypeMapArray of new indices. UInt(-1)
    * indicates
    *         deleted entries. */
   inline void
   onElementsRemoved(const ElementTypeMapArray<UInt> & new_numbering);
 
   /// text output helper
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /*! set the id
    *  @param id the new name
    */
   inline void setID(const ID & id) { this->id = id; }
 
   ElementTypeMap<UInt>
   getNbComponents(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
                   ElementKind kind = _ek_not_defined) const {
 
     ElementTypeMap<UInt> nb_components;
 
-    type_iterator tit = this->firstType(dim, ghost_type, kind);
-    type_iterator end = this->lastType(dim, ghost_type, kind);
-
-    while (tit != end) {
-      UInt nb_comp = (*this)(*tit, ghost_type).getNbComponent();
-      nb_components(*tit, ghost_type) = nb_comp;
-      ++tit;
+    for (auto & type : this->elementTypes(dim, ghost_type, kind)) {
+      UInt nb_comp = (*this)(type, ghost_type).getNbComponent();
+      nb_components(type, ghost_type) = nb_comp;
     }
+
     return nb_components;
   }
 
   /* ------------------------------------------------------------------------ */
   /* more evolved allocators                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the arrays in accordance to a functor
   template <class Func>
   void initialize(const Func & f, const T & default_value = T());
 
   /// initialize with sizes and number of components in accordance of a mesh
   /// content
   template <typename... pack>
   void initialize(const Mesh & mesh, pack &&... _pack);
 
   /// initialize with sizes and number of components in accordance of a fe
   /// engine content (aka integration points)
   template <typename... pack>
   void initialize(const FEEngine & fe_engine, pack &&... _pack);
 
   /* ------------------------------------------------------------------------ */
   /* Accesssors                                                               */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the name of the internal field
   AKANTU_GET_MACRO(Name, name, ID);
 
 private:
   ElementTypeMapArray operator=(__attribute__((unused))
                                 const ElementTypeMapArray & other){};
 
   /// name of the elment type map: e.g. connectivity, grad_u
   ID name;
 };
 
 /// to store data Array<Real> by element type
 typedef ElementTypeMapArray<Real> ElementTypeMapReal;
 /// to store data Array<Int> by element type
 typedef ElementTypeMapArray<Int> ElementTypeMapInt;
 /// to store data Array<UInt> by element type
 typedef ElementTypeMapArray<UInt, ElementType> ElementTypeMapUInt;
 
 /// Map of data of type UInt stored in a mesh
 typedef std::map<std::string, Array<UInt> *> UIntDataMap;
 typedef ElementTypeMap<UIntDataMap, ElementType> ElementTypeMapUIntDataMap;
 
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_TYPE_MAP_HH__ */
diff --git a/src/mesh/element_type_map_tmpl.hh b/src/mesh/element_type_map_tmpl.hh
index 6a6e038e3..91735c2a0 100644
--- a/src/mesh/element_type_map_tmpl.hh
+++ b/src/mesh/element_type_map_tmpl.hh
@@ -1,623 +1,621 @@
 /**
  * @file   element_type_map_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Aug 31 2011
  * @date last modification: Fri Oct 02 2015
  *
  * @brief  implementation of template functions of the ElementTypeMap and
  * ElementTypeMapArray classes
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_type_map.hh"
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
+#include "element_type_conversion.hh"
+/* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__
 #define __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
-/* ElementTypeMap */
+/* ElementTypeMap                                                             */
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline std::string
 ElementTypeMap<Stored, SupportType>::printType(const SupportType & type,
                                                const GhostType & ghost_type) {
   std::stringstream sstr;
   sstr << "(" << ghost_type << ":" << type << ")";
   return sstr.str();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline bool ElementTypeMap<Stored, SupportType>::exists(
     const SupportType & type, const GhostType & ghost_type) const {
   return this->getData(ghost_type).find(type) !=
          this->getData(ghost_type).end();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline const Stored & ElementTypeMap<Stored, SupportType>::
 operator()(const SupportType & type, const GhostType & ghost_type) const {
   typename DataMap::const_iterator it = this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end())
     AKANTU_SILENT_EXCEPTION("No element of type "
                             << ElementTypeMap::printType(type, ghost_type)
                             << " in this ElementTypeMap<"
                             << debug::demangle(typeid(Stored).name())
                             << "> class");
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline Stored & ElementTypeMap<Stored, SupportType>::
 operator()(const SupportType & type, const GhostType & ghost_type) {
   return this->getData(ghost_type)[type];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline Stored & ElementTypeMap<Stored, SupportType>::
 operator()(const Stored & insert, const SupportType & type,
            const GhostType & ghost_type) {
   typename DataMap::iterator it = this->getData(ghost_type).find(type);
 
   if (it != this->getData(ghost_type).end()) {
     AKANTU_SILENT_EXCEPTION("Element of type "
                             << ElementTypeMap::printType(type, ghost_type)
                             << " already in this ElementTypeMap<"
                             << debug::demangle(typeid(Stored).name())
                             << "> class");
   } else {
     DataMap & data = this->getData(ghost_type);
     const std::pair<typename DataMap::iterator, bool> & res =
         data.insert(std::pair<ElementType, Stored>(type, insert));
     it = res.first;
   }
 
   return it->second;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::DataMap &
 ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) {
   if (ghost_type == _not_ghost)
     return data;
   else
     return ghost_data;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline const typename ElementTypeMap<Stored, SupportType>::DataMap &
 ElementTypeMap<Stored, SupportType>::getData(GhostType ghost_type) const {
   if (ghost_type == _not_ghost)
     return data;
   else
     return ghost_data;
 }
 
 /* -------------------------------------------------------------------------- */
 /// Works only if stored is a pointer to a class with a printself method
 template <class Stored, typename SupportType>
 void ElementTypeMap<Stored, SupportType>::printself(std::ostream & stream,
                                                     int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "ElementTypeMap<" << debug::demangle(typeid(Stored).name())
          << "> [" << std::endl;
-  for (UInt g = _not_ghost; g <= _ghost; ++g) {
-    GhostType gt = (GhostType)g;
-
+  for (auto gt : ghost_types) {
     const DataMap & data = getData(gt);
-    typename DataMap::const_iterator it;
-    for (it = data.begin(); it != data.end(); ++it) {
-      stream << space << space << ElementTypeMap::printType(it->first, gt)
+    for (auto & pair : data) {
+      stream << space << space << ElementTypeMap::printType(pair.first, gt)
              << std::endl;
     }
   }
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::ElementTypeMap() {
   AKANTU_DEBUG_IN();
 
   // std::stringstream sstr;
   // if(parent_id != "") sstr << parent_id << ":";
   // sstr << id;
 
   // this->id = sstr.str();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::~ElementTypeMap() {}
 
 /* -------------------------------------------------------------------------- */
 /* ElementTypeMapArray                                                        */
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline Array<T> & ElementTypeMapArray<T, SupportType>::alloc(
     UInt size, UInt nb_component, const SupportType & type,
     const GhostType & ghost_type, const T & default_value) {
   std::string ghost_id = "";
   if (ghost_type == _ghost)
     ghost_id = ":ghost";
 
   Array<T> * tmp;
 
   typename ElementTypeMapArray<T, SupportType>::DataMap::iterator it =
       this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end()) {
     std::stringstream sstr;
     sstr << this->id << ":" << type << ghost_id;
     tmp = &(Memory::alloc<T>(sstr.str(), size, nb_component, default_value));
     std::stringstream sstrg;
     sstrg << ghost_type;
     // tmp->setTag(sstrg.str());
     this->getData(ghost_type)[type] = tmp;
   } else {
     AKANTU_DEBUG_INFO(
         "The vector "
         << this->id << this->printType(type, ghost_type)
         << " already exists, it is resized instead of allocated.");
     tmp = it->second;
     it->second->resize(size);
   }
 
   return *tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void
 ElementTypeMapArray<T, SupportType>::alloc(UInt size, UInt nb_component,
                                            const SupportType & type,
                                            const T & default_value) {
   this->alloc(size, nb_component, type, _not_ghost, default_value);
   this->alloc(size, nb_component, type, _ghost, default_value);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::free() {
   AKANTU_DEBUG_IN();
 
-  for (UInt g = _not_ghost; g <= _ghost; ++g) {
-    GhostType gt = (GhostType)g;
-
+  for (auto gt : ghost_types) {
     DataMap & data = this->getData(gt);
-    typename DataMap::const_iterator it;
-    for (it = data.begin(); it != data.end(); ++it) {
-      dealloc(it->second->getID());
+    for (auto & pair : data) {
+      dealloc(pair.second->getID());
     }
     data.clear();
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::clear() {
-  for (UInt g = _not_ghost; g <= _ghost; ++g) {
-    GhostType gt = (GhostType)g;
-
+  for (auto gt : ghost_types) {
     DataMap & data = this->getData(gt);
-    typename DataMap::const_iterator it;
-    for (it = data.begin(); it != data.end(); ++it) {
-      it->second->clear();
+    for (auto & vect : data) {
+      vect.second->clear();
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline const Array<T> & ElementTypeMapArray<T, SupportType>::
 operator()(const SupportType & type, const GhostType & ghost_type) const {
   typename ElementTypeMapArray<T, SupportType>::DataMap::const_iterator it =
       this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end())
     AKANTU_SILENT_EXCEPTION("No element of type "
                             << ElementTypeMapArray::printType(type, ghost_type)
                             << " in this const ElementTypeMapArray<"
                             << debug::demangle(typeid(T).name()) << "> class(\""
                             << this->id << "\")");
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline Array<T> & ElementTypeMapArray<T, SupportType>::
 operator()(const SupportType & type, const GhostType & ghost_type) {
   typename ElementTypeMapArray<T, SupportType>::DataMap::iterator it =
       this->getData(ghost_type).find(type);
 
   if (it == this->getData(ghost_type).end())
     AKANTU_SILENT_EXCEPTION("No element of type "
                             << ElementTypeMapArray::printType(type, ghost_type)
                             << " in this ElementTypeMapArray<"
                             << debug::demangle(typeid(T).name())
                             << "> class (\"" << this->id << "\")");
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void
 ElementTypeMapArray<T, SupportType>::setArray(const SupportType & type,
                                               const GhostType & ghost_type,
                                               const Array<T> & vect) {
   typename ElementTypeMapArray<T, SupportType>::DataMap::iterator it =
       this->getData(ghost_type).find(type);
 
   if (AKANTU_DEBUG_TEST(dblWarning) && it != this->getData(ghost_type).end() &&
       it->second != &vect) {
     AKANTU_DEBUG_WARNING(
         "The Array "
         << this->printType(type, ghost_type)
         << " is already registred, this call can lead to a memory leak.");
   }
 
   this->getData(ghost_type)[type] = &(const_cast<Array<T> &>(vect));
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 inline void ElementTypeMapArray<T, SupportType>::onElementsRemoved(
     const ElementTypeMapArray<UInt> & new_numbering) {
-  for (UInt g = _not_ghost; g <= _ghost; ++g) {
-    GhostType gt = (GhostType)g;
-    ElementTypeMapArray<UInt>::type_iterator it =
-        new_numbering.firstType(_all_dimensions, gt, _ek_not_defined);
-    ElementTypeMapArray<UInt>::type_iterator end =
-        new_numbering.lastType(_all_dimensions, gt, _ek_not_defined);
-    for (; it != end; ++it) {
-      SupportType type = *it;
-      if (this->exists(type, gt)) {
-        const Array<UInt> & renumbering = new_numbering(type, gt);
+  for (auto gt : ghost_types) {
+    for (auto & type :
+         new_numbering.elementTypes(_all_dimensions, gt, _ek_not_defined)) {
+      SupportType support_type = convertType<ElementType, SupportType>(type);
+      if (this->exists(support_type, gt)) {
+        const auto & renumbering = new_numbering(type, gt);
         if (renumbering.getSize() == 0)
           continue;
-        Array<T> & vect = this->operator()(type, gt);
-        UInt nb_component = vect.getNbComponent();
+
+        auto & vect = this->operator()(support_type, gt);
+        auto nb_component = vect.getNbComponent();
         Array<T> tmp(renumbering.getSize(), nb_component);
         UInt new_size = 0;
+
         for (UInt i = 0; i < vect.getSize(); ++i) {
           UInt new_i = renumbering(i);
           if (new_i != UInt(-1)) {
             memcpy(tmp.storage() + new_i * nb_component,
                    vect.storage() + i * nb_component, nb_component * sizeof(T));
             ++new_size;
           }
         }
         tmp.resize(new_size);
         vect.copy(tmp);
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 void ElementTypeMapArray<T, SupportType>::printself(std::ostream & stream,
                                                     int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "ElementTypeMapArray<" << debug::demangle(typeid(T).name())
          << "> [" << std::endl;
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     GhostType gt = (GhostType)g;
 
     const DataMap & data = this->getData(gt);
     typename DataMap::const_iterator it;
     for (it = data.begin(); it != data.end(); ++it) {
       stream << space << space << ElementTypeMapArray::printType(it->first, gt)
              << " [" << std::endl;
       it->second->printself(stream, indent + 3);
       stream << space << space << " ]" << std::endl;
     }
   }
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 /* SupportType Iterator                                                       */
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(
     DataMapIterator & list_begin, DataMapIterator & list_end, UInt dim,
     ElementKind ek)
     : list_begin(list_begin), list_end(list_end), dim(dim), kind(ek) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 ElementTypeMap<Stored, SupportType>::type_iterator::type_iterator(
     const type_iterator & it)
     : list_begin(it.list_begin), list_end(it.list_end), dim(it.dim),
       kind(it.kind) {}
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 typename ElementTypeMap<Stored, SupportType>::type_iterator &
 ElementTypeMap<Stored, SupportType>::type_iterator::
 operator=(const type_iterator & it) {
   if (this != &it) {
     list_begin = it.list_begin;
     list_end = it.list_end;
     dim = it.dim;
     kind = it.kind;
   }
   return *this;
 }
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
     ElementTypeMap<Stored, SupportType>::type_iterator::operator*() {
   return list_begin->first;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator::reference
     ElementTypeMap<Stored, SupportType>::type_iterator::operator*() const {
   return list_begin->first;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator &
     ElementTypeMap<Stored, SupportType>::type_iterator::operator++() {
   ++list_begin;
   while ((list_begin != list_end) &&
          (((dim != _all_dimensions) &&
            (dim != Mesh::getSpatialDimension(list_begin->first))) ||
           ((kind != _ek_not_defined) &&
            (kind != Mesh::getKind(list_begin->first)))))
     ++list_begin;
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 typename ElementTypeMap<Stored, SupportType>::type_iterator
     ElementTypeMap<Stored, SupportType>::type_iterator::operator++(int) {
   type_iterator tmp(*this);
   operator++();
   return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline bool ElementTypeMap<Stored, SupportType>::type_iterator::
 operator==(const type_iterator & other) const {
   return this->list_begin == other.list_begin;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline bool ElementTypeMap<Stored, SupportType>::type_iterator::
 operator!=(const type_iterator & other) const {
   return this->list_begin != other.list_begin;
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 typename ElementTypeMap<Stored, SupportType>::ElementTypesIteratorHelper
 ElementTypeMap<Stored, SupportType>::elementTypes(UInt dim,
                                                   GhostType ghost_type,
                                                   ElementKind kind) const {
   return ElementTypesIteratorHelper(*this, dim, ghost_type, kind);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator
 ElementTypeMap<Stored, SupportType>::firstType(UInt dim, GhostType ghost_type,
                                                ElementKind kind) const {
   typename DataMap::const_iterator b, e;
   b = getData(ghost_type).begin();
   e = getData(ghost_type).end();
 
   // loop until the first valid type
   while ((b != e) &&
          (((dim != _all_dimensions) &&
            (dim != Mesh::getSpatialDimension(b->first))) ||
           ((kind != _ek_not_defined) && (kind != Mesh::getKind(b->first)))))
     ++b;
 
   return typename ElementTypeMap<Stored, SupportType>::type_iterator(b, e, dim,
                                                                      kind);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class Stored, typename SupportType>
 inline typename ElementTypeMap<Stored, SupportType>::type_iterator
 ElementTypeMap<Stored, SupportType>::lastType(UInt dim, GhostType ghost_type,
                                               ElementKind kind) const {
   typename DataMap::const_iterator e;
   e = getData(ghost_type).end();
   return typename ElementTypeMap<Stored, SupportType>::type_iterator(e, e, dim,
                                                                      kind);
 }
 
 /* -------------------------------------------------------------------------- */
 
 /// standard output stream operator
 template <class Stored, typename SupportType>
 inline std::ostream &
 operator<<(std::ostream & stream,
            const ElementTypeMap<Stored, SupportType> & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /* -------------------------------------------------------------------------- */
 class ElementTypeMapArrayInializer {
 public:
   ElementTypeMapArrayInializer(UInt spatial_dimension = _all_dimensions,
                                UInt nb_component = 1,
                                const GhostType & ghost_type = _not_ghost,
                                const ElementKind & element_kind = _ek_regular)
       : spatial_dimension(spatial_dimension), nb_component(nb_component),
         ghost_type(ghost_type), element_kind(element_kind) {}
 
   const GhostType & ghostType() const { return ghost_type; }
 
 protected:
   UInt spatial_dimension;
   UInt nb_component;
   GhostType ghost_type;
   ElementKind element_kind;
 };
 
 /* -------------------------------------------------------------------------- */
 class MeshElementTypeMapArrayInializer : public ElementTypeMapArrayInializer {
 public:
   MeshElementTypeMapArrayInializer(
-      const Mesh & mesh, UInt spatial_dimension = _all_dimensions,
-      UInt nb_component = 1, const GhostType & ghost_type = _not_ghost,
+      const Mesh & mesh, UInt nb_component = 1,
+      UInt spatial_dimension = _all_dimensions,
+      const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_regular,
       bool with_nb_element = false, bool with_nb_nodes_per_element = false)
       : ElementTypeMapArrayInializer(spatial_dimension, nb_component,
                                      ghost_type, element_kind),
         mesh(mesh), with_nb_element(with_nb_element),
         with_nb_nodes_per_element(with_nb_nodes_per_element) {}
 
   decltype(auto) elementTypes() const {
     return mesh.elementTypes(this->spatial_dimension, this->ghost_type,
                              this->element_kind);
   }
 
   virtual UInt size(const ElementType & type) const {
     if (with_nb_element)
       return mesh.getNbElement(type, this->ghost_type);
 
     return 0;
   }
 
   UInt nbComponent(const ElementType & type) const {
     if (with_nb_nodes_per_element)
       return (this->nb_component * mesh.getNbNodesPerElement(type));
 
     return this->nb_component;
   }
 
 protected:
   const Mesh & mesh;
   bool with_nb_element;
   bool with_nb_nodes_per_element;
 };
 
 /* -------------------------------------------------------------------------- */
 class FEEngineElementTypeMapArrayInializer
     : public MeshElementTypeMapArrayInializer {
 public:
   FEEngineElementTypeMapArrayInializer(
-      const FEEngine & fe_engine, UInt spatial_dimension = _all_dimensions,
-      UInt nb_component = 1, const GhostType & ghost_type = _not_ghost,
+      const FEEngine & fe_engine, UInt nb_component = 1,
+      UInt spatial_dimension = _all_dimensions,
+      const GhostType & ghost_type = _not_ghost,
       const ElementKind & element_kind = _ek_regular);
 
   UInt size(const ElementType & type) const override;
 
+  using ElementTypesIteratorHelper =
+      ElementTypeMapArray<Real, ElementType>::ElementTypesIteratorHelper;
+
+  ElementTypesIteratorHelper elementTypes() const;
+
 protected:
   const FEEngine & fe_engine;
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 template <class Func>
 void ElementTypeMapArray<T, SupportType>::initialize(const Func & f,
                                                      const T & default_value) {
   for (auto & type : f.elementTypes()) {
     if (not this->exists(type, f.ghostType()))
       this->alloc(f.size(type), f.nbComponent(type), type, f.ghostType(),
                   default_value);
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 template <typename... pack>
 void ElementTypeMapArray<T, SupportType>::initialize(const Mesh & mesh,
                                                      pack &&... _pack) {
   GhostType requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _casper);
   bool all_ghost_types = requested_ghost_type == _casper;
 
   for (auto ghost_type : ghost_types) {
     if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types))
       continue;
 
     this->initialize(
         MeshElementTypeMapArrayInializer(
             mesh, OPTIONAL_NAMED_ARG(nb_component, 1),
             OPTIONAL_NAMED_ARG(spatial_dimension, mesh.getSpatialDimension()),
             ghost_type, OPTIONAL_NAMED_ARG(element_kind, _ek_regular),
             OPTIONAL_NAMED_ARG(with_nb_element, false),
             OPTIONAL_NAMED_ARG(with_nb_nodes_per_element, false)),
         OPTIONAL_NAMED_ARG(default_value, T()));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T, typename SupportType>
 template <typename... pack>
 void ElementTypeMapArray<T, SupportType>::initialize(const FEEngine & fe_engine,
                                                      pack &&... _pack) {
   bool all_ghost_types = OPTIONAL_NAMED_ARG(all_ghost_types, true);
   GhostType requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _not_ghost);
 
   for (auto ghost_type : ghost_types) {
     if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types))
       continue;
 
     this->initialize(FEEngineElementTypeMapArrayInializer(
-                         fe_engine,
-                         OPTIONAL_NAMED_ARG(spatial_dimension, _all_dimensions),
-                         OPTIONAL_NAMED_ARG(nb_component, 1), ghost_type,
+                         fe_engine, OPTIONAL_NAMED_ARG(nb_component, 1),
+                         OPTIONAL_NAMED_ARG(spatial_dimension, UInt(-2)),
+                         ghost_type,
                          OPTIONAL_NAMED_ARG(element_kind, _ek_regular)),
                      OPTIONAL_NAMED_ARG(default_value, T()));
   }
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_ELEMENT_TYPE_MAP_TMPL_HH__ */
diff --git a/src/mesh/group_manager.cc b/src/mesh/group_manager.cc
index 18afdb476..f9517336a 100644
--- a/src/mesh/group_manager.cc
+++ b/src/mesh/group_manager.cc
@@ -1,1030 +1,1041 @@
 /**
  * @file   group_manager.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@gmail.com>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
  * @date last modification: Mon Aug 17 2015
  *
  * @brief  Stores information about ElementGroup and NodeGroup
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "group_manager.hh"
 #include "aka_csr.hh"
 #include "data_accessor.hh"
 #include "element_group.hh"
 #include "element_synchronizer.hh"
 #include "mesh.hh"
+#include "mesh_accessor.hh"
 #include "mesh_utils.hh"
 #include "node_group.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <iterator>
 #include <list>
 #include <numeric>
 #include <queue>
 #include <sstream>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 GroupManager::GroupManager(const Mesh & mesh, const ID & id,
                            const MemoryID & mem_id)
     : id(id), memory_id(mem_id), mesh(mesh) {
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 GroupManager::~GroupManager() {
   auto eit = element_groups.begin();
   auto eend = element_groups.end();
   for (; eit != eend; ++eit)
     delete (eit->second);
 
   auto nit = node_groups.begin();
   auto nend = node_groups.end();
   for (; nit != nend; ++nit)
     delete (nit->second);
 }
 
 /* -------------------------------------------------------------------------- */
 NodeGroup & GroupManager::createNodeGroup(const std::string & group_name,
                                           bool replace_group) {
   AKANTU_DEBUG_IN();
 
   auto it = node_groups.find(group_name);
 
   if (it != node_groups.end()) {
     if (replace_group) {
       it->second->empty();
       AKANTU_DEBUG_OUT();
       return *(it->second);
     } else
       AKANTU_EXCEPTION(
           "Trying to create a node group that already exists:" << group_name);
   }
 
   std::stringstream sstr;
   sstr << this->id << ":" << group_name << "_node_group";
 
   NodeGroup * node_group =
       new NodeGroup(group_name, mesh, sstr.str(), memory_id);
 
   node_groups[group_name] = node_group;
 
   AKANTU_DEBUG_OUT();
 
   return *node_group;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 NodeGroup &
 GroupManager::createFilteredNodeGroup(const std::string & group_name,
                                       const NodeGroup & source_node_group,
                                       T & filter) {
   AKANTU_DEBUG_IN();
 
   NodeGroup & node_group = this->createNodeGroup(group_name);
   node_group.append(source_node_group);
   if (T::type == FilterFunctor::_node_filter_functor) {
     node_group.applyNodeFilter(filter);
   } else {
     AKANTU_DEBUG_ERROR("ElementFilter cannot be applied to NodeGroup yet."
                        << " Needs to be implemented.");
   }
 
   AKANTU_DEBUG_OUT();
   return node_group;
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::destroyNodeGroup(const std::string & group_name) {
   AKANTU_DEBUG_IN();
 
   NodeGroups::iterator nit = node_groups.find(group_name);
   NodeGroups::iterator nend = node_groups.end();
   if (nit != nend) {
     delete (nit->second);
     node_groups.erase(nit);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
                                                 UInt dimension,
                                                 bool replace_group) {
   AKANTU_DEBUG_IN();
 
   NodeGroup & new_node_group =
       createNodeGroup(group_name + "_nodes", replace_group);
 
   auto it = element_groups.find(group_name);
 
   if (it != element_groups.end()) {
     if (replace_group) {
       it->second->empty();
       AKANTU_DEBUG_OUT();
       return *(it->second);
     } else
       AKANTU_EXCEPTION("Trying to create a element group that already exists:"
                        << group_name);
   }
 
   std::stringstream sstr;
   sstr << this->id << ":" << group_name << "_element_group";
 
   ElementGroup * element_group = new ElementGroup(
       group_name, mesh, new_node_group, dimension, sstr.str(), memory_id);
 
   std::stringstream sstr_nodes;
   sstr_nodes << group_name << "_nodes";
 
   node_groups[sstr_nodes.str()] = &new_node_group;
   element_groups[group_name] = element_group;
 
   AKANTU_DEBUG_OUT();
 
   return *element_group;
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::destroyElementGroup(const std::string & group_name,
                                        bool destroy_node_group) {
   AKANTU_DEBUG_IN();
 
   auto eit = element_groups.find(group_name);
   auto eend = element_groups.end();
   if (eit != eend) {
     if (destroy_node_group)
       destroyNodeGroup(eit->second->getNodeGroup().getName());
     delete (eit->second);
     element_groups.erase(eit);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::destroyAllElementGroups(bool destroy_node_groups) {
   AKANTU_DEBUG_IN();
 
   auto eit = element_groups.begin();
   auto eend = element_groups.end();
   for (; eit != eend; ++eit) {
     if (destroy_node_groups)
       destroyNodeGroup(eit->second->getNodeGroup().getName());
     delete (eit->second);
   }
   element_groups.clear();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 ElementGroup & GroupManager::createElementGroup(const std::string & group_name,
                                                 UInt dimension,
                                                 NodeGroup & node_group) {
   AKANTU_DEBUG_IN();
 
   if (element_groups.find(group_name) != element_groups.end())
     AKANTU_EXCEPTION(
         "Trying to create a element group that already exists:" << group_name);
 
   ElementGroup * element_group =
       new ElementGroup(group_name, mesh, node_group, dimension,
                        id + ":" + group_name + "_element_group", memory_id);
 
   element_groups[group_name] = element_group;
 
   AKANTU_DEBUG_OUT();
 
   return *element_group;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 ElementGroup & GroupManager::createFilteredElementGroup(
     const std::string & group_name, UInt dimension,
     const NodeGroup & node_group, T & filter) {
   AKANTU_DEBUG_IN();
 
   ElementGroup * element_group = NULL;
 
   if (T::type == FilterFunctor::_node_filter_functor) {
     NodeGroup & filtered_node_group = this->createFilteredNodeGroup(
         group_name + "_nodes", node_group, filter);
     element_group =
         &(this->createElementGroup(group_name, dimension, filtered_node_group));
   } else if (T::type == FilterFunctor::_element_filter_functor) {
     AKANTU_DEBUG_ERROR(
         "Cannot handle an ElementFilter yet. Needs to be implemented.");
   }
 
   AKANTU_DEBUG_OUT();
 
   return *element_group;
 }
 
 /* -------------------------------------------------------------------------- */
 class ClusterSynchronizer : public DataAccessor<Element> {
   using DistantIDs = std::set<std::pair<UInt, UInt>>;
 
 public:
   ClusterSynchronizer(GroupManager & group_manager, UInt element_dimension,
                       std::string cluster_name_prefix,
                       ElementTypeMapArray<UInt> & element_to_fragment,
                       const ElementSynchronizer & element_synchronizer,
                       UInt nb_cluster)
       : group_manager(group_manager), element_dimension(element_dimension),
         cluster_name_prefix(cluster_name_prefix),
         element_to_fragment(element_to_fragment),
         element_synchronizer(element_synchronizer), nb_cluster(nb_cluster) {}
 
   UInt synchronize() {
     StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
     UInt rank = comm.whoAmI();
     UInt nb_proc = comm.getNbProc();
 
     /// find starting index to renumber local clusters
     Array<UInt> nb_cluster_per_proc(nb_proc);
     nb_cluster_per_proc(rank) = nb_cluster;
     comm.allGather(nb_cluster_per_proc);
 
     starting_index = std::accumulate(nb_cluster_per_proc.begin(),
                                      nb_cluster_per_proc.begin() + rank, 0);
 
     UInt global_nb_fragment =
         std::accumulate(nb_cluster_per_proc.begin() + rank,
                         nb_cluster_per_proc.end(), starting_index);
 
     /// create the local to distant cluster pairs with neighbors
     element_synchronizer.synchronizeOnce(*this, _gst_gm_clusters);
 
     /// count total number of pairs
     Array<int> nb_pairs(nb_proc); // This is potentially a bug for more than
     // 2**31 pairs, but due to a all gatherv after
     // it must be int to match MPI interfaces
     nb_pairs(rank) = distant_ids.size();
     comm.allGather(nb_pairs);
 
     UInt total_nb_pairs = std::accumulate(nb_pairs.begin(), nb_pairs.end(), 0);
 
     /// generate pairs global array
     UInt local_pair_index =
         std::accumulate(nb_pairs.storage(), nb_pairs.storage() + rank, 0);
 
     Array<UInt> total_pairs(total_nb_pairs, 2);
 
     for (auto & ids : distant_ids) {
       total_pairs(local_pair_index, 0) = ids.first;
       total_pairs(local_pair_index, 1) = ids.second;
       ++local_pair_index;
     }
 
     /// communicate pairs to all processors
     nb_pairs *= 2;
     comm.allGatherV(total_pairs, nb_pairs);
 
     /// renumber clusters
 
     /// generate fragment list
     std::vector<std::set<UInt>> global_clusters;
     UInt total_nb_cluster = 0;
 
     Array<bool> is_fragment_in_cluster(global_nb_fragment, 1, false);
     std::queue<UInt> fragment_check_list;
 
     while (total_pairs.getSize() != 0) {
       /// create a new cluster
       ++total_nb_cluster;
       global_clusters.resize(total_nb_cluster);
       std::set<UInt> & current_cluster = global_clusters[total_nb_cluster - 1];
 
       UInt first_fragment = total_pairs(0, 0);
       UInt second_fragment = total_pairs(0, 1);
       total_pairs.erase(0);
 
       fragment_check_list.push(first_fragment);
       fragment_check_list.push(second_fragment);
 
       while (!fragment_check_list.empty()) {
         UInt current_fragment = fragment_check_list.front();
 
         UInt * total_pairs_end =
             total_pairs.storage() + total_pairs.getSize() * 2;
 
         UInt * fragment_found =
             std::find(total_pairs.storage(), total_pairs_end, current_fragment);
 
         if (fragment_found != total_pairs_end) {
           UInt position = fragment_found - total_pairs.storage();
           UInt pair = position / 2;
           UInt other_index = (position + 1) % 2;
           fragment_check_list.push(total_pairs(pair, other_index));
           total_pairs.erase(pair);
         } else {
           fragment_check_list.pop();
           current_cluster.insert(current_fragment);
           is_fragment_in_cluster(current_fragment) = true;
         }
       }
     }
 
     /// add to FragmentToCluster all local fragments
     for (UInt c = 0; c < global_nb_fragment; ++c) {
       if (!is_fragment_in_cluster(c)) {
         ++total_nb_cluster;
         global_clusters.resize(total_nb_cluster);
         std::set<UInt> & current_cluster =
             global_clusters[total_nb_cluster - 1];
 
         current_cluster.insert(c);
       }
     }
 
     /// reorganize element groups to match global clusters
     for (UInt c = 0; c < global_clusters.size(); ++c) {
 
       /// create new element group corresponding to current cluster
       std::stringstream sstr;
       sstr << cluster_name_prefix << "_" << c;
       ElementGroup & cluster =
           group_manager.createElementGroup(sstr.str(), element_dimension, true);
 
       std::set<UInt>::iterator it = global_clusters[c].begin();
       std::set<UInt>::iterator end = global_clusters[c].end();
 
       /// append to current element group all fragments that belong to
       /// the same cluster if they exist
       for (; it != end; ++it) {
         Int local_index = *it - starting_index;
 
         if (local_index < 0 || local_index >= Int(nb_cluster))
           continue;
 
         std::stringstream tmp_sstr;
         tmp_sstr << "tmp_" << cluster_name_prefix << "_" << local_index;
         auto eg_it = group_manager.element_group_find(tmp_sstr.str());
 
         AKANTU_DEBUG_ASSERT(eg_it != group_manager.element_group_end(),
                             "Temporary fragment \"" << tmp_sstr.str()
                                                     << "\" not found");
 
         cluster.append(*(eg_it->second));
         group_manager.destroyElementGroup(tmp_sstr.str(), true);
       }
     }
 
     return total_nb_cluster;
   }
 
 private:
   /// functions for parallel communications
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const {
     if (tag == _gst_gm_clusters)
       return elements.getSize() * sizeof(UInt);
 
     return 0;
   }
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const {
     if (tag != _gst_gm_clusters)
       return;
 
     Array<Element>::const_iterator<> el_it = elements.begin();
     Array<Element>::const_iterator<> el_end = elements.end();
 
     for (; el_it != el_end; ++el_it) {
 
       const Element & el = *el_it;
 
       /// for each element pack its global cluster index
       buffer << element_to_fragment(el.type, el.ghost_type)(el.element) +
                     starting_index;
     }
   }
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) {
     if (tag != _gst_gm_clusters)
       return;
 
     Array<Element>::const_iterator<> el_it = elements.begin();
     Array<Element>::const_iterator<> el_end = elements.end();
 
     for (; el_it != el_end; ++el_it) {
       UInt distant_cluster;
 
       buffer >> distant_cluster;
 
       const Element & el = *el_it;
       UInt local_cluster =
           element_to_fragment(el.type, el.ghost_type)(el.element) +
           starting_index;
 
       distant_ids.insert(std::make_pair(local_cluster, distant_cluster));
     }
   }
 
 private:
   GroupManager & group_manager;
   UInt element_dimension;
   std::string cluster_name_prefix;
   ElementTypeMapArray<UInt> & element_to_fragment;
   const ElementSynchronizer & element_synchronizer;
 
   UInt nb_cluster;
   DistantIDs distant_ids;
 
   UInt starting_index;
 };
 
 /* -------------------------------------------------------------------------- */
 /// \todo this function doesn't work in 1D
 UInt GroupManager::createBoundaryGroupFromGeometry() {
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   return createClusters(spatial_dimension - 1, "boundary");
 }
 
+/* -------------------------------------------------------------------------- */
+UInt GroupManager::createClusters(
+    UInt element_dimension, Mesh & mesh_facets, std::string cluster_name_prefix,
+    const GroupManager::ClusteringFilter & filter) {
+  return createClusters(element_dimension, cluster_name_prefix, filter, mesh_facets);
+}
+
+/* -------------------------------------------------------------------------- */
+UInt GroupManager::createClusters(
+    UInt element_dimension, std::string cluster_name_prefix,
+    const GroupManager::ClusteringFilter & filter) {
+  std::unique_ptr<Mesh> mesh_facets;
+  if (!mesh_facets && element_dimension > 0) {
+    MeshAccessor mesh_accessor(const_cast<Mesh &>(mesh));
+    mesh_facets = std::make_unique<Mesh>(mesh.getSpatialDimension(),
+                                         mesh_accessor.getNodesSharedPtr(),
+                                         "mesh_facets_for_clusters");
+
+    mesh_facets->defineMeshParent(mesh);
+
+    MeshUtils::buildAllFacets(mesh, *mesh_facets, element_dimension,
+                              element_dimension - 1);
+  }
+
+  return createClusters(element_dimension, cluster_name_prefix, filter, *mesh_facets);
+}
+
 /* -------------------------------------------------------------------------- */
 //// \todo if needed element list construction can be optimized by
 //// templating the filter class
 UInt GroupManager::createClusters(UInt element_dimension,
                                   std::string cluster_name_prefix,
                                   const GroupManager::ClusteringFilter & filter,
-                                  Mesh * mesh_facets) {
+                                  Mesh & mesh_facets) {
   AKANTU_DEBUG_IN();
 
   UInt nb_proc = StaticCommunicator::getStaticCommunicator().getNbProc();
   std::string tmp_cluster_name_prefix = cluster_name_prefix;
 
   ElementTypeMapArray<UInt> * element_to_fragment = nullptr;
 
   if (nb_proc > 1 && mesh.isDistributed()) {
     element_to_fragment =
         new ElementTypeMapArray<UInt>("element_to_fragment", id, memory_id);
 
-    element_to_fragment->initialize(mesh, _nb_component = 1,
-                                    _spatial_dimension = element_dimension,
-                                    _element_kind = _ek_not_defined,
-                                    _with_nb_element = true);
+    element_to_fragment->initialize(
+        mesh, _nb_component = 1, _spatial_dimension = element_dimension,
+        _element_kind = _ek_not_defined, _with_nb_element = true);
     // mesh.initElementTypeMapArray(*element_to_fragment, 1, element_dimension,
     //                              false, _ek_not_defined, true);
     tmp_cluster_name_prefix = "tmp_" + tmp_cluster_name_prefix;
   }
 
-  /// Get facets
-  bool mesh_facets_created = false;
-
-  if (!mesh_facets && element_dimension > 0) {
-    mesh_facets = new Mesh(mesh.getSpatialDimension(), mesh.getNodes().getID(),
-                           "mesh_facets_for_clusters");
-
-    mesh_facets->defineMeshParent(mesh);
-
-    MeshUtils::buildAllFacets(mesh, *mesh_facets, element_dimension,
-                              element_dimension - 1);
-  }
-
   ElementTypeMapArray<bool> seen_elements("seen_elements", id, memory_id);
   seen_elements.initialize(mesh, _spatial_dimension = element_dimension,
-                            _element_kind = _ek_not_defined,
-                            _with_nb_element = true);
+                           _element_kind = _ek_not_defined,
+                           _with_nb_element = true);
   // mesh.initElementTypeMapArray(seen_elements, 1, element_dimension, false,
   //                              _ek_not_defined, true);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType ghost_type = *gt;
     Element el;
     el.ghost_type = ghost_type;
 
     Mesh::type_iterator type_it =
         mesh.firstType(element_dimension, ghost_type, _ek_not_defined);
     Mesh::type_iterator type_end =
         mesh.lastType(element_dimension, ghost_type, _ek_not_defined);
 
     for (; type_it != type_end; ++type_it) {
       el.type = *type_it;
       el.kind = Mesh::getKind(*type_it);
       UInt nb_element = mesh.getNbElement(*type_it, ghost_type);
       Array<bool> & seen_elements_array = seen_elements(el.type, ghost_type);
 
       for (UInt e = 0; e < nb_element; ++e) {
         el.element = e;
         if (!filter(el))
           seen_elements_array(e) = true;
       }
     }
   }
 
   Array<bool> checked_node(mesh.getNbNodes(), 1, false);
 
   UInt nb_cluster = 0;
 
   /// keep looping until all elements are seen
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType ghost_type = *gt;
     Element uns_el;
     uns_el.ghost_type = ghost_type;
 
     Mesh::type_iterator type_it =
         mesh.firstType(element_dimension, ghost_type, _ek_not_defined);
     Mesh::type_iterator type_end =
         mesh.lastType(element_dimension, ghost_type, _ek_not_defined);
 
     for (; type_it != type_end; ++type_it) {
       uns_el.type = *type_it;
       Array<bool> & seen_elements_vec =
           seen_elements(uns_el.type, uns_el.ghost_type);
 
       for (UInt e = 0; e < seen_elements_vec.getSize(); ++e) {
         // skip elements that have been already seen
         if (seen_elements_vec(e) == true)
           continue;
 
         // set current element
         uns_el.element = e;
         seen_elements_vec(e) = true;
 
         /// create a new cluster
         std::stringstream sstr;
         sstr << tmp_cluster_name_prefix << "_" << nb_cluster;
         ElementGroup & cluster =
             createElementGroup(sstr.str(), element_dimension, true);
         ++nb_cluster;
 
         // point element are cluster by themself
         if (element_dimension == 0) {
           cluster.add(uns_el);
 
           UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(uns_el.type);
           Vector<UInt> connect =
               mesh.getConnectivity(uns_el.type, uns_el.ghost_type)
                   .begin(nb_nodes_per_element)[uns_el.element];
           for (UInt n = 0; n < nb_nodes_per_element; ++n) {
             /// add element's nodes to the cluster
             UInt node = connect[n];
             if (!checked_node(node)) {
               cluster.addNode(node);
               checked_node(node) = true;
             }
           }
 
           continue;
         }
 
         std::queue<Element> element_to_add;
         element_to_add.push(uns_el);
 
         /// keep looping until current cluster is complete (no more
         /// connected elements)
         while (!element_to_add.empty()) {
 
           /// take first element and erase it in the queue
           Element el = element_to_add.front();
           element_to_add.pop();
 
           /// if parallel, store cluster index per element
           if (nb_proc > 1 && mesh.isDistributed())
             (*element_to_fragment)(el.type, el.ghost_type)(el.element) =
                 nb_cluster - 1;
 
           /// add current element to the cluster
           cluster.add(el);
 
           const Array<Element> & element_to_facet =
-              mesh_facets->getSubelementToElement(el.type, el.ghost_type);
+              mesh_facets.getSubelementToElement(el.type, el.ghost_type);
 
           UInt nb_facet_per_element = element_to_facet.getNbComponent();
 
           for (UInt f = 0; f < nb_facet_per_element; ++f) {
             const Element & facet = element_to_facet(el.element, f);
 
             if (facet == ElementNull)
               continue;
 
             const std::vector<Element> & connected_elements =
-                mesh_facets->getElementToSubelement(
+                mesh_facets.getElementToSubelement(
                     facet.type, facet.ghost_type)(facet.element);
 
             for (UInt elem = 0; elem < connected_elements.size(); ++elem) {
               const Element & check_el = connected_elements[elem];
 
               // check if this element has to be skipped
               if (check_el == ElementNull || check_el == el)
                 continue;
 
               Array<bool> & seen_elements_vec_current =
                   seen_elements(check_el.type, check_el.ghost_type);
 
               if (seen_elements_vec_current(check_el.element) == false) {
                 seen_elements_vec_current(check_el.element) = true;
                 element_to_add.push(check_el);
               }
             }
           }
 
           UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
           Vector<UInt> connect = mesh.getConnectivity(el.type, el.ghost_type)
                                      .begin(nb_nodes_per_element)[el.element];
           for (UInt n = 0; n < nb_nodes_per_element; ++n) {
             /// add element's nodes to the cluster
             UInt node = connect[n];
             if (!checked_node(node)) {
               cluster.addNode(node, false);
               checked_node(node) = true;
             }
           }
         }
       }
     }
   }
 
   if (nb_proc > 1 && mesh.isDistributed()) {
     ClusterSynchronizer cluster_synchronizer(
         *this, element_dimension, cluster_name_prefix, *element_to_fragment,
         this->mesh.getElementSynchronizer(), nb_cluster);
     nb_cluster = cluster_synchronizer.synchronize();
     delete element_to_fragment;
   }
 
-  if (mesh_facets_created)
-    delete mesh_facets;
-
   if (mesh.isDistributed())
     this->synchronizeGroupNames();
 
   AKANTU_DEBUG_OUT();
   return nb_cluster;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void GroupManager::createGroupsFromMeshData(const std::string & dataset_name) {
   std::set<std::string> group_names;
   const ElementTypeMapArray<T> & datas = mesh.getData<T>(dataset_name);
   typedef typename ElementTypeMapArray<T>::type_iterator type_iterator;
 
   std::map<std::string, UInt> group_dim;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     type_iterator type_it = datas.firstType(_all_dimensions, *gt);
     type_iterator type_end = datas.lastType(_all_dimensions, *gt);
     for (; type_it != type_end; ++type_it) {
       const Array<T> & dataset = datas(*type_it, *gt);
       UInt nb_element = mesh.getNbElement(*type_it, *gt);
       AKANTU_DEBUG_ASSERT(dataset.getSize() == nb_element,
                           "Not the same number of elements ("
                               << *type_it << ":" << *gt
                               << ") in the map from MeshData ("
                               << dataset.getSize() << ") " << dataset_name
                               << " and in the mesh (" << nb_element << ")!");
       for (UInt e(0); e < nb_element; ++e) {
         std::stringstream sstr;
         sstr << dataset(e);
         std::string gname = sstr.str();
         group_names.insert(gname);
 
         std::map<std::string, UInt>::iterator it = group_dim.find(gname);
         if (it == group_dim.end()) {
           group_dim[gname] = mesh.getSpatialDimension(*type_it);
         } else {
           it->second = std::max(it->second, mesh.getSpatialDimension(*type_it));
         }
       }
     }
   }
 
   std::set<std::string>::iterator git = group_names.begin();
   std::set<std::string>::iterator gend = group_names.end();
   for (; git != gend; ++git)
     createElementGroup(*git, group_dim[*git]);
 
   if (mesh.isDistributed())
     this->synchronizeGroupNames();
 
   Element el;
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     el.ghost_type = *gt;
 
     type_iterator type_it = datas.firstType(_all_dimensions, *gt);
     type_iterator type_end = datas.lastType(_all_dimensions, *gt);
     for (; type_it != type_end; ++type_it) {
       el.type = *type_it;
 
       const Array<T> & dataset = datas(*type_it, *gt);
       UInt nb_element = mesh.getNbElement(*type_it, *gt);
       AKANTU_DEBUG_ASSERT(dataset.getSize() == nb_element,
                           "Not the same number of elements in the map from "
                           "MeshData and in the mesh!");
 
       UInt nb_nodes_per_element = mesh.getNbNodesPerElement(el.type);
 
       Array<UInt>::const_iterator<Vector<UInt>> cit =
           mesh.getConnectivity(*type_it, *gt).begin(nb_nodes_per_element);
 
       for (UInt e(0); e < nb_element; ++e, ++cit) {
         el.element = e;
         std::stringstream sstr;
         sstr << dataset(e);
         ElementGroup & group = getElementGroup(sstr.str());
         group.add(el, false, false);
 
         const Vector<UInt> & connect = *cit;
         for (UInt n = 0; n < nb_nodes_per_element; ++n) {
           UInt node = connect[n];
           group.addNode(node, false);
         }
       }
     }
   }
 
   git = group_names.begin();
   for (; git != gend; ++git) {
     getElementGroup(*git).optimize();
   }
 }
 
 template void GroupManager::createGroupsFromMeshData<std::string>(
     const std::string & dataset_name);
 template void
 GroupManager::createGroupsFromMeshData<UInt>(const std::string & dataset_name);
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::createElementGroupFromNodeGroup(
     const std::string & name, const std::string & node_group_name,
     UInt dimension) {
   NodeGroup & node_group = getNodeGroup(node_group_name);
   ElementGroup & group = createElementGroup(name, dimension, node_group);
 
   group.fillFromNodeGroup();
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "GroupManager [" << std::endl;
 
   std::set<std::string> node_group_seen;
   for (const_element_group_iterator it(element_group_begin());
        it != element_group_end(); ++it) {
     it->second->printself(stream, indent + 1);
     node_group_seen.insert(it->second->getNodeGroup().getName());
   }
 
   for (const_node_group_iterator it(node_group_begin()); it != node_group_end();
        ++it) {
     if (node_group_seen.find(it->second->getName()) == node_group_seen.end())
       it->second->printself(stream, indent + 1);
   }
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 UInt GroupManager::getNbElementGroups(UInt dimension) const {
   if (dimension == _all_dimensions)
     return element_groups.size();
 
   ElementGroups::const_iterator it = element_groups.begin();
   ElementGroups::const_iterator end = element_groups.end();
   UInt count = 0;
   for (; it != end; ++it)
     count += (it->second->getDimension() == dimension);
   return count;
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::checkAndAddGroups(CommunicationBuffer & buffer) {
   AKANTU_DEBUG_IN();
 
   UInt nb_node_group;
   buffer >> nb_node_group;
   AKANTU_DEBUG_INFO("Received " << nb_node_group << " node group names");
 
   for (UInt ng = 0; ng < nb_node_group; ++ng) {
     std::string node_group_name;
     buffer >> node_group_name;
 
     if (node_groups.find(node_group_name) == node_groups.end()) {
       this->createNodeGroup(node_group_name);
     }
 
     AKANTU_DEBUG_INFO("Received node goup name: " << node_group_name);
   }
 
   UInt nb_element_group;
   buffer >> nb_element_group;
   AKANTU_DEBUG_INFO("Received " << nb_element_group << " element group names");
   for (UInt eg = 0; eg < nb_element_group; ++eg) {
     std::string element_group_name;
     buffer >> element_group_name;
     std::string node_group_name;
     buffer >> node_group_name;
     UInt dim;
     buffer >> dim;
 
     AKANTU_DEBUG_INFO("Received element group name: "
                       << element_group_name << " corresponding to a "
                       << Int(dim) << "D group with node group "
                       << node_group_name);
 
     NodeGroup & node_group = *node_groups[node_group_name];
 
     if (element_groups.find(element_group_name) == element_groups.end()) {
       this->createElementGroup(element_group_name, dim, node_group);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::fillBufferWithGroupNames(
     DynamicCommunicationBuffer & comm_buffer) const {
   AKANTU_DEBUG_IN();
 
   // packing node group names;
   UInt nb_groups = this->node_groups.size();
   comm_buffer << nb_groups;
   AKANTU_DEBUG_INFO("Sending " << nb_groups << " node group names");
 
   NodeGroups::const_iterator nnames_it = node_groups.begin();
   NodeGroups::const_iterator nnames_end = node_groups.end();
   for (; nnames_it != nnames_end; ++nnames_it) {
     std::string node_group_name = nnames_it->first;
     comm_buffer << node_group_name;
     AKANTU_DEBUG_INFO("Sending node goupe name: " << node_group_name);
   }
 
   // packing element group names with there associated node group name
   nb_groups = this->element_groups.size();
   comm_buffer << nb_groups;
   AKANTU_DEBUG_INFO("Sending " << nb_groups << " element group names");
   ElementGroups::const_iterator gnames_it = this->element_groups.begin();
   ElementGroups::const_iterator gnames_end = this->element_groups.end();
   for (; gnames_it != gnames_end; ++gnames_it) {
     ElementGroup & element_group = *(gnames_it->second);
     std::string element_group_name = gnames_it->first;
     std::string node_group_name = element_group.getNodeGroup().getName();
     UInt dim = element_group.getDimension();
 
     comm_buffer << element_group_name;
     comm_buffer << node_group_name;
     comm_buffer << dim;
 
     AKANTU_DEBUG_INFO("Sending element group name: "
                       << element_group_name << " corresponding to a "
                       << Int(dim) << "D group with the node group "
                       << node_group_name);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void GroupManager::synchronizeGroupNames() {
   AKANTU_DEBUG_IN();
 
   StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
   Int nb_proc = comm.getNbProc();
   Int my_rank = comm.whoAmI();
 
   if (nb_proc == 1)
     return;
 
   if (my_rank == 0) {
     for (Int p = 1; p < nb_proc; ++p) {
       CommunicationStatus status;
       comm.probe<char>(p, p, status);
       AKANTU_DEBUG_INFO("Got " << printMemorySize<char>(status.getSize())
                                << " from proc " << p);
 
       CommunicationBuffer recv_buffer(status.getSize());
       comm.receive(recv_buffer, p, p);
 
       this->checkAndAddGroups(recv_buffer);
     }
 
     DynamicCommunicationBuffer comm_buffer;
     this->fillBufferWithGroupNames(comm_buffer);
 
     UInt buffer_size = comm_buffer.getSize();
 
     comm.broadcast(buffer_size, 0);
 
     AKANTU_DEBUG_INFO("Initiating broadcast with "
                       << printMemorySize<char>(comm_buffer.getSize()));
     comm.broadcast(comm_buffer, 0);
 
   } else {
     DynamicCommunicationBuffer comm_buffer;
     this->fillBufferWithGroupNames(comm_buffer);
 
     AKANTU_DEBUG_INFO("Sending " << printMemorySize<char>(comm_buffer.getSize())
                                  << " to proc " << 0);
     comm.send(comm_buffer, 0, my_rank);
 
     UInt buffer_size = 0;
     comm.broadcast(buffer_size, 0);
 
     AKANTU_DEBUG_INFO("Receiving broadcast with "
                       << printMemorySize<char>(comm_buffer.getSize()));
     CommunicationBuffer recv_buffer(buffer_size);
     comm.broadcast(recv_buffer, 0);
 
     this->checkAndAddGroups(recv_buffer);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 const ElementGroup &
 GroupManager::getElementGroup(const std::string & name) const {
   const_element_group_iterator it = element_group_find(name);
   if (it == element_group_end()) {
     AKANTU_EXCEPTION("There are no element groups named "
                      << name << " associated to the group manager: " << id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 ElementGroup & GroupManager::getElementGroup(const std::string & name) {
   element_group_iterator it = element_group_find(name);
   if (it == element_group_end()) {
     AKANTU_EXCEPTION("There are no element groups named "
                      << name << " associated to the group manager: " << id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 const NodeGroup & GroupManager::getNodeGroup(const std::string & name) const {
   const_node_group_iterator it = node_group_find(name);
   if (it == node_group_end()) {
     AKANTU_EXCEPTION("There are no node groups named "
                      << name << " associated to the group manager: " << id);
   }
 
   return *(it->second);
 }
 
 /* -------------------------------------------------------------------------- */
 NodeGroup & GroupManager::getNodeGroup(const std::string & name) {
   node_group_iterator it = node_group_find(name);
   if (it == node_group_end()) {
     AKANTU_EXCEPTION("There are no node groups named "
                      << name << " associated to the group manager: " << id);
   }
 
   return *(it->second);
 }
 
 } // namespace akantu
diff --git a/src/mesh/group_manager.hh b/src/mesh/group_manager.hh
index d4b7dc1a3..731f71f2c 100644
--- a/src/mesh/group_manager.hh
+++ b/src/mesh/group_manager.hh
@@ -1,294 +1,304 @@
 /**
  * @file   group_manager.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@gmail.com>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Nov 13 2013
  * @date last modification: Mon Nov 16 2015
  *
  * @brief  Stores information relevent to the notion of element and nodes
  *groups.
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_GROUP_MANAGER_HH__
 #define __AKANTU_GROUP_MANAGER_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "element_type_map.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class ElementGroup;
 class NodeGroup;
 class Mesh;
 class Element;
 class ElementSynchronizer;
 template <bool> class CommunicationBufferTemplated;
 namespace dumper {
   class Field;
 }
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class GroupManager {
   /* ------------------------------------------------------------------------ */
   /* Typedefs                                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   using ElementGroups = std::map<std::string, ElementGroup *>;
   using NodeGroups = std::map<std::string, NodeGroup *>;
 
 public:
   typedef std::set<ElementType> GroupManagerTypeSet;
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   GroupManager(const Mesh & mesh, const ID & id = "group_manager",
                const MemoryID & memory_id = 0);
   virtual ~GroupManager();
 
   /* ------------------------------------------------------------------------ */
   /* Groups iterators                                                         */
   /* ------------------------------------------------------------------------ */
 public:
   typedef NodeGroups::iterator node_group_iterator;
   typedef ElementGroups::iterator element_group_iterator;
 
   typedef NodeGroups::const_iterator const_node_group_iterator;
   typedef ElementGroups::const_iterator const_element_group_iterator;
 
 #ifndef SWIG
 #define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(group_type, function,    \
                                                       param_in, param_out)     \
   inline BOOST_PP_CAT(BOOST_PP_CAT(const_, group_type), _iterator)             \
       BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) const {    \
     return BOOST_PP_CAT(group_type, s).function(param_out);                    \
   };                                                                           \
                                                                                \
   inline BOOST_PP_CAT(group_type, _iterator)                                   \
       BOOST_PP_CAT(BOOST_PP_CAT(group_type, _), function)(param_in) {          \
     return BOOST_PP_CAT(group_type, s).function(param_out);                    \
   }
 
 #define AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(group_type, function) \
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(                               \
       group_type, function, BOOST_PP_EMPTY(), BOOST_PP_EMPTY())
 
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, begin);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(node_group, end);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, begin);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION_NP(element_group, end);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(element_group, find,
                                                 const std::string & name, name);
   AKANTU_GROUP_MANAGER_DEFINE_ITERATOR_FUNCTION(node_group, find,
                                                 const std::string & name, name);
 #endif
 
   /* ------------------------------------------------------------------------ */
   /* Clustering filter                                                        */
   /* ------------------------------------------------------------------------ */
 public:
   class ClusteringFilter {
   public:
     virtual bool operator()(const Element &) const { return true; }
   };
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// create an empty node group
   NodeGroup & createNodeGroup(const std::string & group_name,
                               bool replace_group = false);
 
   /// create a node group from another node group but filtered
   template <typename T>
   NodeGroup & createFilteredNodeGroup(const std::string & group_name,
                                       const NodeGroup & node_group, T & filter);
 
   /// destroy a node group
   void destroyNodeGroup(const std::string & group_name);
 
   /// create an element group and the associated node group
   ElementGroup & createElementGroup(const std::string & group_name,
                                     UInt dimension = _all_dimensions,
                                     bool replace_group = false);
 
   /// create an element group from another element group but filtered
   template <typename T>
   ElementGroup &
   createFilteredElementGroup(const std::string & group_name, UInt dimension,
                              const NodeGroup & node_group, T & filter);
 
   /// destroy an element group and the associated node group
   void destroyElementGroup(const std::string & group_name,
                            bool destroy_node_group = false);
 
   /// destroy all element groups and the associated node groups
   void destroyAllElementGroups(bool destroy_node_groups = false);
 
   /// create a element group using an existing node group
   ElementGroup & createElementGroup(const std::string & group_name,
                                     UInt dimension, NodeGroup & node_group);
 
   /// create groups based on values stored in a given mesh data
   template <typename T>
   void createGroupsFromMeshData(const std::string & dataset_name);
 
   /// create boundaries group by a clustering algorithm \todo extend to parallel
   UInt createBoundaryGroupFromGeometry();
 
+  /// create element clusters for a given dimension
+  UInt createClusters(UInt element_dimension, Mesh & mesh_facets,
+                      std::string cluster_name_prefix = "cluster",
+                      const ClusteringFilter & filter = ClusteringFilter());
+
   /// create element clusters for a given dimension
   UInt createClusters(UInt element_dimension,
                       std::string cluster_name_prefix = "cluster",
-                      const ClusteringFilter & filter = ClusteringFilter(),
-                      Mesh * mesh_facets = nullptr);
+                      const ClusteringFilter & filter = ClusteringFilter());
 
+private:
+  /// create element clusters for a given dimension
+  UInt createClusters(UInt element_dimension, std::string cluster_name_prefix,
+                      const ClusteringFilter & filter, Mesh & mesh_facets);
+
+public:
   /// Create an ElementGroup based on a NodeGroup
   void createElementGroupFromNodeGroup(const std::string & name,
                                        const std::string & node_group,
                                        UInt dimension = _all_dimensions);
 
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// this function insure that the group names are present on all processors
   /// /!\ it is a SMP call
   void synchronizeGroupNames();
 
 /// register an elemental field to the given group name (overloading for
 /// ElementalPartionField)
 #ifndef SWIG
   template <typename T, template <bool> class dump_type>
   dumper::Field * createElementalField(
       const ElementTypeMapArray<T> & field, const std::string & group_name,
       UInt spatial_dimension, const ElementKind & kind,
       ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
 
   /// register an elemental field to the given group name (overloading for
   /// ElementalField)
   template <typename T, template <class> class ret_type,
             template <class, template <class> class, bool> class dump_type>
   dumper::Field * createElementalField(
       const ElementTypeMapArray<T> & field, const std::string & group_name,
       UInt spatial_dimension, const ElementKind & kind,
       ElementTypeMap<UInt> nb_data_per_elem = ElementTypeMap<UInt>());
 
   /// register an elemental field to the given group name (overloading for
   /// MaterialInternalField)
   template <typename T,
             /// type of InternalMaterialField
             template <typename, bool filtered> class dump_type>
   dumper::Field * createElementalField(const ElementTypeMapArray<T> & field,
                                        const std::string & group_name,
                                        UInt spatial_dimension,
                                        const ElementKind & kind,
                                        ElementTypeMap<UInt> nb_data_per_elem);
 
   template <typename type, bool flag, template <class, bool> class ftype>
   dumper::Field * createNodalField(const ftype<type, flag> * field,
                                    const std::string & group_name,
                                    UInt padding_size = 0);
 
   template <typename type, bool flag, template <class, bool> class ftype>
   dumper::Field * createStridedNodalField(const ftype<type, flag> * field,
                                           const std::string & group_name,
                                           UInt size, UInt stride,
                                           UInt padding_size);
 
 protected:
   /// fill a buffer with all the group names
   void fillBufferWithGroupNames(
       CommunicationBufferTemplated<false> & comm_buffer) const;
 
   /// take a buffer and create the missing groups localy
   void checkAndAddGroups(CommunicationBufferTemplated<true> & buffer);
 
   /// register an elemental field to the given group name
   template <class dump_type, typename field_type>
   inline dumper::Field *
   createElementalField(const field_type & field, const std::string & group_name,
                        UInt spatial_dimension, const ElementKind & kind,
                        ElementTypeMap<UInt> nb_data_per_elem);
 
   /// register an elemental field to the given group name
   template <class dump_type, typename field_type>
   inline dumper::Field *
   createElementalFilteredField(const field_type & field,
                                const std::string & group_name,
                                UInt spatial_dimension, const ElementKind & kind,
                                ElementTypeMap<UInt> nb_data_per_elem);
 #endif
 
   /* ------------------------------------------------------------------------ */
   /* Accessor                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   const ElementGroup & getElementGroup(const std::string & name) const;
   const NodeGroup & getNodeGroup(const std::string & name) const;
 
   ElementGroup & getElementGroup(const std::string & name);
   NodeGroup & getNodeGroup(const std::string & name);
 
   UInt getNbElementGroups(UInt dimension = _all_dimensions) const;
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// id to create element and node groups
   ID id;
   /// memory_id to create element and node groups
   MemoryID memory_id;
 
   /// list of the node groups managed
   NodeGroups node_groups;
 
   /// list of the element groups managed
   ElementGroups element_groups;
 
   /// Mesh to which the element belongs
   const Mesh & mesh;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const GroupManager & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #endif /* __AKANTU_GROUP_MANAGER_HH__ */
diff --git a/src/mesh/mesh.cc b/src/mesh/mesh.cc
index 795934832..c06e28f3d 100644
--- a/src/mesh/mesh.cc
+++ b/src/mesh/mesh.cc
@@ -1,523 +1,429 @@
 /**
  * @file   mesh.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Jan 22 2016
  *
  * @brief  class handling meshes
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <sstream>
 
 #include "aka_config.hh"
 
 /* -------------------------------------------------------------------------- */
 #include "element_class.hh"
 #include "group_manager_inline_impl.cc"
 #include "mesh.hh"
 #include "mesh_io.hh"
 /* -------------------------------------------------------------------------- */
 #include "element_synchronizer.hh"
 #include "mesh_utils_distribution.hh"
 #include "node_synchronizer.hh"
 #include "static_communicator.hh"
 /* -------------------------------------------------------------------------- */
 #ifdef AKANTU_USE_IOHELPER
 #include "dumper_field.hh"
 #include "dumper_internal_material_field.hh"
 #endif
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 const Element ElementNull(_not_defined, 0);
 
 /* -------------------------------------------------------------------------- */
 void Element::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
   stream << space << "Element [" << type << ", " << element << ", "
          << ghost_type << "]";
 }
 
 /* -------------------------------------------------------------------------- */
 Mesh::Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id,
            StaticCommunicator & communicator)
     : Memory(id, memory_id),
-      GroupManager(*this, id + ":group_manager", memory_id), nodes(NULL),
-      nodes_global_ids(nullptr), nodes_type(0, 1, id + ":nodes_type"),
-      nb_global_nodes(0), created_nodes(true),
+      GroupManager(*this, id + ":group_manager", memory_id),
+      nodes_type(0, 1, id + ":nodes_type"),
       connectivities("connectivities", id, memory_id),
       normals("normals", id, memory_id), spatial_dimension(spatial_dimension),
-      types_offsets(Array<UInt>((UInt)_max_element_type + 1, 1)),
-      ghost_types_offsets(Array<UInt>((UInt)_max_element_type + 1, 1)),
       lower_bounds(spatial_dimension, 0.), upper_bounds(spatial_dimension, 0.),
       size(spatial_dimension, 0.), local_lower_bounds(spatial_dimension, 0.),
       local_upper_bounds(spatial_dimension, 0.),
-      mesh_data("mesh_data", id, memory_id), mesh_facets(nullptr),
-      mesh_parent(nullptr), is_mesh_facets(false), is_distributed(false),
-      communicator(&communicator), element_synchronizer(nullptr),
-      node_synchronizer(nullptr) {
+      mesh_data("mesh_data", id, memory_id), communicator(&communicator) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Mesh::Mesh(UInt spatial_dimension, StaticCommunicator & communicator,
            const ID & id, const MemoryID & memory_id)
     : Mesh(spatial_dimension, id, memory_id, communicator) {
   AKANTU_DEBUG_IN();
+
   this->nodes =
-      &(alloc<Real>(id + ":coordinates", memory_id, spatial_dimension));
+      std::make_shared<Array<Real>>(0, spatial_dimension, id + ":coordinates");
+
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 Mesh::Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id)
     : Mesh(spatial_dimension, StaticCommunicator::getStaticCommunicator(), id,
            memory_id) {}
 
-/* -------------------------------------------------------------------------- */
-Mesh::Mesh(UInt spatial_dimension, const ID & nodes_id, const ID & id,
-           const MemoryID & memory_id)
-    : Mesh(spatial_dimension, id, memory_id,
-           StaticCommunicator::getStaticCommunicator()) {
-  this->nodes = &(this->getArray<Real>(nodes_id));
-  this->nb_global_nodes = this->nodes->getSize();
-  this->computeBoundingBox();
-}
+// /* --------------------------------------------------------------------------
+// */ Mesh::Mesh(UInt spatial_dimension, const ID & nodes_id, const ID & id,
+//            const MemoryID & memory_id)
+//     : Mesh(spatial_dimension, id, memory_id,
+//            StaticCommunicator::getStaticCommunicator()) {
+//   this->nodes = &(this->getArray<Real>(nodes_id));
+//   this->nb_global_nodes = this->nodes->getSize();
+//   this->computeBoundingBox();
+// }
 
 /* -------------------------------------------------------------------------- */
-Mesh::Mesh(UInt spatial_dimension, Array<Real> & nodes, const ID & id,
-           const MemoryID & memory_id)
+Mesh::Mesh(UInt spatial_dimension, std::shared_ptr<Array<Real>> nodes,
+           const ID & id, const MemoryID & memory_id)
     : Mesh(spatial_dimension, id, memory_id,
            StaticCommunicator::getStaticCommunicator()) {
-  this->nodes = &nodes;
+  this->nodes = nodes;
   this->nb_global_nodes = this->nodes->getSize();
   this->computeBoundingBox();
 }
 
 /* -------------------------------------------------------------------------- */
 Mesh & Mesh::initMeshFacets(const ID & id) {
   AKANTU_DEBUG_IN();
 
   if (!mesh_facets) {
-    mesh_facets = new Mesh(spatial_dimension, *(this->nodes),
-                           getID() + ":" + id, getMemoryID());
+    mesh_facets = std::make_unique<Mesh>(spatial_dimension, this->nodes,
+                                         getID() + ":" + id, getMemoryID());
 
     mesh_facets->mesh_parent = this;
     mesh_facets->is_mesh_facets = true;
   }
 
   AKANTU_DEBUG_OUT();
   return *mesh_facets;
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::defineMeshParent(const Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   this->mesh_parent = &mesh;
   this->is_mesh_facets = true;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-Mesh::~Mesh() {
-  AKANTU_DEBUG_IN();
-
-  delete mesh_facets;
-
-  delete element_synchronizer;
-  delete node_synchronizer;
-
-  AKANTU_DEBUG_OUT();
-}
+Mesh::~Mesh() = default;
 
 /* -------------------------------------------------------------------------- */
 void Mesh::read(const std::string & filename, const MeshIOType & mesh_io_type) {
   MeshIO mesh_io;
   mesh_io.read(filename, *this, mesh_io_type);
 
   type_iterator it =
       this->firstType(spatial_dimension, _not_ghost, _ek_not_defined);
   type_iterator last =
       this->lastType(spatial_dimension, _not_ghost, _ek_not_defined);
   if (it == last)
     AKANTU_EXCEPTION(
         "The mesh contained in the file "
         << filename << " does not seem to be of the good dimension."
         << " No element of dimension " << spatial_dimension << " where read.");
+
+  this->computeBoundingBox();
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::write(const std::string & filename,
                  const MeshIOType & mesh_io_type) {
   MeshIO mesh_io;
   mesh_io.write(filename, *this, mesh_io_type);
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "Mesh [" << std::endl;
   stream << space << " + id                : " << getID() << std::endl;
   stream << space << " + spatial dimension : " << this->spatial_dimension
          << std::endl;
   stream << space << " + nodes [" << std::endl;
   nodes->printself(stream, indent + 2);
   stream << space << " + connectivities [" << std::endl;
   connectivities.printself(stream, indent + 2);
   stream << space << " ]" << std::endl;
 
   GroupManager::printself(stream, indent + 1);
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::computeBoundingBox() {
   AKANTU_DEBUG_IN();
   for (UInt k = 0; k < spatial_dimension; ++k) {
     local_lower_bounds(k) = std::numeric_limits<double>::max();
     local_upper_bounds(k) = -std::numeric_limits<double>::max();
   }
 
   for (UInt i = 0; i < nodes->getSize(); ++i) {
     //    if(!isPureGhostNode(i))
     for (UInt k = 0; k < spatial_dimension; ++k) {
       local_lower_bounds(k) = std::min(local_lower_bounds[k], (*nodes)(i, k));
       local_upper_bounds(k) = std::max(local_upper_bounds[k], (*nodes)(i, k));
     }
   }
 
   if (this->is_distributed) {
     StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
 
     Matrix<Real> reduce_bounds(spatial_dimension, 2);
     for (UInt k = 0; k < spatial_dimension; ++k) {
       reduce_bounds(k, 0) = local_lower_bounds(k);
       reduce_bounds(k, 1) = -local_upper_bounds(k);
     }
 
     comm.allReduce(reduce_bounds, _so_min);
 
     for (UInt k = 0; k < spatial_dimension; ++k) {
       lower_bounds(k) = reduce_bounds(k, 0);
       upper_bounds(k) = -reduce_bounds(k, 1);
     }
   } else {
     this->lower_bounds = this->local_lower_bounds;
     this->upper_bounds = this->local_upper_bounds;
   }
 
   size = upper_bounds - lower_bounds;
 
   AKANTU_DEBUG_OUT();
 }
 
-// /* --------------------------------------------------------------------------
-// */ template <typename T> void
-// Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
-//                                    UInt nb_component, UInt dim, GhostType gt,
-//                                    const T & default_value,
-//                                    const bool &
-//                                    flag_nb_node_per_elem_multiply,
-//                                    ElementKind element_kind,
-//                                    bool size_to_nb_element) const {
-//   AKANTU_DEBUG_IN();
-
-//   for (auto type : elementTypes(dim, gt, element_kind)) {
-//     // determines the number of component
-//     UInt nb_comp = nb_component;
-//     if (flag_nb_node_per_elem_multiply)
-//       nb_comp *= Mesh::getNbNodesPerElement(type);
-
-//     // determines the size
-//     UInt size = 0;
-//     if (size_to_nb_element)
-//       size = this->getNbElement(type, gt);
-
-//     // allocate
-//     if (not vect.exists(type, gt))
-//       vect.alloc(size, nb_comp, type, gt, default_value);
-//   }
-//   AKANTU_DEBUG_OUT();
-// }
-
-// /* --------------------------------------------------------------------------
-// */ template <typename T> void
-// Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
-//                                    UInt nb_component, UInt dim,
-//                                    const bool &
-//                                    flag_nb_node_per_elem_multiply,
-//                                    ElementKind element_kind,
-//                                    bool size_to_nb_element) const {
-//   AKANTU_DEBUG_IN();
-
-//   for (auto ghost_type : ghost_types) {
-//     this->initElementTypeMapArray(vect, nb_component, dim, ghost_types,
-//                                   flag_nb_node_per_elem_multiply,
-//                                   element_kind, size_to_nb_element);
-//   }
-
-//   AKANTU_DEBUG_OUT();
-// }
-
-// /* --------------------------------------------------------------------------
-// */ template <typename T> void
-// Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
-//                                    UInt nb_component, UInt dim, GhostType gt,
-//                                    const bool &
-//                                    flag_nb_node_per_elem_multiply,
-//                                    ElementKind element_kind,
-//                                    bool size_to_nb_element) const {
-//   AKANTU_DEBUG_IN();
-
-//   this->initElementTypeMapArray(vect, nb_component, dim, gt, T(),
-//                                 flag_nb_node_per_elem_multiply, element_kind,
-//                                 size_to_nb_element);
-
-//   AKANTU_DEBUG_OUT();
-// }
-
-// /* --------------------------------------------------------------------------
-// */ template <typename T> void
-// Mesh::initElementTypeMapArray(ElementTypeMapArray<T> & vect,
-//                                    UInt nb_component, UInt dim, GhostType gt,
-//                                    const T & default_value,
-//                                    const bool &
-//                                    flag_nb_node_per_elem_multiply,
-//                                    ElementKind element_kind,
-//                                    bool size_to_nb_element) const {
-//   AKANTU_DEBUG_IN();
-
-//   for (auto type : elementTypes(dim, gt, element_kind)) {
-//     // determines the number of component
-//     UInt nb_comp = nb_component;
-//     if (flag_nb_node_per_elem_multiply)
-//       nb_comp *= Mesh::getNbNodesPerElement(type);
-
-//     // determines the size
-//     UInt size = 0;
-//     if (size_to_nb_element)
-//       size = this->getNbElement(type, gt);
-
-//     // allocate
-//     if (not vect.exists(type, gt))
-//       vect.alloc(size, nb_comp, type, gt, default_value);
-//   }
-//   AKANTU_DEBUG_OUT();
-// }
-
-// /* --------------------------------------------------------------------------
-// */
-/*
-#define AKANTU_INSTANTIATE_INIT(type)                                   \
-   template void Mesh::initElementTypeMapArray<type>( \
-       ElementTypeMapArray<type> & vect, UInt nb_component, UInt dim, \
-       const bool & flag_nb_elem_multiply, ElementKind element_kind, \
-       bool size_to_nb_element) const; \
-   template void Mesh::initElementTypeMapArray<type>( \
-       ElementTypeMapArray<type> & vect, UInt nb_component, UInt dim, \
-       GhostType gt, const bool & flag_nb_elem_multiply, \
-       ElementKind element_kind, bool size_to_nb_element) const; \
-   template void Mesh::initElementTypeMapArray<type>( \
-       ElementTypeMapArray<type> & vect, UInt nb_component, UInt dim, \
-       GhostType gt, const type & default_value, \
-       const bool & flag_nb_elem_multiply, ElementKind element_kind, \ bool
-size_to_nb_element) const
-*/
-// AKANTU_INSTANTIATE_INIT(Real);
-// AKANTU_INSTANTIATE_INIT(UInt);
-// AKANTU_INSTANTIATE_INIT(Int);
-// AKANTU_INSTANTIATE_INIT(bool);
-
 /* -------------------------------------------------------------------------- */
 void Mesh::initNormals() {
   normals.initialize(*this, _nb_component = spatial_dimension,
                      _spatial_dimension = spatial_dimension,
                      _element_kind = _ek_not_defined);
-  // this->initElementTypeMapArray(normals, spatial_dimension,
-  // spatial_dimension,
-  //                               false, _ek_not_defined);
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::getGlobalConnectivity(
     ElementTypeMapArray<UInt> & global_connectivity, UInt dimension,
     GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   for (auto type : elementTypes(dimension, ghost_type)) {
-    Array<UInt> & local_conn = connectivities(type, ghost_type);
-    Array<UInt> & g_connectivity = global_connectivity(type, ghost_type);
-
-    if (!nodes_global_ids)
-      nodes_global_ids = mesh_parent->nodes_global_ids;
-
-    UInt * local_c = local_conn.storage();
-    UInt * global_c = g_connectivity.storage();
-
-    UInt nb_terms = local_conn.getSize() * local_conn.getNbComponent();
-
-    for (UInt i = 0; i < nb_terms; ++i, ++local_c, ++global_c)
-      *global_c = (*nodes_global_ids)(*local_c);
+    auto & local_conn = connectivities(type, ghost_type);
+    auto & g_connectivity = global_connectivity(type, ghost_type);
+
+    UInt nb_nodes = local_conn.getSize() * local_conn.getNbComponent();
+
+    if (!nodes_global_ids && is_mesh_facets) {
+      std::transform(
+          local_conn.begin_reinterpret(nb_nodes),
+          local_conn.end_reinterpret(nb_nodes),
+          g_connectivity.begin_reinterpret(nb_nodes),
+          [& node_ids = *mesh_parent->nodes_global_ids](UInt l)->UInt {
+            return node_ids(l);
+          });
+    } else {
+      std::transform(local_conn.begin_reinterpret(nb_nodes),
+                     local_conn.end_reinterpret(nb_nodes),
+                     g_connectivity.begin_reinterpret(nb_nodes),
+                     [& node_ids = *nodes_global_ids](UInt l)->UInt {
+                       return node_ids(l);
+                     });
+    }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-
 DumperIOHelper & Mesh::getGroupDumper(const std::string & dumper_name,
                                       const std::string & group_name) {
-
   if (group_name == "all")
     return this->getDumper(dumper_name);
   else
     return element_groups[group_name]->getDumper(dumper_name);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 ElementTypeMap<UInt> Mesh::getNbDataPerElem(ElementTypeMapArray<T> & arrays,
                                             const ElementKind & element_kind) {
-
   ElementTypeMap<UInt> nb_data_per_elem;
 
   for (auto type : elementTypes(spatial_dimension, _not_ghost, element_kind)) {
     UInt nb_elements = this->getNbElement(type);
     auto & array = arrays(type);
 
     nb_data_per_elem(type) = array.getNbComponent() * array.getSize();
     nb_data_per_elem(type) /= nb_elements;
   }
 
   return nb_data_per_elem;
 }
 
 /* -------------------------------------------------------------------------- */
-
 template ElementTypeMap<UInt>
 Mesh::getNbDataPerElem(ElementTypeMapArray<Real> & array,
                        const ElementKind & element_kind);
 
 template ElementTypeMap<UInt>
 Mesh::getNbDataPerElem(ElementTypeMapArray<UInt> & array,
                        const ElementKind & element_kind);
 
 /* -------------------------------------------------------------------------- */
-
 #ifdef AKANTU_USE_IOHELPER
-
 template <typename T>
 dumper::Field *
 Mesh::createFieldFromAttachedData(const std::string & field_id,
                                   const std::string & group_name,
                                   const ElementKind & element_kind) {
 
   dumper::Field * field = nullptr;
   ElementTypeMapArray<T> * internal = nullptr;
   try {
     internal = &(this->getData<T>(field_id));
   } catch (...) {
     return nullptr;
   }
 
   ElementTypeMap<UInt> nb_data_per_elem =
       this->getNbDataPerElem(*internal, element_kind);
 
   field = this->createElementalField<T, dumper::InternalMaterialField>(
       *internal, group_name, this->spatial_dimension, element_kind,
       nb_data_per_elem);
 
   return field;
 }
 
 template dumper::Field *
 Mesh::createFieldFromAttachedData<Real>(const std::string & field_id,
                                         const std::string & group_name,
                                         const ElementKind & element_kind);
 
 template dumper::Field *
 Mesh::createFieldFromAttachedData<UInt>(const std::string & field_id,
                                         const std::string & group_name,
                                         const ElementKind & element_kind);
-
 #endif
 
 /* -------------------------------------------------------------------------- */
 void Mesh::distribute() {
   this->distribute(StaticCommunicator::getStaticCommunicator());
 }
 
 /* -------------------------------------------------------------------------- */
 void Mesh::distribute(StaticCommunicator & communicator) {
   AKANTU_DEBUG_ASSERT(is_distributed == false,
                       "This mesh is already distribute");
   this->communicator = &communicator;
 
-  this->element_synchronizer =
-      new ElementSynchronizer(*this, this->getID() + ":element_synchronizer",
-                              this->getMemoryID(), true);
+  this->element_synchronizer = std::make_unique<ElementSynchronizer>(
+      *this, this->getID() + ":element_synchronizer", this->getMemoryID(),
+      true);
 
-  this->node_synchronizer = new NodeSynchronizer(
+  this->node_synchronizer = std::make_unique<NodeSynchronizer>(
       *this, this->getID() + ":node_synchronizer", this->getMemoryID(), true);
 
   Int psize = this->communicator->getNbProc();
 #ifdef AKANTU_USE_SCOTCH
   Int prank = this->communicator->whoAmI();
   if (prank == 0) {
     MeshPartitionScotch partition(*this, spatial_dimension);
     partition.partitionate(psize);
 
     MeshUtilsDistribution::distributeMeshCentralized(*this, 0, partition);
   } else {
     MeshUtilsDistribution::distributeMeshCentralized(*this, 0);
   }
 #else
   if (!(psize == 1)) {
     AKANTU_DEBUG_ERROR("Cannot distribute a mesh without a partitioning tool");
   }
 #endif
 
   this->is_distributed = true;
   this->element_synchronizer->buildPrankToElement();
   this->computeBoundingBox();
 }
 
 /* -------------------------------------------------------------------------- */
+void Mesh::getAssociatedElements(const Array<UInt> & node_list,
+                                 Array<Element> & elements) {
+  for(const auto & node : node_list)
+    for(const auto & element : *nodes_to_elements[node])
+      elements.push_back(element);
+}
+
+/* -------------------------------------------------------------------------- */
+void Mesh::fillNodesToElements() {
+  Element e;
+
+  UInt nb_nodes = nodes->getSize();
+  for (UInt n = 0; n < nb_nodes; ++n) {
+    this->nodes_to_elements[n]->clear();
+  }
+
+  for (auto ghost_type : ghost_types) {
+    e.ghost_type = ghost_type;
+    for (const auto & type :
+         elementTypes(spatial_dimension, ghost_type, _ek_not_defined)) {
+      e.type = type;
+      e.kind = getKind(type);
+
+      UInt nb_element = this->getNbElement(type, ghost_type);
+      Array<UInt>::const_iterator<Vector<UInt>> conn_it =
+          connectivities(type, ghost_type).begin(Mesh::getNbNodesPerElement(type));
+
+      for (UInt el = 0; el < nb_element; ++el, ++conn_it) {
+        e.element = el;
+        const Vector<UInt> & conn = *conn_it;
+        for (UInt n = 0; n < conn.size(); ++n)
+          nodes_to_elements[conn(n)]->insert(e);
+      }
+    }
+  }
+}
 
 } // namespace akantu
diff --git a/src/mesh/mesh.hh b/src/mesh/mesh.hh
index 16aac2d0f..312202a7b 100644
--- a/src/mesh/mesh.hh
+++ b/src/mesh/mesh.hh
@@ -1,613 +1,595 @@
 /**
  * @file   mesh.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Jan 14 2016
  *
  * @brief  the class representing the meshes
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MESH_HH__
 #define __AKANTU_MESH_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_event_handler_manager.hh"
 #include "aka_memory.hh"
 #include "dumpable.hh"
 #include "element.hh"
 #include "element_class.hh"
 #include "element_type_map.hh"
 #include "group_manager.hh"
 #include "mesh_data.hh"
 #include "mesh_events.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class StaticCommunicator;
 class ElementSynchronizer;
 class NodeSynchronizer;
-} // akantu
+} // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Mesh                                                                       */
 /* -------------------------------------------------------------------------- */
 
 /**
  * @class  Mesh this  contain the  coordinates of  the nodes  in  the Mesh.nodes
  * Array,  and the  connectivity. The  connectivity  are stored  in by  element
  * types.
  *
  * In order to loop on all element you have to loop on all types like this :
  * @code{.cpp}
  Mesh::type_iterator it = mesh.firstType(dim, ghost_type);
  Mesh::type_iterator end = mesh.lastType(dim, ghost_type);
  for(; it != end; ++it) {
    UInt nb_element  = mesh.getNbElement(*it);
    const Array<UInt> & conn = mesh.getConnectivity(*it);
    for(UInt e = 0; e < nb_element; ++e) {
      ...
    }
  }
  @endcode
 */
 class Mesh : protected Memory,
              public EventHandlerManager<MeshEventHandler>,
              public GroupManager,
              public Dumpable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   /// default constructor used for chaining, the last parameter is just to
   /// differentiate constructors
   Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id,
        StaticCommunicator & communicator);
 
 public:
   /// constructor that create nodes coordinates array
   Mesh(UInt spatial_dimension, const ID & id = "mesh",
        const MemoryID & memory_id = 0);
 
   /// mesh not distributed and not using the default communicator
   Mesh(UInt spatial_dimension, StaticCommunicator & communicator,
        const ID & id = "mesh", const MemoryID & memory_id = 0);
 
   /// constructor that use an existing nodes coordinates array, by knowing its
   /// ID
-  Mesh(UInt spatial_dimension, const ID & nodes_id, const ID & id,
-       const MemoryID & memory_id = 0);
+  // Mesh(UInt spatial_dimension, const ID & nodes_id, const ID & id,
+  //      const MemoryID & memory_id = 0);
 
   /**
    * constructor that use an existing nodes coordinates
    * array, by getting the vector of coordinates
    */
-  Mesh(UInt spatial_dimension, Array<Real> & nodes, const ID & id = "mesh",
+  Mesh(UInt spatial_dimension, std::shared_ptr<Array<Real>> nodes, const ID & id = "mesh",
        const MemoryID & memory_id = 0);
 
   virtual ~Mesh();
 
   /// @typedef ConnectivityTypeList list of the types present in a Mesh
   typedef std::set<ElementType> ConnectivityTypeList;
 
   /// read the mesh from a file
   void read(const std::string & filename,
             const MeshIOType & mesh_io_type = _miot_auto);
   /// write the mesh to a file
   void write(const std::string & filename,
              const MeshIOType & mesh_io_type = _miot_auto);
 
 private:
   /// initialize the connectivity to NULL and other stuff
   void init();
 
+  /// function that computes the bounding box (fills xmin, xmax)
+  void computeBoundingBox();
+
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// patitionate the mesh among the processors involved in their computation
   virtual void distribute(StaticCommunicator & communicator);
   virtual void distribute();
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
-  /// function that computes the bounding box (fills xmin, xmax)
-  void computeBoundingBox();
-
-  // /// init a by-element-type real vector with provided ids
-  // template <typename T>
-  // void
-  // initElementTypeMapArray(ElementTypeMapArray<T> & v, UInt nb_component,
-  //                         UInt spatial_dimension,
-  //                         const bool & flag_nb_node_per_elem_multiply = false,
-  //                         ElementKind element_kind = _ek_regular,
-  //                         bool size_to_nb_element = false)
-  //     const; /// @todo: think about nicer way to do it
-  // template <typename T>
-  // void
-  // initElementTypeMapArray(ElementTypeMapArray<T> & v, UInt nb_component,
-  //                         UInt spatial_dimension, GhostType ghost_type,
-  //                         const bool & flag_nb_node_per_elem_multiply = false,
-  //                         ElementKind element_kind = _ek_regular,
-  //                         bool size_to_nb_element = false)
-  //     const; /// @todo: think about nicer way to do it
-
-  // template <typename T>
-  // void
-  // initElementTypeMapArray(ElementTypeMapArray<T> & v, UInt nb_component,
-  //                         UInt spatial_dimension, GhostType ghost_type,
-  //                         const T & default_value,
-  //                         const bool & flag_nb_node_per_elem_multiply = false,
-  //                         ElementKind element_kind = _ek_regular,
-  //                         bool size_to_nb_element = false)
-  //     const; /// @todo: think about nicer way to do it
-
   /// extract coordinates of nodes from an element
   template <typename T>
   inline void extractNodalValuesFromElement(const Array<T> & nodal_values,
                                             T * elemental_values,
                                             UInt * connectivity, UInt n_nodes,
                                             UInt nb_degree_of_freedom) const;
 
   // /// extract coordinates of nodes from a reversed element
   // inline void extractNodalCoordinatesFromPBCElement(Real * local_coords,
   //                                                   UInt * connectivity,
   //                                                   UInt n_nodes);
 
   /// convert a element to a linearized element
   inline UInt elementToLinearized(const Element & elem) const;
 
   /// convert a linearized element to an element
   inline Element linearizedToElement(UInt linearized_element) const;
 
   /// update the types offsets array for the conversions
-  inline void updateTypesOffsets(const GhostType & ghost_type);
+  //inline void updateTypesOffsets(const GhostType & ghost_type);
 
   /// add a Array of connectivity for the type <type>.
   inline void addConnectivityType(const ElementType & type,
                                   const GhostType & ghost_type = _not_ghost);
 
   /* ------------------------------------------------------------------------ */
   template <class Event> inline void sendEvent(Event & event) {
     //    if(event.getList().getSize() != 0)
     EventHandlerManager<MeshEventHandler>::sendEvent<Event>(event);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void removeNodesFromArray(Array<T> & vect,
                                    const Array<UInt> & new_numbering);
 
   /// initialize normals
   void initNormals();
 
   /// init facets' mesh
   Mesh & initMeshFacets(const ID & id = "mesh_facets");
 
   /// define parent mesh
   void defineMeshParent(const Mesh & mesh);
 
   /// get global connectivity array
   void getGlobalConnectivity(ElementTypeMapArray<UInt> & global_connectivity,
                              UInt dimension, GhostType ghost_type);
 
+public:
+  void getAssociatedElements(const Array<UInt> & node_list,
+                             Array<Element> & elements);
+
+private:
+  /// fills the nodes_to_elements structure
+  void fillNodesToElements();
+
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the id of the mesh
   AKANTU_GET_MACRO(ID, Memory::id, const ID &);
 
   /// get the id of the mesh
   AKANTU_GET_MACRO(MemoryID, Memory::memory_id, const MemoryID &);
 
   /// get the spatial dimension of the mesh = number of component of the
   /// coordinates
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
 
   /// get the nodes Array aka coordinates
   AKANTU_GET_MACRO(Nodes, *nodes, const Array<Real> &);
   AKANTU_GET_MACRO_NOT_CONST(Nodes, *nodes, Array<Real> &);
 
   /// get the normals for the elements
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Normals, normals, Real);
 
   /// get the number of nodes
   AKANTU_GET_MACRO(NbNodes, nodes->getSize(), UInt);
 
   /// get the Array of global ids of the nodes (only used in parallel)
   AKANTU_GET_MACRO(GlobalNodesIds, *nodes_global_ids, const Array<UInt> &);
   AKANTU_GET_MACRO_NOT_CONST(GlobalNodesIds, *nodes_global_ids, Array<UInt> &);
 
   /// get the global id of a node
   inline UInt getNodeGlobalId(UInt local_id) const;
 
   /// get the global id of a node
   inline UInt getNodeLocalId(UInt global_id) const;
 
   /// get the global number of nodes
   inline UInt getNbGlobalNodes() const;
 
   /// get the nodes type Array
   AKANTU_GET_MACRO(NodesType, nodes_type, const Array<NodeType> &);
 
 protected:
   AKANTU_GET_MACRO_NOT_CONST(NodesType, nodes_type, Array<NodeType> &);
 
 public:
   inline NodeType getNodeType(UInt local_id) const;
 
   /// say if a node is a pure ghost node
   inline bool isPureGhostNode(UInt n) const;
 
   /// say if a node is pur local or master node
   inline bool isLocalOrMasterNode(UInt n) const;
 
   inline bool isLocalNode(UInt n) const;
   inline bool isMasterNode(UInt n) const;
   inline bool isSlaveNode(UInt n) const;
 
   AKANTU_GET_MACRO(LowerBounds, lower_bounds, const Vector<Real> &);
   AKANTU_GET_MACRO(UpperBounds, upper_bounds, const Vector<Real> &);
   AKANTU_GET_MACRO(LocalLowerBounds, local_lower_bounds, const Vector<Real> &);
   AKANTU_GET_MACRO(LocalUpperBounds, local_upper_bounds, const Vector<Real> &);
 
   /// get the connectivity Array for a given type
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Connectivity, connectivities, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Connectivity, connectivities, UInt);
   AKANTU_GET_MACRO(Connectivities, connectivities,
                    const ElementTypeMapArray<UInt> &);
 
   /// get the number of element of a type in the mesh
   inline UInt getNbElement(const ElementType & type,
                            const GhostType & ghost_type = _not_ghost) const;
 
   /// get the number of element for a given ghost_type and a given dimension
   inline UInt getNbElement(const UInt spatial_dimension = _all_dimensions,
                            const GhostType & ghost_type = _not_ghost,
                            const ElementKind & kind = _ek_not_defined) const;
 
-  /// get the connectivity list either for the elements or the ghost elements
-  inline const ConnectivityTypeList &
-  getConnectivityTypeList(const GhostType & ghost_type = _not_ghost) const;
+  // /// get the connectivity list either for the elements or the ghost elements
+  // inline const ConnectivityTypeList &
+  // getConnectivityTypeList(const GhostType & ghost_type = _not_ghost) const;
 
   /// compute the barycenter of a given element
   inline void getBarycenter(UInt element, const ElementType & type,
                             Real * barycenter,
                             GhostType ghost_type = _not_ghost) const;
   inline void getBarycenter(const Element & element,
                             Vector<Real> & barycenter) const;
 
   /// get the element connected to a subelement
   const Array<std::vector<Element>> &
   getElementToSubelement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost) const;
   /// get the element connected to a subelement
   Array<std::vector<Element>> &
   getElementToSubelement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost);
 
   /// get the subelement connected to an element
   const Array<Element> &
   getSubelementToElement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost) const;
   /// get the subelement connected to an element
   Array<Element> &
   getSubelementToElement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost);
 
   /// get a name field associated to the mesh
   template <typename T>
   inline const Array<T> &
   getData(const std::string & data_name, const ElementType & el_type,
           const GhostType & ghost_type = _not_ghost) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline Array<T> & getData(const std::string & data_name,
                             const ElementType & el_type,
                             const GhostType & ghost_type = _not_ghost);
 
   /// register a new ElementalTypeMap in the MeshData
   template <typename T>
   inline ElementTypeMapArray<T> & registerData(const std::string & data_name);
 
   /// get a name field associated to the mesh
   template <typename T>
   inline const ElementTypeMapArray<T> &
   getData(const std::string & data_name) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline ElementTypeMapArray<T> & getData(const std::string & data_name);
 
   template <typename T>
   ElementTypeMap<UInt> getNbDataPerElem(ElementTypeMapArray<T> & array,
                                         const ElementKind & element_kind);
 
   template <typename T>
   dumper::Field * createFieldFromAttachedData(const std::string & field_id,
                                               const std::string & group_name,
                                               const ElementKind & element_kind);
 
   /// templated getter returning the pointer to data in MeshData (modifiable)
   template <typename T>
-  inline Array<T> *
+  inline Array<T> &
   getDataPointer(const std::string & data_name, const ElementType & el_type,
                  const GhostType & ghost_type = _not_ghost,
                  UInt nb_component = 1, bool size_to_nb_element = true,
                  bool resize_with_parent = false);
 
   /// Facets mesh accessor
   inline const Mesh & getMeshFacets() const;
   inline Mesh & getMeshFacets();
 
   /// Parent mesh accessor
   inline const Mesh & getMeshParent() const;
 
   inline bool isMeshFacets() const { return this->is_mesh_facets; }
 
   /// defines is the mesh is distributed or not
   inline bool isDistributed() const { return this->is_distributed; }
 
 #ifndef SWIG
   /// return the dumper from a group and and a dumper name
   DumperIOHelper & getGroupDumper(const std::string & dumper_name,
                                   const std::string & group_name);
 #endif
   /* ------------------------------------------------------------------------ */
   /* Wrappers on ElementClass functions                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the number of nodes per element for a given element type
   static inline UInt getNbNodesPerElement(const ElementType & type);
 
   /// get the number of nodes per element for a given element type considered as
   /// a first order element
   static inline ElementType getP1ElementType(const ElementType & type);
 
   /// get the kind of the element type
   static inline ElementKind getKind(const ElementType & type);
 
   /// get spatial dimension of a type of element
   static inline UInt getSpatialDimension(const ElementType & type);
 
   /// get number of facets of a given element type
   static inline UInt getNbFacetsPerElement(const ElementType & type);
 
   /// get number of facets of a given element type
   static inline UInt getNbFacetsPerElement(const ElementType & type, UInt t);
 
   /// get local connectivity of a facet for a given facet type
   static inline MatrixProxy<UInt>
   getFacetLocalConnectivity(const ElementType & type, UInt t = 0);
 
   /// get connectivity of facets for a given element
   inline Matrix<UInt> getFacetConnectivity(const Element & element,
                                            UInt t = 0) const;
 
   /// get the number of type of the surface element associated to a given
   /// element type
   static inline UInt getNbFacetTypes(const ElementType & type, UInt t = 0);
 
   /// get the type of the surface element associated to a given element
   static inline ElementType getFacetType(const ElementType & type, UInt t = 0);
 
   /// get all the type of the surface element associated to a given element
   static inline VectorProxy<ElementType>
   getAllFacetTypes(const ElementType & type);
 
   /// get the number of nodes in the given element list
   static inline UInt getNbNodesPerElementList(const Array<Element> & elements);
 
   /* ------------------------------------------------------------------------ */
   /* Element type Iterator                                                    */
   /* ------------------------------------------------------------------------ */
-  typedef ElementTypeMapArray<UInt, ElementType>::type_iterator type_iterator;
-  typedef ElementTypeMapArray<UInt, ElementType>::ElementTypesIteratorHelper
-      ElementTypesIteratorHelper;
+  using type_iterator = ElementTypeMapArray<UInt, ElementType>::type_iterator;
+  using ElementTypesIteratorHelper =
+      ElementTypeMapArray<UInt, ElementType>::ElementTypesIteratorHelper;
 
   inline ElementTypesIteratorHelper
   elementTypes(UInt dim = _all_dimensions, GhostType ghost_type = _not_ghost,
                ElementKind kind = _ek_regular) const {
     return connectivities.elementTypes(dim, ghost_type, kind);
   }
 
   inline type_iterator firstType(UInt dim = _all_dimensions,
                                  GhostType ghost_type = _not_ghost,
                                  ElementKind kind = _ek_regular) const {
     return connectivities.firstType(dim, ghost_type, kind);
   }
 
   inline type_iterator lastType(UInt dim = _all_dimensions,
                                 GhostType ghost_type = _not_ghost,
                                 ElementKind kind = _ek_regular) const {
     return connectivities.lastType(dim, ghost_type, kind);
   }
 
   AKANTU_GET_MACRO(ElementSynchronizer, *element_synchronizer,
                    const ElementSynchronizer &);
   AKANTU_GET_MACRO_NOT_CONST(ElementSynchronizer, *element_synchronizer,
                              ElementSynchronizer &);
   AKANTU_GET_MACRO(NodeSynchronizer, *node_synchronizer,
                    const NodeSynchronizer &);
   AKANTU_GET_MACRO_NOT_CONST(NodeSynchronizer, *node_synchronizer,
                              NodeSynchronizer &);
 
   // AKANTU_GET_MACRO_NOT_CONST(Communicator, *communicator, StaticCommunicator
   // &);
   AKANTU_GET_MACRO(Communicator, *communicator, const StaticCommunicator &);
   /* ------------------------------------------------------------------------ */
   /* Private methods for friends                                              */
   /* ------------------------------------------------------------------------ */
 private:
   friend class MeshAccessor;
 
   //#if defined(AKANTU_COHESIVE_ELEMENT)
   //  friend class CohesiveElementInserter;
   //#endif
 
   //#if defined(AKANTU_IGFEM)
   //  template <UInt dim> friend class MeshIgfemSphericalGrowingGel;
   //#endif
 
-  AKANTU_GET_MACRO(NodesPointer, nodes, Array<Real> *);
+  AKANTU_GET_MACRO(NodesPointer, *nodes, Array<Real> &);
 
   /// get a pointer to the nodes_global_ids Array<UInt> and create it if
   /// necessary
-  inline Array<UInt> * getNodesGlobalIdsPointer();
+  inline Array<UInt> & getNodesGlobalIdsPointer();
 
   /// get a pointer to the nodes_type Array<Int> and create it if necessary
-  inline Array<NodeType> * getNodesTypePointer();
+  inline Array<NodeType> & getNodesTypePointer();
 
   /// get a pointer to the connectivity Array for the given type and create it
   /// if necessary
-  inline Array<UInt> *
+  inline Array<UInt> &
   getConnectivityPointer(const ElementType & type,
                          const GhostType & ghost_type = _not_ghost);
 
   /// get a pointer to the element_to_subelement Array for the given type and
   /// create it if necessary
-  inline Array<std::vector<Element>> *
+  inline Array<std::vector<Element>> &
   getElementToSubelementPointer(const ElementType & type,
                                 const GhostType & ghost_type = _not_ghost);
 
   /// get a pointer to the subelement_to_element Array for the given type and
   /// create it if necessary
-  inline Array<Element> *
+  inline Array<Element> &
   getSubelementToElementPointer(const ElementType & type,
                                 const GhostType & ghost_type = _not_ghost);
 
   AKANTU_GET_MACRO_NOT_CONST(MeshData, mesh_data, MeshData &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// array of the nodes coordinates
-  Array<Real> * nodes;
+  std::shared_ptr<Array<Real>> nodes;
 
   /// global node ids
-  Array<UInt> * nodes_global_ids;
+  std::unique_ptr<Array<UInt>> nodes_global_ids;
 
   /// node type,  -3 pure ghost, -2  master for the  node, -1 normal node,  i in
   /// [0-N] slave node and master is proc i
   Array<NodeType> nodes_type;
 
   /// global number of nodes;
-  UInt nb_global_nodes;
-
-  /// boolean to know if the nodes have to be deleted with the mesh or not
-  bool created_nodes;
+  UInt nb_global_nodes{0};
 
   /// all class of elements present in this mesh (for heterogenous meshes)
   ElementTypeMapArray<UInt> connectivities;
 
   /// map to normals for all class of elements present in this mesh
   ElementTypeMapArray<Real> normals;
 
   /// list of all existing types in the mesh
-  ConnectivityTypeList type_set;
+  // ConnectivityTypeList type_set;
 
   /// the spatial dimension of this mesh
-  UInt spatial_dimension;
+  UInt spatial_dimension{0};
 
   /// types offsets
-  Array<UInt> types_offsets;
+  // Array<UInt> types_offsets;
 
-  /// list of all existing types in the mesh
-  ConnectivityTypeList ghost_type_set;
-  /// ghost types offsets
-  Array<UInt> ghost_types_offsets;
+  // /// list of all existing types in the mesh
+  // ConnectivityTypeList ghost_type_set;
+  // /// ghost types offsets
+  // Array<UInt> ghost_types_offsets;
 
   /// min of coordinates
   Vector<Real> lower_bounds;
   /// max of coordinates
   Vector<Real> upper_bounds;
   /// size covered by the mesh on each direction
   Vector<Real> size;
 
   /// local min of coordinates
   Vector<Real> local_lower_bounds;
   /// local max of coordinates
   Vector<Real> local_upper_bounds;
 
   /// Extra data loaded from the mesh file
   MeshData mesh_data;
 
   /// facets' mesh
-  Mesh * mesh_facets;
+  std::unique_ptr<Mesh> mesh_facets;
 
   /// parent mesh (this is set for mesh_facets meshes)
-  const Mesh * mesh_parent;
+  const Mesh * mesh_parent{nullptr};
 
   /// defines if current mesh is mesh_facets or not
-  bool is_mesh_facets;
+  bool is_mesh_facets{false};
 
   /// defines if the mesh is centralized or distributed
-  bool is_distributed;
+  bool is_distributed{false};
 
   /// Communicator on which mesh is distributed
-  StaticCommunicator * communicator;
+  const StaticCommunicator * communicator;
 
   /// Element synchronizer
-  ElementSynchronizer * element_synchronizer;
+  std::unique_ptr<ElementSynchronizer> element_synchronizer;
 
   /// Node synchronizer
-  NodeSynchronizer * node_synchronizer;
+  std::unique_ptr<NodeSynchronizer> node_synchronizer;
+
+  using NodesToElements = std::vector<std::unique_ptr<std::set<Element>>>;
+
+  /// This info is stored to simplify the dynamic changes
+  NodesToElements nodes_to_elements;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream, const Element & _this) {
   _this.printself(stream);
   return stream;
 }
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream, const Mesh & _this) {
   _this.printself(stream);
   return stream;
 }
 
-} // akantu
+} // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* Inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "element_type_map_tmpl.hh"
 #include "mesh_inline_impl.cc"
 
 #endif /* __AKANTU_MESH_HH__ */
diff --git a/src/mesh/mesh_accessor.hh b/src/mesh/mesh_accessor.hh
index abf01fe45..061f20a3b 100644
--- a/src/mesh/mesh_accessor.hh
+++ b/src/mesh/mesh_accessor.hh
@@ -1,129 +1,132 @@
 /**
  * @file   mesh_accessor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jun 30 2015
  *
  * @brief  this class allow to access some private member of mesh it is used for
  * IO for examples
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "mesh.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_ACCESSOR_HH__
 #define __AKANTU_MESH_ACCESSOR_HH__
 
 namespace akantu {
 class NodeSynchronizer;
 class ElementSynchronizer;
-}  // akantu
+} // namespace akantu
 
 namespace akantu {
 
 class MeshAccessor {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
-  MeshAccessor(Mesh & mesh) : _mesh(mesh){};
-  virtual ~MeshAccessor(){};
+  explicit MeshAccessor(Mesh & mesh) : _mesh(mesh){};
+  virtual ~MeshAccessor() = default;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the global number of nodes
   inline UInt getNbGlobalNodes() const { return this->_mesh.nb_global_nodes; };
 
   /// set the global number of nodes
   inline void setNbGlobalNodes(UInt nb_global_nodes) {
     this->_mesh.nb_global_nodes = nb_global_nodes;
   };
 
   /// set the mesh as being distributed
   inline void setDistributed() { this->_mesh.is_distributed = true; }
 
   /// get a pointer to the nodes_global_ids Array<UInt> and create it if
   /// necessary
   inline Array<UInt> & getNodesGlobalIds() {
-    return *(this->_mesh.getNodesGlobalIdsPointer());
+    return this->_mesh.getNodesGlobalIdsPointer();
   }
 
   /// get a pointer to the nodes_type Array<Int> and create it if necessary
   inline Array<NodeType> & getNodesType() {
-    return *(this->_mesh.getNodesTypePointer());
+    return this->_mesh.getNodesTypePointer();
   }
 
   /// get a pointer to the coordinates Array
-  inline Array<Real> & getNodes() { return *(this->_mesh.getNodesPointer()); }
+  inline Array<Real> & getNodes() { return this->_mesh.getNodesPointer(); }
+
+  /// get a pointer to the coordinates Array
+  inline std::shared_ptr<Array<Real>> getNodesSharedPtr() { return this->_mesh.nodes; }
 
   /// get a pointer to the connectivity Array for the given type and create it
   /// if necessary
   inline Array<UInt> &
   getConnectivity(const ElementType & type,
                   const GhostType & ghost_type = _not_ghost) {
-    return *(this->_mesh.getConnectivityPointer(type, ghost_type));
+    return this->_mesh.getConnectivityPointer(type, ghost_type);
   }
 
   /// get a pointer to the element_to_subelement Array for the given type and
   /// create it if necessary
-  inline Array<std::vector<Element> > &
+  inline Array<std::vector<Element>> &
   getElementToSubelement(const ElementType & type,
                          const GhostType & ghost_type = _not_ghost) {
-    return *(this->_mesh.getElementToSubelementPointer(type, ghost_type));
+    return this->_mesh.getElementToSubelementPointer(type, ghost_type);
   }
 
   /// get a pointer to the subelement_to_element Array for the given type and
   /// create it if necessary
   inline Array<Element> &
   getSubelementToElement(const ElementType & type,
                          const GhostType & ghost_type = _not_ghost) {
-    return *(this->_mesh.getSubelementToElementPointer(type, ghost_type));
+    return this->_mesh.getSubelementToElementPointer(type, ghost_type);
   }
 
   template <typename T>
   inline Array<T> &
   getData(const std::string & data_name, const ElementType & el_type,
           const GhostType & ghost_type = _not_ghost, UInt nb_component = 1,
           bool size_to_nb_element = true, bool resize_with_parent = false) {
-    return *(this->_mesh.getDataPointer<T>(data_name, el_type, ghost_type,
-                                           nb_component, size_to_nb_element,
-                                           resize_with_parent));
+    return this->_mesh.getDataPointer<T>(data_name, el_type, ghost_type,
+                                         nb_component, size_to_nb_element,
+                                         resize_with_parent);
   }
 
   MeshData & getMeshData() { return this->_mesh.getMeshData(); }
 
   /// get the node synchonizer
   NodeSynchronizer & getNodeSynchronizer();
 
   /// get the element synchonizer
   ElementSynchronizer & getElementSynchronizer();
 
 private:
   Mesh & _mesh;
 };
 
-} // akantu
+} // namespace akantu
 
 #endif /* __AKANTU_MESH_ACCESSOR_HH__ */
diff --git a/src/mesh/mesh_inline_impl.cc b/src/mesh/mesh_inline_impl.cc
index 3e74a8532..612d3fe5c 100644
--- a/src/mesh/mesh_inline_impl.cc
+++ b/src/mesh/mesh_inline_impl.cc
@@ -1,630 +1,681 @@
 /**
  * @file   mesh_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
  * @date last modification: Thu Jan 21 2016
  *
  * @brief  Implementation of the inline functions of the mesh class
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_COHESIVE_ELEMENT)
 #include "cohesive_element.hh"
 #endif
 
 #ifndef __AKANTU_MESH_INLINE_IMPL_CC__
 #define __AKANTU_MESH_INLINE_IMPL_CC__
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 inline RemovedNodesEvent::RemovedNodesEvent(const Mesh & mesh)
     : new_numbering(mesh.getNbNodes(), 1, "new_numbering") {}
 
 /* -------------------------------------------------------------------------- */
 inline RemovedElementsEvent::RemovedElementsEvent(const Mesh & mesh,
                                                   ID new_numbering_id)
     : new_numbering(new_numbering_id, mesh.getID(), mesh.getMemoryID()) {}
 
+/* -------------------------------------------------------------------------- */
+template <>
+inline void Mesh::sendEvent<NewElementsEvent>(NewElementsEvent & event) {
+  this->nodes_to_elements.resize(nodes->getSize());
+  for (const auto & elem : event.getList()) {
+    const Array<UInt> & conn = connectivities(elem.type, elem.ghost_type);
+
+    UInt nb_nodes_per_elem = this->getNbNodesPerElement(elem.type);
+
+    for (UInt n = 0; n < nb_nodes_per_elem; ++n) {
+      UInt node = conn(elem.element, n);
+      if (not nodes_to_elements[node])
+        nodes_to_elements[node] = std::make_unique<std::set<Element>>();
+      nodes_to_elements[node]->insert(elem);
+    }
+  }
+
+  EventHandlerManager<MeshEventHandler>::sendEvent(event);
+}
+
+/* -------------------------------------------------------------------------- */
+template <> inline void Mesh::sendEvent<NewNodesEvent>(NewNodesEvent & event) {
+  this->computeBoundingBox();
+
+  EventHandlerManager<MeshEventHandler>::sendEvent(event);
+}
+
 /* -------------------------------------------------------------------------- */
 template <>
 inline void
 Mesh::sendEvent<RemovedElementsEvent>(RemovedElementsEvent & event) {
   this->connectivities.onElementsRemoved(event.getNewNumbering());
+  this->fillNodesToElements();
+  this->computeBoundingBox();
+
   EventHandlerManager<MeshEventHandler>::sendEvent(event);
 }
 
 /* -------------------------------------------------------------------------- */
 template <>
 inline void Mesh::sendEvent<RemovedNodesEvent>(RemovedNodesEvent & event) {
-  if (created_nodes)
-    this->removeNodesFromArray(*nodes, event.getNewNumbering());
+  const auto & new_numbering = event.getNewNumbering();
+  this->removeNodesFromArray(*nodes, new_numbering);
   if (nodes_global_ids)
-    this->removeNodesFromArray(*nodes_global_ids, event.getNewNumbering());
+    this->removeNodesFromArray(*nodes_global_ids, new_numbering);
   if (nodes_type.getSize() != 0)
-    this->removeNodesFromArray(nodes_type, event.getNewNumbering());
+    this->removeNodesFromArray(nodes_type, new_numbering);
+
+  std::vector<std::unique_ptr<std::set<Element>>> tmp(nodes_to_elements.size());
+  auto it = nodes_to_elements.begin();
+
+  UInt new_nb_nodes = 0;
+  for (auto new_i : new_numbering) {
+    if (new_i != UInt(-1)) {
+      tmp[new_i] = std::move(*it);
+      ++new_nb_nodes;
+    }
+    ++it;
+  }
+
+  tmp.resize(new_nb_nodes);
+  std::move(tmp.begin(), tmp.end(), nodes_to_elements.begin());
+
+  computeBoundingBox();
 
   EventHandlerManager<MeshEventHandler>::sendEvent(event);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Mesh::removeNodesFromArray(Array<T> & vect,
                                        const Array<UInt> & new_numbering) {
   Array<T> tmp(vect.getSize(), vect.getNbComponent());
   UInt nb_component = vect.getNbComponent();
   UInt new_nb_nodes = 0;
   for (UInt i = 0; i < new_numbering.getSize(); ++i) {
     UInt new_i = new_numbering(i);
     if (new_i != UInt(-1)) {
       T * to_copy = vect.storage() + i * nb_component;
       std::uninitialized_copy(to_copy, to_copy + nb_component,
                               tmp.storage() + new_i * nb_component);
       ++new_nb_nodes;
     }
   }
 
   tmp.resize(new_nb_nodes);
   vect.copy(tmp);
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt Mesh::elementToLinearized(const Element & elem) const {
-  AKANTU_DEBUG_ASSERT(elem.type < _max_element_type &&
-                          elem.element < types_offsets.storage()[elem.type + 1],
-                      "The element " << elem << "does not exists in the mesh "
-                                     << getID());
-
-  return types_offsets.storage()[elem.type] + elem.element;
-}
-
-/* -------------------------------------------------------------------------- */
-inline Element Mesh::linearizedToElement(UInt linearized_element) const {
-
-  UInt t;
-
-  for (t = _not_defined;
-       t != _max_element_type && linearized_element >= types_offsets(t); ++t)
-    ;
-
-  AKANTU_DEBUG_ASSERT(linearized_element < types_offsets(t),
-                      "The linearized element "
-                          << linearized_element
-                          << "does not exists in the mesh " << getID());
-
-  --t;
-  ElementType type = ElementType(t);
-  return Element(type, linearized_element - types_offsets.storage()[t],
-                 _not_ghost, getKind(type));
-}
-
-/* -------------------------------------------------------------------------- */
-inline void Mesh::updateTypesOffsets(const GhostType & ghost_type) {
-  Array<UInt> * types_offsets_ptr = &this->types_offsets;
-  if (ghost_type == _ghost)
-    types_offsets_ptr = &this->ghost_types_offsets;
-  Array<UInt> & types_offsets = *types_offsets_ptr;
-
-  types_offsets.clear();
-  for (auto type : elementTypes(_all_dimensions, ghost_type, _ek_not_defined))
-    types_offsets(type) = connectivities(type, ghost_type).getSize();
-
-  for (UInt t = _not_defined + 1; t < _max_element_type; ++t)
-    types_offsets(t) += types_offsets(t - 1);
-  for (UInt t = _max_element_type; t > _not_defined; --t)
-    types_offsets(t) = types_offsets(t - 1);
-  types_offsets(0) = 0;
-}
-
-/* -------------------------------------------------------------------------- */
-inline const Mesh::ConnectivityTypeList &
-Mesh::getConnectivityTypeList(const GhostType & ghost_type) const {
-  if (ghost_type == _not_ghost)
-    return type_set;
-  else
-    return ghost_type_set;
-}
-
-/* -------------------------------------------------------------------------- */
-inline Array<UInt> * Mesh::getNodesGlobalIdsPointer() {
+// inline UInt Mesh::elementToLinearized(const Element & elem) const {
+//   AKANTU_DEBUG_ASSERT(elem.type < _max_element_type &&
+//                           elem.element < types_offsets.storage()[elem.type +
+//                           1],
+//                       "The element " << elem << "does not exists in the mesh
+//                       "
+//                                      << getID());
+
+//   return types_offsets.storage()[elem.type] + elem.element;
+// }
+
+// /* --------------------------------------------------------------------------
+// */ inline Element Mesh::linearizedToElement(UInt linearized_element) const {
+
+//   UInt t;
+
+//   for (t = _not_defined;
+//        t != _max_element_type && linearized_element >= types_offsets(t); ++t)
+//     ;
+
+//   AKANTU_DEBUG_ASSERT(linearized_element < types_offsets(t),
+//                       "The linearized element "
+//                           << linearized_element
+//                           << "does not exists in the mesh " << getID());
+
+//   --t;
+//   ElementType type = ElementType(t);
+//   return Element(type, linearized_element - types_offsets.storage()[t],
+//                  _not_ghost, getKind(type));
+// }
+
+// /* --------------------------------------------------------------------------
+// */ inline void Mesh::updateTypesOffsets(const GhostType & ghost_type) {
+//   Array<UInt> * types_offsets_ptr = &this->types_offsets;
+//   if (ghost_type == _ghost)
+//     types_offsets_ptr = &this->ghost_types_offsets;
+//   Array<UInt> & types_offsets = *types_offsets_ptr;
+
+//   types_offsets.clear();
+//   for (auto type : elementTypes(_all_dimensions, ghost_type,
+//   _ek_not_defined))
+//     types_offsets(type) = connectivities(type, ghost_type).getSize();
+
+//   for (UInt t = _not_defined + 1; t < _max_element_type; ++t)
+//     types_offsets(t) += types_offsets(t - 1);
+//   for (UInt t = _max_element_type; t > _not_defined; --t)
+//     types_offsets(t) = types_offsets(t - 1);
+//   types_offsets(0) = 0;
+// }
+
+// /* --------------------------------------------------------------------------
+// */ inline const Mesh::ConnectivityTypeList &
+// Mesh::getConnectivityTypeList(const GhostType & ghost_type) const {
+//   if (ghost_type == _not_ghost)
+//     return type_set;
+//   else
+//     return ghost_type_set;
+// }
+
+/* -------------------------------------------------------------------------- */
+inline Array<UInt> & Mesh::getNodesGlobalIdsPointer() {
   AKANTU_DEBUG_IN();
-  if (nodes_global_ids == NULL) {
-    std::stringstream sstr;
-    sstr << getID() << ":nodes_global_ids";
-    nodes_global_ids = &(alloc<UInt>(sstr.str(), nodes->getSize(), 1));
-    for (UInt i = 0; i < nodes->getSize(); ++i) {
-      (*nodes_global_ids)(i) = i;
+  if (not nodes_global_ids) {
+    auto nb_nodes = nodes->getSize();
+    nodes_global_ids = std::make_unique<Array<UInt>>(
+        nb_nodes, 1, getID() + ":nodes_global_ids");
+
+    UInt i = 0;
+    for (auto & global_id : *nodes_global_ids) {
+      global_id = ++i;
     }
   }
+
   AKANTU_DEBUG_OUT();
-  return nodes_global_ids;
+  return *nodes_global_ids;
 }
 
 /* -------------------------------------------------------------------------- */
-inline Array<NodeType> * Mesh::getNodesTypePointer() {
+inline Array<NodeType> & Mesh::getNodesTypePointer() {
   AKANTU_DEBUG_IN();
   if (nodes_type.getSize() == 0) {
     nodes_type.resize(nodes->getSize());
     nodes_type.set(_nt_normal);
   }
+
   AKANTU_DEBUG_OUT();
-  return &nodes_type;
+  return nodes_type;
 }
 
 /* -------------------------------------------------------------------------- */
-inline Array<UInt> *
+inline Array<UInt> &
 Mesh::getConnectivityPointer(const ElementType & type,
                              const GhostType & ghost_type) {
   AKANTU_DEBUG_IN();
 
   Array<UInt> * tmp;
   if (!connectivities.exists(type, ghost_type)) {
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     tmp = &(connectivities.alloc(0, nb_nodes_per_element, type, ghost_type));
 
     AKANTU_DEBUG_INFO("The connectivity vector for the type " << type
                                                               << " created");
+    // if (ghost_type == _not_ghost)
+    //   type_set.insert(type);
+    // else
+    //   ghost_type_set.insert(type);
 
-    if (ghost_type == _not_ghost)
-      type_set.insert(type);
-    else
-      ghost_type_set.insert(type);
-
-    updateTypesOffsets(ghost_type);
+    // updateTypesOffsets(ghost_type);
   } else {
     tmp = &connectivities(type, ghost_type);
   }
 
   AKANTU_DEBUG_OUT();
-  return tmp;
+  return *tmp;
 }
 
 /* -------------------------------------------------------------------------- */
-inline Array<std::vector<Element>> *
+inline Array<std::vector<Element>> &
 Mesh::getElementToSubelementPointer(const ElementType & type,
                                     const GhostType & ghost_type) {
-  Array<std::vector<Element>> * tmp = getDataPointer<std::vector<Element>>(
-      "element_to_subelement", type, ghost_type, 1, true);
-  return tmp;
+  return getDataPointer<std::vector<Element>>("element_to_subelement", type,
+                                              ghost_type, 1, true);
 }
 
 /* -------------------------------------------------------------------------- */
-inline Array<Element> *
+inline Array<Element> &
 Mesh::getSubelementToElementPointer(const ElementType & type,
                                     const GhostType & ghost_type) {
-  Array<Element> * tmp = getDataPointer<Element>(
-      "subelement_to_element", type, ghost_type, getNbFacetsPerElement(type),
-      true, is_mesh_facets);
-  return tmp;
+  return getDataPointer<Element>("subelement_to_element", type, ghost_type,
+                                 getNbFacetsPerElement(type), true,
+                                 is_mesh_facets);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<std::vector<Element>> &
 Mesh::getElementToSubelement(const ElementType & type,
                              const GhostType & ghost_type) const {
   return getData<std::vector<Element>>("element_to_subelement", type,
                                        ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<std::vector<Element>> &
 Mesh::getElementToSubelement(const ElementType & type,
                              const GhostType & ghost_type) {
   return getData<std::vector<Element>>("element_to_subelement", type,
                                        ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Array<Element> &
 Mesh::getSubelementToElement(const ElementType & type,
                              const GhostType & ghost_type) const {
   return getData<Element>("subelement_to_element", type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline Array<Element> &
 Mesh::getSubelementToElement(const ElementType & type,
                              const GhostType & ghost_type) {
   return getData<Element>("subelement_to_element", type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
-inline Array<T> *
+inline Array<T> &
 Mesh::getDataPointer(const std::string & data_name, const ElementType & el_type,
                      const GhostType & ghost_type, UInt nb_component,
                      bool size_to_nb_element, bool resize_with_parent) {
   Array<T> & tmp = mesh_data.getElementalDataArrayAlloc<T>(
       data_name, el_type, ghost_type, nb_component);
 
   if (size_to_nb_element) {
     if (resize_with_parent)
       tmp.resize(mesh_parent->getNbElement(el_type, ghost_type));
     else
       tmp.resize(this->getNbElement(el_type, ghost_type));
   } else {
     tmp.resize(0);
   }
 
-  return &tmp;
+  return tmp;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline const Array<T> & Mesh::getData(const std::string & data_name,
                                       const ElementType & el_type,
                                       const GhostType & ghost_type) const {
   return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline Array<T> & Mesh::getData(const std::string & data_name,
                                 const ElementType & el_type,
                                 const GhostType & ghost_type) {
   return mesh_data.getElementalDataArray<T>(data_name, el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline const ElementTypeMapArray<T> &
 Mesh::getData(const std::string & data_name) const {
   return mesh_data.getElementalData<T>(data_name);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline ElementTypeMapArray<T> & Mesh::getData(const std::string & data_name) {
   return mesh_data.getElementalData<T>(data_name);
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline ElementTypeMapArray<T> &
 Mesh::registerData(const std::string & data_name) {
   this->mesh_data.registerElementalData<T>(data_name);
   return this->getData<T>(data_name);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbElement(const ElementType & type,
                                const GhostType & ghost_type) const {
   try {
 
     const Array<UInt> & conn = connectivities(type, ghost_type);
     return conn.getSize();
   } catch (...) {
     return 0;
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbElement(const UInt spatial_dimension,
                                const GhostType & ghost_type,
                                const ElementKind & kind) const {
   AKANTU_DEBUG_ASSERT(spatial_dimension <= 3 || spatial_dimension == UInt(-1),
                       "spatial_dimension is " << spatial_dimension
                                               << " and is greater than 3 !");
   UInt nb_element = 0;
 
   for (auto type : elementTypes(spatial_dimension, ghost_type, kind))
     nb_element += getNbElement(type, ghost_type);
 
   return nb_element;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Mesh::getBarycenter(UInt element, const ElementType & type,
                                 Real * barycenter, GhostType ghost_type) const {
   UInt * conn_val = getConnectivity(type, ghost_type).storage();
   UInt nb_nodes_per_element = getNbNodesPerElement(type);
 
   Real * local_coord = new Real[spatial_dimension * nb_nodes_per_element];
 
   UInt offset = element * nb_nodes_per_element;
   for (UInt n = 0; n < nb_nodes_per_element; ++n) {
     memcpy(local_coord + n * spatial_dimension,
            nodes->storage() + conn_val[offset + n] * spatial_dimension,
            spatial_dimension * sizeof(Real));
   }
 
   Math::barycenter(local_coord, nb_nodes_per_element, spatial_dimension,
                    barycenter);
 
   delete[] local_coord;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Mesh::getBarycenter(const Element & element,
                                 Vector<Real> & barycenter) const {
   getBarycenter(element.element, element.type, barycenter.storage(),
                 element.ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbNodesPerElement(const ElementType & type) {
   UInt nb_nodes_per_element = 0;
 #define GET_NB_NODES_PER_ELEMENT(type)                                         \
   nb_nodes_per_element = ElementClass<type>::getNbNodesPerElement()
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_NODES_PER_ELEMENT);
 #undef GET_NB_NODES_PER_ELEMENT
   return nb_nodes_per_element;
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementType Mesh::getP1ElementType(const ElementType & type) {
   ElementType p1_type = _not_defined;
 #define GET_P1_TYPE(type) p1_type = ElementClass<type>::getP1ElementType()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_P1_TYPE);
 #undef GET_P1_TYPE
   return p1_type;
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementKind Mesh::getKind(const ElementType & type) {
   ElementKind kind = _ek_not_defined;
 #define GET_KIND(type) kind = ElementClass<type>::getKind()
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_KIND);
 #undef GET_KIND
   return kind;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getSpatialDimension(const ElementType & type) {
   UInt spatial_dimension = 0;
 #define GET_SPATIAL_DIMENSION(type)                                            \
   spatial_dimension = ElementClass<type>::getSpatialDimension()
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_SPATIAL_DIMENSION);
 #undef GET_SPATIAL_DIMENSION
 
   return spatial_dimension;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbFacetTypes(const ElementType & type,
                                   __attribute__((unused)) UInt t) {
   UInt nb = 0;
 #define GET_NB_FACET_TYPE(type) nb = ElementClass<type>::getNbFacetTypes()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET_TYPE);
 #undef GET_NB_FACET_TYPE
   return nb;
 }
 
 /* -------------------------------------------------------------------------- */
 inline ElementType Mesh::getFacetType(const ElementType & type, UInt t) {
   ElementType surface_type = _not_defined;
 #define GET_FACET_TYPE(type) surface_type = ElementClass<type>::getFacetType(t)
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_TYPE);
 #undef GET_FACET_TYPE
 
   return surface_type;
 }
 
 /* -------------------------------------------------------------------------- */
 inline VectorProxy<ElementType>
 Mesh::getAllFacetTypes(const ElementType & type) {
 #define GET_FACET_TYPE(type)                                                   \
   UInt nb = ElementClass<type>::getNbFacetTypes();                             \
   ElementType * elt_ptr =                                                      \
       const_cast<ElementType *>(ElementClass<type>::getFacetTypeInternal());   \
   return VectorProxy<ElementType>(elt_ptr, nb);
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_TYPE);
 #undef GET_FACET_TYPE
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbFacetsPerElement(const ElementType & type) {
   AKANTU_DEBUG_IN();
 
   UInt n_facet = 0;
 #define GET_NB_FACET(type) n_facet = ElementClass<type>::getNbFacetsPerElement()
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
 #undef GET_NB_FACET
 
   AKANTU_DEBUG_OUT();
   return n_facet;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbFacetsPerElement(const ElementType & type, UInt t) {
   AKANTU_DEBUG_IN();
 
   UInt n_facet = 0;
 #define GET_NB_FACET(type)                                                     \
   n_facet = ElementClass<type>::getNbFacetsPerElement(t)
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_NB_FACET);
 #undef GET_NB_FACET
 
   AKANTU_DEBUG_OUT();
   return n_facet;
 }
 
 /* -------------------------------------------------------------------------- */
 inline MatrixProxy<UInt>
 Mesh::getFacetLocalConnectivity(const ElementType & type, UInt t) {
   AKANTU_DEBUG_IN();
 
 #define GET_FACET_CON(type)                                                    \
   AKANTU_DEBUG_OUT();                                                          \
   return ElementClass<type>::getFacetLocalConnectivityPerElement(t)
 
   AKANTU_BOOST_ALL_ELEMENT_SWITCH(GET_FACET_CON);
 #undef GET_FACET_CON
 
   AKANTU_DEBUG_OUT();
   return MatrixProxy<UInt>(
       nullptr, 0, 0); // This avoid a compilation warning but will certainly
   // also cause a segfault if reached
 }
 
 /* -------------------------------------------------------------------------- */
 inline Matrix<UInt> Mesh::getFacetConnectivity(const Element & element,
                                                UInt t) const {
   AKANTU_DEBUG_IN();
 
   Matrix<UInt> local_facets(getFacetLocalConnectivity(element.type, t), false);
   Matrix<UInt> facets(local_facets.rows(), local_facets.cols());
 
   const Array<UInt> & conn = connectivities(element.type, element.ghost_type);
 
   for (UInt f = 0; f < facets.rows(); ++f) {
     for (UInt n = 0; n < facets.cols(); ++n) {
       facets(f, n) = conn(element.element, local_facets(f, n));
     }
   }
 
   AKANTU_DEBUG_OUT();
   return facets;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 inline void Mesh::extractNodalValuesFromElement(
     const Array<T> & nodal_values, T * local_coord, UInt * connectivity,
     UInt n_nodes, UInt nb_degree_of_freedom) const {
   for (UInt n = 0; n < n_nodes; ++n) {
     memcpy(local_coord + n * nb_degree_of_freedom,
            nodal_values.storage() + connectivity[n] * nb_degree_of_freedom,
            nb_degree_of_freedom * sizeof(T));
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void Mesh::addConnectivityType(const ElementType & type,
                                       const GhostType & ghost_type) {
   getConnectivityPointer(type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isPureGhostNode(UInt n) const {
   return nodes_type.getSize() ? (nodes_type(n) == _nt_pure_gost) : false;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isLocalOrMasterNode(UInt n) const {
   return nodes_type.getSize()
              ? (nodes_type(n) == _nt_master) || (nodes_type(n) == _nt_normal)
              : true;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isLocalNode(UInt n) const {
   return nodes_type.getSize() ? nodes_type(n) == _nt_normal : true;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isMasterNode(UInt n) const {
   return nodes_type.getSize() ? nodes_type(n) == _nt_master : false;
 }
 
 /* -------------------------------------------------------------------------- */
 inline bool Mesh::isSlaveNode(UInt n) const {
   return nodes_type.getSize() ? nodes_type(n) >= 0 : false;
 }
 
 /* -------------------------------------------------------------------------- */
 inline NodeType Mesh::getNodeType(UInt local_id) const {
   return nodes_type.getSize() ? nodes_type(local_id) : _nt_normal;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNodeGlobalId(UInt local_id) const {
   return nodes_global_ids ? (*nodes_global_ids)(local_id) : local_id;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNodeLocalId(UInt global_id) const {
   AKANTU_DEBUG_ASSERT(nodes_global_ids != NULL, "The global ids are note set.");
   return nodes_global_ids->find(global_id);
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbGlobalNodes() const {
   return nodes_global_ids ? nb_global_nodes : nodes->getSize();
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt Mesh::getNbNodesPerElementList(const Array<Element> & elements) {
   UInt nb_nodes_per_element = 0;
   UInt nb_nodes = 0;
   ElementType current_element_type = _not_defined;
 
   Array<Element>::const_iterator<Element> el_it = elements.begin();
   Array<Element>::const_iterator<Element> el_end = elements.end();
 
   for (; el_it != el_end; ++el_it) {
     const Element & el = *el_it;
 
     if (el.type != current_element_type) {
       current_element_type = el.type;
       nb_nodes_per_element = Mesh::getNbNodesPerElement(current_element_type);
     }
 
     nb_nodes += nb_nodes_per_element;
   }
 
   return nb_nodes;
 }
 
 /* -------------------------------------------------------------------------- */
 inline Mesh & Mesh::getMeshFacets() {
   if (!this->mesh_facets)
     AKANTU_EXCEPTION(
         "No facet mesh is defined yet! check the buildFacets functions");
 
   return *this->mesh_facets;
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Mesh & Mesh::getMeshFacets() const {
   if (!this->mesh_facets)
     AKANTU_EXCEPTION(
         "No facet mesh is defined yet! check the buildFacets functions");
 
   return *this->mesh_facets;
 }
 /* -------------------------------------------------------------------------- */
 inline const Mesh & Mesh::getMeshParent() const {
   if (!this->mesh_parent)
     AKANTU_EXCEPTION(
         "No parent mesh is defined! This is only valid in a mesh_facets");
 
   return *this->mesh_parent;
 }
 
 /* -------------------------------------------------------------------------- */
 
-} // akantu
+} // namespace akantu
 
 #endif /* __AKANTU_MESH_INLINE_IMPL_CC__ */
diff --git a/src/mesh/node_group.hh b/src/mesh/node_group.hh
index a1602815a..40af0023e 100644
--- a/src/mesh/node_group.hh
+++ b/src/mesh/node_group.hh
@@ -1,137 +1,141 @@
 /**
  * @file   node_group.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Tue Dec 08 2015
  *
  * @brief  Node group definition
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_array.hh"
 #include "aka_memory.hh"
 #include "mesh_filter.hh"
 #include "dumpable.hh"
 /* -------------------------------------------------------------------------- */
 
 
 
 #ifndef __AKANTU_NODE_GROUP_HH__
 #define __AKANTU_NODE_GROUP_HH__
 
 namespace akantu {
 
 class NodeGroup : public Memory, public Dumpable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
 
   NodeGroup(const std::string & name,
 	    const Mesh & mesh,
             const std::string & id = "node_group",
             const MemoryID & memory_id = 0);
   virtual ~NodeGroup();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   typedef Array<UInt>::const_iterator<UInt> const_node_iterator;
 
   /// empty the node group
   void empty();
 
   /// iterator to the beginning of the node group
   inline const_node_iterator begin() const;
   /// iterator to the end of the node group
   inline const_node_iterator end() const;
 
   /// add a node and give the local position through an iterator
   inline const_node_iterator add(UInt node, bool check_for_duplicate = true);
 
   /// remove a node
   inline void remove(UInt node);
 
+  inline decltype(auto) find(UInt node) const {
+    return node_group.find(node);
+  }
+  
   /// remove duplicated nodes
   void optimize();
 
   /// append a group to current one
   void append(const NodeGroup & other_group);
 
   /// apply a filter on current node group
   template <typename T>
   void applyNodeFilter(T & filter);
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
 
   AKANTU_GET_MACRO_NOT_CONST(Nodes, node_group, Array<UInt> &);
   AKANTU_GET_MACRO(Nodes, node_group, const Array<UInt> &);
   AKANTU_GET_MACRO(Name, name, const std::string &);
 
   /// give the number of nodes in the current group
   inline UInt getSize() const;
 
   UInt * storage(){return node_group.storage();};
   
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// name of the group
   std::string name;
 
   /// list of nodes in the group
   Array<UInt> & node_group;
 
   /// reference to the mesh in question
   //const Mesh & mesh;
 };
 
 /// standard output stream operator
 inline std::ostream & operator <<(std::ostream & stream, const NodeGroup & _this)
 {
   _this.printself(stream);
   return stream;
 }
 
 } // akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "node_group_inline_impl.cc"
 
 
 
 #endif /* __AKANTU_NODE_GROUP_HH__ */
diff --git a/src/mesh_utils/cohesive_element_inserter.cc b/src/mesh_utils/cohesive_element_inserter.cc
index 1e282c93f..587afc25c 100644
--- a/src/mesh_utils/cohesive_element_inserter.cc
+++ b/src/mesh_utils/cohesive_element_inserter.cc
@@ -1,451 +1,458 @@
 /**
  * @file   cohesive_element_inserter.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Dec 04 2013
  * @date last modification: Sun Oct 04 2015
  *
  * @brief  Cohesive element inserter functions
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "cohesive_element_inserter.hh"
 #include "element_group.hh"
 #include <algorithm>
 #include <limits>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 CohesiveElementInserter::CohesiveElementInserter(Mesh & mesh, bool is_extrinsic,
                                                  const ID & id)
     : id(id), mesh(mesh), mesh_facets(mesh.initMeshFacets()),
       insertion_facets("insertion_facets", id),
       insertion_limits(mesh.getSpatialDimension(), 2),
       check_facets("check_facets", id) {
 
   MeshUtils::buildAllFacets(mesh, mesh_facets, 0);
   init(is_extrinsic);
 }
 
 /* -------------------------------------------------------------------------- */
 CohesiveElementInserter::~CohesiveElementInserter() {
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   delete global_ids_updater;
 #endif
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::init(bool is_extrinsic) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   MeshUtils::resetFacetToDouble(mesh_facets);
 
   /// initialize facet insertion array
   insertion_facets.initialize(mesh_facets,
                               _spatial_dimension = (spatial_dimension - 1),
                               _with_nb_element = true);
   // mesh_facets.initElementTypeMapArray(
   //     insertion_facets, 1, spatial_dimension - 1, false, _ek_regular, true);
 
   /// init insertion limits
   for (UInt dim = 0; dim < spatial_dimension; ++dim) {
     insertion_limits(dim, 0) = std::numeric_limits<Real>::max() * (-1.);
     insertion_limits(dim, 1) = std::numeric_limits<Real>::max();
   }
 
   if (is_extrinsic) {
     check_facets.initialize(mesh_facets,
                             _spatial_dimension = spatial_dimension - 1);
     // mesh_facets.initElementTypeMapArray(check_facets, 1, spatial_dimension -
     // 1);
     initFacetsCheck();
   }
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   facet_synchronizer = NULL;
   global_ids_updater = NULL;
 #endif
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::initFacetsCheck() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType facet_gt = *gt;
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, facet_gt);
     Mesh::type_iterator last =
         mesh_facets.lastType(spatial_dimension - 1, facet_gt);
 
     for (; it != last; ++it) {
       ElementType facet_type = *it;
 
       Array<bool> & f_check = check_facets(facet_type, facet_gt);
 
       const Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(facet_type, facet_gt);
 
       UInt nb_facet = element_to_facet.getSize();
       f_check.resize(nb_facet);
 
       for (UInt f = 0; f < nb_facet; ++f) {
         if (element_to_facet(f)[1] == ElementNull ||
             (element_to_facet(f)[0].ghost_type == _ghost &&
              element_to_facet(f)[1].ghost_type == _ghost)) {
           f_check(f) = false;
         } else
           f_check(f) = true;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::limitCheckFacets() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   Vector<Real> bary_facet(spatial_dimension);
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, ghost_type);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, ghost_type);
     for (; it != end; ++it) {
       ElementType type = *it;
       Array<bool> & f_check = check_facets(type, ghost_type);
       UInt nb_facet = mesh_facets.getNbElement(type, ghost_type);
 
       for (UInt f = 0; f < nb_facet; ++f) {
         if (f_check(f)) {
 
           mesh_facets.getBarycenter(f, type, bary_facet.storage(), ghost_type);
 
           UInt coord_in_limit = 0;
 
           while (coord_in_limit < spatial_dimension &&
                  bary_facet(coord_in_limit) >
                      insertion_limits(coord_in_limit, 0) &&
                  bary_facet(coord_in_limit) <
                      insertion_limits(coord_in_limit, 1))
             ++coord_in_limit;
 
           if (coord_in_limit != spatial_dimension)
             f_check(f) = false;
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::setLimit(SpacialDirection axis, Real first_limit,
                                        Real second_limit) {
 
   AKANTU_DEBUG_ASSERT(
       axis < mesh.getSpatialDimension(),
       "You are trying to limit insertion in a direction that doesn't exist");
 
   insertion_limits(axis, 0) = std::min(first_limit, second_limit);
   insertion_limits(axis, 1) = std::max(first_limit, second_limit);
 }
 
 /* -------------------------------------------------------------------------- */
 UInt CohesiveElementInserter::insertIntrinsicElements() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   Vector<Real> bary_facet(spatial_dimension);
 
   for (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) {
       const ElementType type_facet = *it;
       Array<bool> & f_insertion = insertion_facets(type_facet, ghost_type);
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, ghost_type);
 
       UInt nb_facet = mesh_facets.getNbElement(type_facet, ghost_type);
 
       for (UInt f = 0; f < nb_facet; ++f) {
 
         if (element_to_facet(f)[1] == ElementNull)
           continue;
 
         mesh_facets.getBarycenter(f, type_facet, bary_facet.storage(),
                                   ghost_type);
 
         UInt coord_in_limit = 0;
 
         while (coord_in_limit < spatial_dimension &&
                bary_facet(coord_in_limit) >
                    insertion_limits(coord_in_limit, 0) &&
                bary_facet(coord_in_limit) < insertion_limits(coord_in_limit, 1))
           ++coord_in_limit;
 
         if (coord_in_limit == spatial_dimension)
           f_insertion(f) = true;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 
   return insertElements();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::insertIntrinsicElements(std::string physname,
                                                       UInt material_index) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   ElementTypeMapArray<UInt> * phys_data;
   try {
     phys_data = &(mesh_facets.getData<UInt>("physical_names"));
   } catch (...) {
     phys_data = &(mesh_facets.registerData<UInt>("physical_names"));
     phys_data->initialize(mesh_facets,
                           _spatial_dimension = spatial_dimension - 1,
                           _with_nb_element = true);
     // mesh_facets.initElementTypeMapArray(*phys_data, 1, spatial_dimension - 1,
     //                                     false, _ek_regular, true);
   }
   Vector<Real> bary_facet(spatial_dimension);
   mesh_facets.createElementGroup(physname);
 
   GhostType ghost_type = _not_ghost;
 
   Mesh::type_iterator it =
       mesh_facets.firstType(spatial_dimension - 1, ghost_type);
   Mesh::type_iterator end =
       mesh_facets.lastType(spatial_dimension - 1, ghost_type);
 
   for (; it != end; ++it) {
     const ElementType type_facet = *it;
     Array<bool> & f_insertion = insertion_facets(type_facet, ghost_type);
     Array<std::vector<Element>> & element_to_facet =
         mesh_facets.getElementToSubelement(type_facet, ghost_type);
 
     UInt nb_facet = mesh_facets.getNbElement(type_facet, ghost_type);
     UInt coord_in_limit = 0;
 
     ElementGroup & group = mesh.getElementGroup(physname);
     ElementGroup & group_facet = mesh_facets.getElementGroup(physname);
 
     Vector<Real> bary_physgroup(spatial_dimension);
     Real norm_bary;
     for (ElementGroup::const_element_iterator el_it(
-             group.element_begin(type_facet, ghost_type));
-         el_it != group.element_end(type_facet, ghost_type); ++el_it) {
+             group.begin(type_facet, ghost_type));
+         el_it != group.end(type_facet, ghost_type); ++el_it) {
 
       UInt e = *el_it;
       mesh.getBarycenter(e, type_facet, bary_physgroup.storage(), ghost_type);
 #ifndef AKANTU_NDEBUG
       bool find_a_partner = false;
 #endif
       norm_bary = bary_physgroup.norm();
       Array<UInt> & material_id = (*phys_data)(type_facet, ghost_type);
 
       for (UInt f = 0; f < nb_facet; ++f) {
 
         if (element_to_facet(f)[1] == ElementNull)
           continue;
 
         mesh_facets.getBarycenter(f, type_facet, bary_facet.storage(),
                                   ghost_type);
 
         coord_in_limit = 0;
 
         while (coord_in_limit < spatial_dimension &&
                (std::abs(bary_facet(coord_in_limit) -
                          bary_physgroup(coord_in_limit)) /
                     norm_bary <
                 Math::getTolerance()))
           ++coord_in_limit;
 
         if (coord_in_limit == spatial_dimension) {
           f_insertion(f) = true;
 #ifndef AKANTU_NDEBUG
           find_a_partner = true;
 #endif
           group_facet.add(type_facet, f, ghost_type, false);
           material_id(f) = material_index;
           break;
         }
       }
       AKANTU_DEBUG_ASSERT(find_a_partner,
                           "The element nO "
                               << e << " of physical group " << physname
                               << " did not find its associated facet!"
                               << " Try to decrease math tolerance. "
                               << std::endl);
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt CohesiveElementInserter::insertElements(bool only_double_facets) {
 
-  NewNodesEvent node_event;
-  node_event.getList().extendComponentsInterlaced(2, 1);
+  CohesiveNewNodesEvent node_event;
   NewElementsEvent element_event;
 
+  Array<UInt> new_pairs(0, 2);
+
   UInt nb_new_elements = MeshUtils::insertCohesiveElements(
-      mesh, mesh_facets, insertion_facets, node_event.getList(),
+      mesh, mesh_facets, insertion_facets, new_pairs,
       element_event.getList(), only_double_facets);
 
-  UInt nb_new_nodes = node_event.getList().getSize();
+  UInt nb_new_nodes = new_pairs.getSize();
+  node_event.getList().reserve(nb_new_nodes);
+  node_event.getOldNodesList().reserve(nb_new_nodes);
+  for(UInt n = 0; n < nb_new_nodes; ++n) {
+    node_event.getList().push_back(new_pairs(n, 1));
+    node_event.getOldNodesList().push_back(new_pairs(n, 0));
+  }
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   if (mesh.getNodesType().getSize()) {
 
     /// update nodes type
     updateNodesType(mesh, node_event);
     updateNodesType(mesh_facets, node_event);
 
     /// update global ids
     nb_new_nodes = this->updateGlobalIDs(node_event);
 
     /// compute total number of new elements
     StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
     comm.allReduce(&nb_new_elements, 1, _so_sum);
   }
 #endif
 
   if (nb_new_nodes > 0)
     mesh.sendEvent(node_event);
 
   if (nb_new_elements > 0) {
     updateInsertionFacets();
-    mesh.updateTypesOffsets(_not_ghost);
+    //mesh.updateTypesOffsets(_not_ghost);
     mesh.sendEvent(element_event);
     MeshUtils::resetFacetToDouble(mesh_facets);
   }
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   if (mesh.getNodesType().getSize()) {
     /// update global ids
     this->synchronizeGlobalIDs(node_event);
   }
 #endif
 
   return nb_new_elements;
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::updateInsertionFacets() {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType facet_gt = *gt;
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, facet_gt);
     Mesh::type_iterator last =
         mesh_facets.lastType(spatial_dimension - 1, facet_gt);
 
     for (; it != last; ++it) {
       ElementType facet_type = *it;
 
       Array<bool> & ins_facets = insertion_facets(facet_type, facet_gt);
 
       // this is the extrinsic case
       if (check_facets.exists(facet_type, facet_gt)) {
         Array<bool> & f_check = check_facets(facet_type, facet_gt);
 
         UInt nb_facets = f_check.getSize();
 
         for (UInt f = 0; f < ins_facets.getSize(); ++f) {
           if (ins_facets(f)) {
             ++nb_facets;
             ins_facets(f) = false;
             f_check(f) = false;
           }
         }
 
         f_check.resize(nb_facets);
       }
       // and this the intrinsic one
       else {
         ins_facets.resize(mesh_facets.getNbElement(facet_type, facet_gt));
         ins_facets.set(false);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void CohesiveElementInserter::printself(std::ostream & stream,
                                         int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   stream << space << "CohesiveElementInserter [" << std::endl;
 
   stream << space << " + mesh [" << std::endl;
   mesh.printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << " + mesh_facets [" << std::endl;
   mesh_facets.printself(stream, indent + 2);
   stream << space << AKANTU_INDENT << "]" << std::endl;
 
   stream << space << "]" << std::endl;
 }
 
 } // namespace akantu
diff --git a/src/mesh_utils/cohesive_element_inserter.hh b/src/mesh_utils/cohesive_element_inserter.hh
index 14620c62a..0377b3191 100644
--- a/src/mesh_utils/cohesive_element_inserter.hh
+++ b/src/mesh_utils/cohesive_element_inserter.hh
@@ -1,211 +1,223 @@
 /**
  * @file   cohesive_element_inserter.hh
  *
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Wed Dec 04 2013
  * @date last modification: Fri Oct 02 2015
  *
  * @brief  Cohesive element inserter
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
 #define __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "data_accessor.hh"
 #include "mesh_utils.hh"
 #include <numeric>
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
 #include "facet_synchronizer.hh"
 #include "global_ids_updater.hh"
 #endif
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class CohesiveElementInserter : public DataAccessor<Element> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   CohesiveElementInserter(Mesh & mesh, bool is_extrinsic = false,
                           const ID & id = "cohesive_element_inserter");
 
   virtual ~CohesiveElementInserter();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// init function
   void init(bool is_extrinsic);
 
   /// set range limitation for intrinsic cohesive element insertion
   void setLimit(SpacialDirection axis, Real first_limit, Real second_limit);
 
   /// insert intrinsic cohesive elements in a predefined range
   UInt insertIntrinsicElements();
 
   /// preset insertion of intrinsic cohesive elements along
   /// a predefined group of facet and assign them a defined material index.
   /// insertElement() method has to be called to finalize insertion.
   void insertIntrinsicElements(std::string physname, UInt material_index);
 
   /// insert extrinsic cohesive elements (returns the number of new
   /// cohesive elements)
   UInt insertElements(bool only_double_facets = false);
 
   /// function to print the contain of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /// limit check facets to match given insertion limits
   void limitCheckFacets();
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   /// init parallel variables
   void initParallel(FacetSynchronizer * facet_synchronizer,
                     ElementSynchronizer * element_synchronizer);
 #endif
 
 protected:
   /// init facets check
   void initFacetsCheck();
 
   /// update facet insertion arrays after facets doubling
   void updateInsertionFacets();
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   /// update nodes type and global ids for parallel simulations
   /// (locally, within each processor)
   UInt updateGlobalIDs(NewNodesEvent & node_event);
 
   /// synchronize the global ids among the processors in parallel simulations
   void synchronizeGlobalIDs(NewNodesEvent & node_event);
 
   /// update nodes type
   void updateNodesType(Mesh & mesh, NewNodesEvent & node_event);
 
   /// functions for parallel communications
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   template <bool pack_mode>
   inline void
   packUnpackGlobalConnectivity(CommunicationBuffer & buffer,
                                const Array<Element> & elements) const;
 
   template <bool pack_mode>
   inline void
   packUnpackGroupedInsertionData(CommunicationBuffer & buffer,
                                  const Array<Element> & elements) const;
 #else
   /// functions for parallel communications
   inline UInt getNbData(const Array<Element> &,
                         const SynchronizationTag &) const override {
     return 0;
   }
 
   inline void packData(CommunicationBuffer &, const Array<Element> &,
                        const SynchronizationTag &) const override {}
 
   inline void unpackData(CommunicationBuffer &, const Array<Element> &,
                          const SynchronizationTag &) override {}
 #endif
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO_NOT_CONST(InsertionFacetsByElement, insertion_facets,
                              ElementTypeMapArray<bool> &);
 
   AKANTU_GET_MACRO(InsertionFacetsByElement, insertion_facets,
                    const ElementTypeMapArray<bool> &);
 
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(InsertionFacets, insertion_facets, bool);
 
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(CheckFacets, check_facets, bool);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(CheckFacets, check_facets, bool);
   AKANTU_GET_MACRO(MeshFacets, mesh_facets, const Mesh &);
   AKANTU_GET_MACRO_NOT_CONST(MeshFacets, mesh_facets, Mesh &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// object id
   ID id;
 
   /// main mesh where to insert cohesive elements
   Mesh & mesh;
 
   /// mesh containing facets
   Mesh & mesh_facets;
 
   /// list of facets where to insert elements
   ElementTypeMapArray<bool> insertion_facets;
 
   /// limits for element insertion
   Array<Real> insertion_limits;
 
   /// vector containing facets in which extrinsic cohesive elements can be
   /// inserted
   ElementTypeMapArray<bool> check_facets;
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
   /// facet synchronizer
   FacetSynchronizer * facet_synchronizer;
 
   /// global connectivity ids updater
   GlobalIdsUpdater * global_ids_updater;
 #endif
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #if defined(AKANTU_PARALLEL_COHESIVE_ELEMENT)
 #include "cohesive_element_inserter_inline_impl.cc"
 #endif
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const CohesiveElementInserter & _this) {
   _this.printself(stream);
   return stream;
 }
 
+class CohesiveNewNodesEvent : public NewNodesEvent{
+public:
+  CohesiveNewNodesEvent() = default;
+  virtual ~CohesiveNewNodesEvent() = default;
+
+  AKANTU_GET_MACRO_NOT_CONST(OldNodesList, old_nodes, Array<UInt> &);
+  AKANTU_GET_MACRO(OldNodesList, old_nodes, const Array<UInt> &);
+private:
+  Array<UInt> old_nodes;
+};
+
+
 } // akantu
 
 #endif /* __AKANTU_COHESIVE_ELEMENT_INSERTER_HH__ */
diff --git a/src/mesh_utils/mesh_partition.cc b/src/mesh_utils/mesh_partition.cc
index 648214182..01ee4574f 100644
--- a/src/mesh_utils/mesh_partition.cc
+++ b/src/mesh_utils/mesh_partition.cc
@@ -1,441 +1,410 @@
 /**
  * @file   mesh_partition.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Aug 17 2010
  * @date last modification: Fri Jan 22 2016
  *
  * @brief  implementation of common part of all partitioner
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "mesh_partition.hh"
-#include "mesh_utils.hh"
 #include "aka_types.hh"
+#include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 #include <unordered_map>
 /* -------------------------------------------------------------------------- */
 
-
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MeshPartition::MeshPartition(const Mesh & mesh, UInt spatial_dimension,
                              const ID & id, const MemoryID & memory_id)
     : Memory(id, memory_id), mesh(mesh), spatial_dimension(spatial_dimension),
       partitions("partition", id, memory_id),
       ghost_partitions("ghost_partition", id, memory_id),
       ghost_partitions_offset("ghost_partition_offset", id, memory_id),
       saved_connectivity("saved_connectivity", id, memory_id) {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 MeshPartition::~MeshPartition() {
   AKANTU_DEBUG_IN();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * TODO this function should most probably be rewritten in a more modern way
  * conversion in c++ of the GENDUALMETIS (mesh.c) function wrote by George in
  * Metis (University of Minnesota)
  */
 void MeshPartition::buildDualGraph(Array<Int> & dxadj, Array<Int> & dadjncy,
                                    Array<Int> & edge_loads,
                                    const EdgeLoadFunctor & edge_load_func) {
   AKANTU_DEBUG_IN();
 
   // tweak mesh;
-  const Mesh::ConnectivityTypeList & type_list = mesh.getConnectivityTypeList();
-  UInt nb_types = type_list.size();
   UInt nb_good_types = 0;
 
-  Vector<UInt> nb_nodes_per_element_p1(nb_types);
-
-  Vector<UInt> magic_number(nb_types);
-
-  //  UInt * conn_val[nb_types];
-  Vector<UInt> nb_element(nb_types);
-
-  Array<UInt> ** conn = new Array<UInt> *[nb_types];
-
-  Array<Element> lin_to_element;
+  std::vector<UInt> nb_nodes_per_element_p1;
+  std::vector<UInt> magic_number;
+  std::vector<UInt> nb_element;
+  std::vector<Array<UInt> *> conn;
 
   Element elem;
   elem.ghost_type = _not_ghost;
 
-  const_cast<Mesh &>(mesh).updateTypesOffsets(_not_ghost);
-  const_cast<Mesh &>(mesh).updateTypesOffsets(_ghost);
+  UInt spatial_dimension = mesh.getSpatialDimension();
 
-  Mesh::ConnectivityTypeList::const_iterator it;
-  for (it = type_list.begin(); it != type_list.end(); ++it) {
-    ElementType type = *it;
-    if (Mesh::getSpatialDimension(type) != mesh.getSpatialDimension())
-      continue;
+  for (auto & type :
+       mesh.elementTypes(spatial_dimension, _not_ghost, _ek_not_defined)) {
     elem.type = type;
 
     ElementType type_p1 = Mesh::getP1ElementType(type);
 
-    nb_nodes_per_element_p1[nb_good_types] =
-        Mesh::getNbNodesPerElement(type_p1);
-    nb_element[nb_good_types] =
-        mesh.getConnectivity(type, _not_ghost).getSize();
-    magic_number[nb_good_types] =
-        Mesh::getNbNodesPerElement(Mesh::getFacetType(type_p1));
-
-    conn[nb_good_types] =
-        &const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
+    conn.push_back(
+        &const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost)));
+    nb_nodes_per_element_p1.push_back(Mesh::getNbNodesPerElement(type_p1));
+    nb_element.push_back(conn.back()->getSize());
+    magic_number.push_back(
+        Mesh::getNbNodesPerElement(Mesh::getFacetType(type_p1)));
 
-    for (UInt i = 0; i < nb_element[nb_good_types]; ++i) {
+    for (UInt i = 0; i < nb_element.back(); ++i) {
       elem.element = i;
       lin_to_element.push_back(elem);
     }
 
-    nb_good_types++;
+    ++nb_good_types;
   }
 
-  CSR<UInt> node_to_elem;
+  CSR<Element> node_to_elem;
 
   MeshUtils::buildNode2Elements(mesh, node_to_elem);
 
   UInt nb_total_element = 0;
   UInt nb_total_node_element = 0;
   for (UInt t = 0; t < nb_good_types; ++t) {
     nb_total_element += nb_element[t];
     nb_total_node_element += nb_element[t] * nb_nodes_per_element_p1[t];
   }
 
   dxadj.resize(nb_total_element + 1);
 
   /// initialize the dxadj array
   for (UInt t = 0, linerized_el = 0; t < nb_good_types; ++t)
     for (UInt el = 0; el < nb_element[t]; ++el, ++linerized_el)
       dxadj(linerized_el) = nb_nodes_per_element_p1[t];
 
   /// convert the dxadj_val array in a csr one
   for (UInt i = 1; i < nb_total_element; ++i)
     dxadj(i) += dxadj(i - 1);
   for (UInt i = nb_total_element; i > 0; --i)
     dxadj(i) = dxadj(i - 1);
   dxadj(0) = 0;
 
   dadjncy.resize(2 * dxadj(nb_total_element));
   edge_loads.resize(2 * dxadj(nb_total_element));
 
   /// weight map to determine adjacency
   std::unordered_map<UInt, UInt> weight_map;
 
   for (UInt t = 0, linerized_el = 0; t < nb_good_types; ++t) {
     for (UInt el = 0; el < nb_element[t]; ++el, ++linerized_el) {
       /// fill the weight map
       for (UInt n = 0; n < nb_nodes_per_element_p1[t]; ++n) {
         UInt node = (*conn[t])(el, n);
-        CSR<UInt>::iterator k;
+        CSR<Element>::iterator k;
         for (k = node_to_elem.rbegin(node); k != node_to_elem.rend(node); --k) {
-          UInt current_el = *k;
+          Element current_element = *k;
+          UInt current_el = lin_to_element.find(current_element);
+
           if (current_el <= linerized_el)
             break;
 
           auto it_w = weight_map.find(current_el);
 
           if (it_w == weight_map.end()) {
             weight_map[current_el] = 1;
           } else {
             it_w->second++;
           }
         }
       }
       /// each element with a weight of the size of a facet are adjacent
       for (auto it_w = weight_map.begin(); it_w != weight_map.end(); ++it_w) {
         if (it_w->second == magic_number[t]) {
           UInt adjacent_el = it_w->first;
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
           /// Patch in order to prevent neighboring cohesive elements
           /// from detecting each other
-          ElementKind linearized_el_kind =
-              mesh.linearizedToElement(linerized_el).kind;
-          ElementKind adjacent_el_kind =
-              mesh.linearizedToElement(adjacent_el).kind;
+          ElementKind linearized_el_kind = lin_to_element(linerized_el).kind;
+          ElementKind adjacent_el_kind = lin_to_element(adjacent_el).kind;
 
           if (linearized_el_kind == adjacent_el_kind &&
               linearized_el_kind == _ek_cohesive)
             continue;
 #endif
 
           UInt index_adj = dxadj(adjacent_el)++;
           UInt index_lin = dxadj(linerized_el)++;
 
           dadjncy(index_lin) = adjacent_el;
           dadjncy(index_adj) = linerized_el;
         }
       }
 
       weight_map.clear();
     }
   }
 
   Int k_start = 0;
   for (UInt t = 0, linerized_el = 0, j = 0; t < nb_good_types; ++t)
     for (UInt el = 0; el < nb_element[t]; ++el, ++linerized_el) {
       for (Int k = k_start; k < dxadj(linerized_el); ++k, ++j)
         dadjncy(j) = dadjncy(k);
       dxadj(linerized_el) = j;
       k_start += nb_nodes_per_element_p1[t];
     }
 
   for (UInt i = nb_total_element; i > 0; --i)
     dxadj(i) = dxadj(i - 1);
   dxadj(0) = 0;
 
   UInt adj = 0;
   for (UInt i = 0; i < nb_total_element; ++i) {
     UInt nb_adj = dxadj(i + 1) - dxadj(i);
     for (UInt j = 0; j < nb_adj; ++j, ++adj) {
       Int el_adj_id = dadjncy(dxadj(i) + j);
       Element el = lin_to_element(i);
       Element el_adj = lin_to_element(el_adj_id);
 
       Int load = edge_load_func(el, el_adj);
       edge_loads(adj) = load;
     }
   }
 
-  delete [] conn;
-
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartition::fillPartitionInformation(
     const Mesh & mesh, const Int * linearized_partitions) {
   AKANTU_DEBUG_IN();
 
-  CSR<UInt> node_to_elem;
+  CSR<Element> node_to_elem;
 
   MeshUtils::buildNode2Elements(mesh, node_to_elem);
 
-  Mesh::type_iterator it =
-      mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
-  Mesh::type_iterator end =
-      mesh.lastType(spatial_dimension, _not_ghost, _ek_not_defined);
-
   UInt linearized_el = 0;
-  for (; it != end; ++it) {
-    ElementType type = *it;
-
+  for (auto & type : mesh.elementTypes(spatial_dimension, _not_ghost, _ek_not_defined)) {
     UInt nb_element = mesh.getNbElement(type);
     UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
     partitions.alloc(nb_element, 1, type, _not_ghost);
-    CSR<UInt> & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
+    auto & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
     ghost_part_csr.resizeRows(nb_element);
 
     ghost_partitions_offset.alloc(nb_element + 1, 1, type, _ghost);
     ghost_partitions.alloc(0, 1, type, _ghost);
 
     const Array<UInt> & connectivity = mesh.getConnectivity(type, _not_ghost);
 
     for (UInt el = 0; el < nb_element; ++el, ++linearized_el) {
       UInt part = linearized_partitions[linearized_el];
 
       partitions(type, _not_ghost)(el) = part;
       std::list<UInt> list_adj_part;
       for (UInt n = 0; n < nb_nodes_per_element; ++n) {
         UInt node = connectivity.storage()[el * nb_nodes_per_element + n];
-        CSR<UInt>::iterator ne;
+        CSR<Element>::iterator ne;
         for (ne = node_to_elem.begin(node); ne != node_to_elem.end(node);
              ++ne) {
-          UInt adj_el = *ne;
+          const Element & adj_element = *ne;
+          UInt adj_el = lin_to_element.find(adj_element);
           UInt adj_part = linearized_partitions[adj_el];
           if (part != adj_part) {
             list_adj_part.push_back(adj_part);
           }
         }
       }
 
       list_adj_part.sort();
       list_adj_part.unique();
 
-      for (std::list<UInt>::iterator adj_it = list_adj_part.begin();
-           adj_it != list_adj_part.end(); ++adj_it) {
-        ghost_part_csr.getRows().push_back(*adj_it);
+      for (auto & adj_part : list_adj_part) {
+        ghost_part_csr.getRows().push_back(adj_part);
         ghost_part_csr.rowOffset(el)++;
 
-        ghost_partitions(type, _ghost).push_back(*adj_it);
+        ghost_partitions(type, _ghost).push_back(adj_part);
         ghost_partitions_offset(type, _ghost)(el)++;
       }
     }
 
     ghost_part_csr.countToCSR();
 
     /// convert the ghost_partitions_offset array in an offset array
     Array<UInt> & ghost_partitions_offset_ptr =
         ghost_partitions_offset(type, _ghost);
     for (UInt i = 1; i < nb_element; ++i)
       ghost_partitions_offset_ptr(i) += ghost_partitions_offset_ptr(i - 1);
     for (UInt i = nb_element; i > 0; --i)
       ghost_partitions_offset_ptr(i) = ghost_partitions_offset_ptr(i - 1);
     ghost_partitions_offset_ptr(0) = 0;
   }
 
   // All Facets
   for (Int sp = spatial_dimension - 1; sp >= 0; --sp) {
-    Mesh::type_iterator fit = mesh.firstType(sp, _not_ghost, _ek_not_defined);
-    Mesh::type_iterator fend = mesh.lastType(sp, _not_ghost, _ek_not_defined);
-
-    for (; fit != fend; ++fit) {
-      ElementType type = *fit;
-
+    for (auto & type : mesh.elementTypes(sp, _not_ghost, _ek_not_defined)) {
       UInt nb_element = mesh.getNbElement(type);
 
       partitions.alloc(nb_element, 1, type, _not_ghost);
       AKANTU_DEBUG_INFO("Allocating partitions for " << type);
-      CSR<UInt> & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
+      auto & ghost_part_csr = ghost_partitions_csr(type, _not_ghost);
       ghost_part_csr.resizeRows(nb_element);
 
       ghost_partitions_offset.alloc(nb_element + 1, 1, type, _ghost);
       ghost_partitions.alloc(0, 1, type, _ghost);
       AKANTU_DEBUG_INFO("Allocating ghost_partitions for " << type);
-      const Array<std::vector<Element> > & elem_to_subelem =
+      const Array<std::vector<Element>> & elem_to_subelem =
           mesh.getElementToSubelement(type, _not_ghost);
       for (UInt i(0); i < mesh.getNbElement(type, _not_ghost);
            ++i) { // Facet loop
 
         const std::vector<Element> & adjacent_elems = elem_to_subelem(i);
         if (!adjacent_elems.empty()) {
           Element min_elem;
           UInt min_part(std::numeric_limits<UInt>::max());
           std::set<UInt> adjacent_parts;
 
           for (UInt j(0); j < adjacent_elems.size(); ++j) {
             UInt adjacent_elem_id = adjacent_elems[j].element;
             UInt adjacent_elem_part =
                 partitions(adjacent_elems[j].type,
                            adjacent_elems[j].ghost_type)(adjacent_elem_id);
             if (adjacent_elem_part < min_part) {
               min_part = adjacent_elem_part;
               min_elem = adjacent_elems[j];
             }
             adjacent_parts.insert(adjacent_elem_part);
           }
           partitions(type, _not_ghost)(i) = min_part;
 
-          CSR<UInt>::iterator git =
+          auto git =
               ghost_partitions_csr(min_elem.type, _not_ghost)
                   .begin(min_elem.element);
-          CSR<UInt>::iterator gend =
+          auto gend =
               ghost_partitions_csr(min_elem.type, _not_ghost)
                   .end(min_elem.element);
           for (; git != gend; ++git) {
-            adjacent_parts.insert(*git);
+
+            adjacent_parts.insert(min_part);
           }
           adjacent_parts.erase(min_part);
-          std::set<UInt>::const_iterator pit = adjacent_parts.begin();
-          std::set<UInt>::const_iterator pend = adjacent_parts.end();
-          for (; pit != pend; ++pit) {
-            ghost_part_csr.getRows().push_back(*pit);
+          for (auto & part : adjacent_parts) {
+            ghost_part_csr.getRows().push_back(part);
             ghost_part_csr.rowOffset(i)++;
-            ghost_partitions(type, _ghost).push_back(*pit);
+            ghost_partitions(type, _ghost).push_back(part);
           }
 
           ghost_partitions_offset(type, _ghost)(i + 1) =
               ghost_partitions_offset(type, _ghost)(i + 1) +
               adjacent_elems.size();
         } else {
           partitions(type, _not_ghost)(i) = 0;
         }
       }
       ghost_part_csr.countToCSR();
     }
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartition::tweakConnectivity(const Array<UInt> & pairs) {
   AKANTU_DEBUG_IN();
 
   if (pairs.getSize() == 0)
     return;
 
   Mesh::type_iterator it =
       mesh.firstType(spatial_dimension, _not_ghost, _ek_not_defined);
   Mesh::type_iterator end =
       mesh.lastType(spatial_dimension, _not_ghost, _ek_not_defined);
 
   for (; it != end; ++it) {
     ElementType type = *it;
 
     Array<UInt> & conn =
         const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
     UInt nb_nodes_per_element = conn.getNbComponent();
     UInt nb_element = conn.getSize();
 
     Array<UInt> & saved_conn = saved_connectivity.alloc(
         nb_element, nb_nodes_per_element, type, _not_ghost);
     saved_conn.copy(conn);
 
     for (UInt i = 0; i < pairs.getSize(); ++i) {
       for (UInt el = 0; el < nb_element; ++el) {
         for (UInt n = 0; n < nb_nodes_per_element; ++n) {
           if (pairs(i, 1) == conn(el, n))
             conn(el, n) = pairs(i, 0);
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshPartition::restoreConnectivity() {
   AKANTU_DEBUG_IN();
 
   ElementTypeMapArray<UInt>::type_iterator it = saved_connectivity.firstType(
       spatial_dimension, _not_ghost, _ek_not_defined);
   ElementTypeMapArray<UInt>::type_iterator end = saved_connectivity.lastType(
       spatial_dimension, _not_ghost, _ek_not_defined);
   for (; it != end; ++it) {
     ElementType type = *it;
 
     Array<UInt> & conn =
         const_cast<Array<UInt> &>(mesh.getConnectivity(type, _not_ghost));
     Array<UInt> & saved_conn = saved_connectivity(type, _not_ghost);
     conn.copy(saved_conn);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
-} // akantu
+} // namespace akantu
diff --git a/src/mesh_utils/mesh_partition.hh b/src/mesh_utils/mesh_partition.hh
index 849530369..0d3ad6346 100644
--- a/src/mesh_utils/mesh_partition.hh
+++ b/src/mesh_utils/mesh_partition.hh
@@ -1,150 +1,152 @@
 /**
  * @file   mesh_partition.hh
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Tue Sep 01 2015
  *
  * @brief  tools to partitionate a mesh
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MESH_PARTITION_HH__
 #define __AKANTU_MESH_PARTITION_HH__
 
 /* -------------------------------------------------------------------------- */
-#include "aka_memory.hh"
 #include "aka_csr.hh"
+#include "aka_memory.hh"
 #include "mesh.hh"
 
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 class MeshPartition : protected Memory {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
-
   MeshPartition(const Mesh & mesh, UInt spatial_dimension,
                 const ID & id = "MeshPartitioner",
-		const MemoryID & memory_id = 0);
+                const MemoryID & memory_id = 0);
 
   virtual ~MeshPartition();
 
   class EdgeLoadFunctor {
   public:
     virtual Int operator()(__attribute__((unused)) const Element & el1,
-			   __attribute__((unused)) const Element & el2) const = 0;
+                           __attribute__((unused))
+                           const Element & el2) const = 0;
   };
 
   class ConstEdgeLoadFunctor : public EdgeLoadFunctor {
   public:
     virtual inline Int operator()(__attribute__((unused)) const Element & el1,
-				  __attribute__((unused)) const Element & el2) const {
+                                  __attribute__((unused))
+                                  const Element & el2) const {
       return 1;
     }
   };
 
-
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// define a partition of the mesh
-  virtual void partitionate(UInt nb_part,
-			    const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
-			    const Array<UInt> & pairs = Array<UInt>()) = 0;
+  virtual void
+  partitionate(UInt nb_part,
+               const EdgeLoadFunctor & edge_load_func = ConstEdgeLoadFunctor(),
+               const Array<UInt> & pairs = Array<UInt>()) = 0;
 
   /// reorder the nodes to reduce the filling during the factorization of a
   /// matrix that has a profil based on the connectivity of the mesh
   virtual void reorder() = 0;
 
   /// fill the partitions array with a given linearized partition information
-  void fillPartitionInformation(const Mesh & mesh, const Int * linearized_partitions);
+  void fillPartitionInformation(const Mesh & mesh,
+                                const Int * linearized_partitions);
 
 protected:
-
   /// build the dual graph of the mesh, for all element of spatial_dimension
   void buildDualGraph(Array<Int> & dxadj, Array<Int> & dadjncy,
-		      Array<Int> & edge_loads,
-		      const EdgeLoadFunctor & edge_load_func);
+                      Array<Int> & edge_loads,
+                      const EdgeLoadFunctor & edge_load_func);
 
   /// tweak the mesh to handle the PBC pairs
   void tweakConnectivity(const Array<UInt> & pairs);
   /// restore the mesh that has been tweaked
   void restoreConnectivity();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
-
   AKANTU_GET_MACRO(Partitions, partitions, const ElementTypeMapArray<UInt> &);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Partition, partitions, UInt);
 
-  AKANTU_GET_MACRO(GhostPartitionCSR, ghost_partitions_csr, const ElementTypeMap< CSR<UInt> > &);
+  AKANTU_GET_MACRO(GhostPartitionCSR, ghost_partitions_csr,
+                   const ElementTypeMap<CSR<UInt>> &);
 
   AKANTU_GET_MACRO(NbPartition, nb_partitions, UInt);
   AKANTU_SET_MACRO(NbPartition, nb_partitions, UInt);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// id
   std::string id;
 
   /// the mesh to partition
   const Mesh & mesh;
 
   /// dimension of the elements to consider in the mesh
   UInt spatial_dimension;
 
   /// number of partitions
   UInt nb_partitions;
 
   /// partition numbers
   ElementTypeMapArray<UInt> partitions;
 
-  ElementTypeMap< CSR<UInt> > ghost_partitions_csr;
+  ElementTypeMap<CSR<UInt>> ghost_partitions_csr;
   ElementTypeMapArray<UInt> ghost_partitions;
   ElementTypeMapArray<UInt> ghost_partitions_offset;
 
   Array<UInt> * permutation;
 
   ElementTypeMapArray<UInt> saved_connectivity;
 
+  Array<Element> lin_to_element;
 };
 
-} // akantu
+} // namespace akantu
 
 #ifdef AKANTU_USE_SCOTCH
 #include "mesh_partition_scotch.hh"
 #endif
 
 #endif /* __AKANTU_MESH_PARTITION_HH__ */
diff --git a/src/mesh_utils/mesh_utils.cc b/src/mesh_utils/mesh_utils.cc
index 61ee0a24a..e0e53ad49 100644
--- a/src/mesh_utils/mesh_utils.cc
+++ b/src/mesh_utils/mesh_utils.cc
@@ -1,2342 +1,2342 @@
 /**
  * @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;
       e.kind = Mesh::getKind(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).getSize();
-    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::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).getSize();
+//     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).getSize();
 
   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");
 
   const ElementTypeMapArray<UInt> * prank_to_element = nullptr;
 
   if (mesh.isDistributed()) {
     prank_to_element = &(mesh.getElementSynchronizer().getPrankToElement());
   }
 
   /// generate facets
   buildFacetsDimension(mesh, mesh_facets, false, from_dimension,
                        prank_to_element);
 
   /// 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, prank_to_element);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::buildFacetsDimension(
     const Mesh & mesh, Mesh & mesh_facets, bool boundary_only, UInt dimension,
     const ElementTypeMapArray<UInt> * prank_to_element) {
   AKANTU_DEBUG_IN();
 
   // save the current parent of mesh_facets and set it temporarly to mesh since
   // mesh is the one containing the elements for which mesh_facets has the
   // sub-elements
   // example: if the function is called with mesh = mesh_facets
   const Mesh * mesh_facets_parent = nullptr;
   try {
     mesh_facets_parent = &mesh_facets.getMeshParent();
   } catch (...) {
   }
 
   mesh_facets.defineMeshParent(mesh);
   MeshAccessor mesh_accessor(mesh_facets);
 
   UInt spatial_dimension = mesh.getSpatialDimension();
 
   const Array<Real> & mesh_facets_nodes = mesh_facets.getNodes();
   const Array<Real>::const_vector_iterator mesh_facets_nodes_it =
       mesh_facets_nodes.begin(spatial_dimension);
 
   CSR<Element> node_to_elem;
   buildNode2Elements(mesh, node_to_elem, dimension);
 
   Array<UInt> counter;
   std::vector<Element> connected_elements;
 
   // init the SubelementToElement data to improve performance
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
     Mesh::type_iterator first = mesh.firstType(dimension, ghost_type);
     Mesh::type_iterator last = mesh.lastType(dimension, ghost_type);
 
     for (; first != last; ++first) {
       ElementType type = *first;
 
       mesh_accessor.getSubelementToElement(type, ghost_type);
 
       Vector<ElementType> facet_types = mesh.getAllFacetTypes(type);
 
       for (UInt ft = 0; ft < facet_types.size(); ++ft) {
         ElementType facet_type = facet_types(ft);
         mesh_accessor.getElementToSubelement(facet_type, ghost_type);
         mesh_accessor.getConnectivity(facet_type, ghost_type);
       }
     }
   }
 
   Element current_element;
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
     GhostType ghost_type = *gt;
     GhostType facet_ghost_type = ghost_type;
 
     current_element.ghost_type = ghost_type;
     Mesh::type_iterator first = mesh.firstType(dimension, ghost_type);
     Mesh::type_iterator last = mesh.lastType(dimension, ghost_type);
 
     for (; first != last; ++first) {
       ElementType type = *first;
       Vector<ElementType> facet_types = mesh.getAllFacetTypes(type);
 
       current_element.type = type;
 
       for (UInt ft = 0; ft < facet_types.size(); ++ft) {
         ElementType facet_type = facet_types(ft);
         UInt nb_element = mesh.getNbElement(type, ghost_type);
 
         Array<std::vector<Element>> * element_to_subelement =
             &mesh_facets.getElementToSubelement(facet_type, ghost_type);
         Array<UInt> * connectivity_facets =
             &mesh_facets.getConnectivity(facet_type, ghost_type);
 
         UInt nb_facet_per_element = mesh.getNbFacetsPerElement(type, ft);
         const Array<UInt> & element_connectivity =
             mesh.getConnectivity(type, ghost_type);
 
         const Matrix<UInt> facet_local_connectivity =
             mesh.getFacetLocalConnectivity(type, ft);
         UInt 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
             CSR<Element>::iterator first_node_elements =
                 node_to_elem.begin(facet(0));
             CSR<Element>::iterator first_node_elements_end =
                 node_to_elem.end(facet(0));
             UInt local_el = 0;
             for (; first_node_elements != first_node_elements_end;
                  ++first_node_elements, ++local_el) {
               for (UInt n = 1; n < nb_nodes_per_facet; ++n) {
                 CSR<Element>::iterator node_elements_begin =
                     node_to_elem.begin(facet(n));
                 CSR<Element>::iterator 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 (counter(el_f) == nb_nodes_per_facet - 1) {
                 ++nb_element_connected_to_facet;
                 minimum_el = std::min(minimum_el, real_el);
                 connected_elements.push_back(real_el);
               }
             }
 
             if (minimum_el == current_element) {
               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) {
                 if (!boundary_only ||
                     (boundary_only && nb_element_connected_to_facet == 1)) {
 
                   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);
 
                   /// boundary facet
                   if (nb_element_connected_to_facet == 1)
                     elements.push_back(ElementNull);
                   /// internal facet
                   else if (nb_element_connected_to_facet == 2) {
                     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] == 1) {
                       if (prank_to_element) {
                         UInt prank[2];
                         for (UInt el = 0; el < 2; ++el) {
                           UInt current_el = connected_elements[el].element;
                           ElementType current_type =
                               connected_elements[el].type;
                           GhostType current_gt =
                               connected_elements[el].ghost_type;
 
                           const Array<UInt> & prank_to_el =
                               (*prank_to_element)(current_type, current_gt);
 
                           prank[el] = prank_to_el(current_el);
                         }
 
                         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);
                       }
                     }
                   }
                   /// facet of facet
                   else {
                     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->getSize() - 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) {
 
                       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) {
                         if (subelement_to_element(loc_el.element, f_in).type ==
                             _not_defined) {
                           subelement_to_element(loc_el.element, f_in).type =
                               facet_type;
                           subelement_to_element(loc_el.element, f_in).element =
                               current_facet;
                           subelement_to_element(loc_el.element, f_in)
                               .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.getSize(); ++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);
 
   std::map<UInt, UInt>::iterator it = renumbering_map.begin();
   std::map<UInt, UInt>::iterator end = renumbering_map.end();
   old_nodes_numbers.resize(renumbering_map.size());
   for (; it != end; ++it) {
     old_nodes_numbers(it->second) = it->first;
   }
   renumbering_map.clear();
 
   MeshAccessor mesh_accessor(mesh);
 
   /// copy the renumbered connectivity to the right place
   Array<UInt> & 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));
 
   Array<UInt> & ghost_conn = mesh_accessor.getConnectivity(type, _ghost);
   ghost_conn.resize(nb_ghost_element);
   memcpy(ghost_conn.storage(),
          local_connectivities.storage() +
              nb_local_element * nb_nodes_per_element,
          nb_ghost_element * nb_nodes_per_element * sizeof(UInt));
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::renumberNodesInConnectivity(
     Array<UInt> & list_nodes, UInt nb_nodes,
     std::map<UInt, UInt> & renumbering_map) {
   AKANTU_DEBUG_IN();
 
   UInt * connectivity = list_nodes.storage();
   UInt new_node_num = renumbering_map.size();
   for (UInt n = 0; n < nb_nodes; ++n, ++connectivity) {
     UInt & node = *connectivity;
     std::map<UInt, UInt>::iterator it = renumbering_map.find(node);
     if (it == renumbering_map.end()) {
       UInt old_node = node;
       renumbering_map[old_node] = new_node_num;
       node = new_node_num;
       ++new_node_num;
     } else {
       node = it->second;
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::purifyMesh(Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   std::map<UInt, UInt> renumbering_map;
 
   RemovedNodesEvent remove_nodes(mesh);
   Array<UInt> & nodes_removed = remove_nodes.getList();
 
   for (UInt gt = _not_ghost; gt <= _ghost; ++gt) {
     GhostType ghost_type = (GhostType)gt;
 
     Mesh::type_iterator it =
         mesh.firstType(_all_dimensions, ghost_type, _ek_not_defined);
     Mesh::type_iterator end =
         mesh.lastType(_all_dimensions, ghost_type, _ek_not_defined);
     for (; it != end; ++it) {
 
       ElementType type(*it);
       UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
 
       Array<UInt> & connectivity = mesh.getConnectivity(type, ghost_type);
       UInt nb_element(connectivity.getSize());
 
       renumberNodesInConnectivity(
           connectivity, nb_element * nb_nodes_per_element, renumbering_map);
     }
   }
 
   Array<UInt> & new_numbering = remove_nodes.getNewNumbering();
   std::fill(new_numbering.begin(), new_numbering.end(), UInt(-1));
 
   std::map<UInt, UInt>::iterator it = renumbering_map.begin();
   std::map<UInt, UInt>::iterator end = renumbering_map.end();
   for (; it != end; ++it) {
     new_numbering(it->first) = it->second;
   }
 
   for (UInt i = 0; i < new_numbering.getSize(); ++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.getSize();
   UInt new_nb_nodes = old_nb_nodes + old_nodes.size();
 
   UInt old_nb_doubled_nodes = doubled_nodes.getSize();
   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.getSize();
 
       if (nb_facet_to_double == 0)
         continue;
 
       ElementType type_subfacet = Mesh::getFacetType(type_facet);
       const UInt nb_subfacet_per_facet =
           Mesh::getNbFacetsPerElement(type_facet);
       GhostType gt_subfacet = _casper;
       Array<std::vector<Element>> * f_to_subfacet = NULL;
 
       Array<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.getSize();
       UInt new_nb_facet = old_nb_facet + nb_facet_to_double;
 
       conn_facet.resize(new_nb_facet);
       subfacet_to_facet.resize(new_nb_facet);
 
       UInt new_facet = old_nb_facet - 1;
       Element new_facet_el(type_facet, 0, gt_facet);
 
       Array<Element>::iterator<Vector<Element>> subfacet_to_facet_begin =
           subfacet_to_facet.begin(nb_subfacet_per_facet);
       Array<UInt>::iterator<Vector<UInt>> conn_facet_begin =
           conn_facet.begin(nb_nodes_per_facet);
 
       for (UInt facet = 0; facet < nb_facet_to_double; ++facet) {
         UInt old_facet = f_to_double(facet);
         ++new_facet;
 
         /// adding a new facet by copying original one
 
         /// copy connectivity in new facet
         std::copy(conn_facet_begin + old_facet,
                   conn_facet_begin + old_facet + 1,
                   conn_facet_begin + new_facet);
 
         /// update subfacet_to_facet
         std::copy(subfacet_to_facet_begin + old_facet,
                   subfacet_to_facet_begin + old_facet + 1,
                   subfacet_to_facet_begin + new_facet);
 
         new_facet_el.element = new_facet;
 
         /// loop on every subfacet
         for (UInt sf = 0; sf < nb_subfacet_per_facet; ++sf) {
           Element & subfacet = subfacet_to_facet(old_facet, sf);
           if (subfacet == ElementNull)
             continue;
 
           if (gt_subfacet != subfacet.ghost_type) {
             gt_subfacet = subfacet.ghost_type;
             f_to_subfacet = &mesh_facets.getElementToSubelement(
                 type_subfacet, subfacet.ghost_type);
           }
 
           /// update facet_to_subfacet array
           (*f_to_subfacet)(subfacet.element).push_back(new_facet_el);
         }
       }
 
       /// update facet_to_subfacet and _segment_3 facets if any
       if (!facet_mode) {
         updateSubfacetToFacet(mesh_facets, type_facet, gt_facet, true);
         updateFacetToSubfacet(mesh_facets, type_facet, gt_facet, true);
         updateQuadraticSegments<true>(mesh, mesh_facets, type_facet, gt_facet,
                                       doubled_nodes);
       } else
         updateQuadraticSegments<false>(mesh, mesh_facets, type_facet, gt_facet,
                                        doubled_nodes);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 UInt MeshUtils::updateFacetToDouble(
     Mesh & mesh_facets, const ElementTypeMapArray<bool> & facet_insertion) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh_facets.getSpatialDimension();
   UInt nb_facets_to_double = 0.;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       const Array<bool> & f_insertion = facet_insertion(type_facet, gt_facet);
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
 
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       ElementType el_type = _not_defined;
       GhostType el_gt = _casper;
       UInt nb_facet_per_element = 0;
       Element old_facet_el(type_facet, 0, gt_facet);
 
       Array<Element> * facet_to_element = NULL;
 
       for (UInt f = 0; f < f_insertion.getSize(); ++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.getSize() - 1;
         old_facet_el.element = f;
 
         /// update facet_to_element vector
         Element & elem_to_update = element_to_facet(f)[1];
         UInt el = elem_to_update.element;
 
         if (elem_to_update.ghost_type != el_gt ||
             elem_to_update.type != el_type) {
           el_type = elem_to_update.type;
           el_gt = elem_to_update.ghost_type;
           facet_to_element =
               &mesh_facets.getSubelementToElement(el_type, el_gt);
           nb_facet_per_element = facet_to_element->getNbComponent();
         }
 
         Element * f_update =
             std::find(facet_to_element->storage() + el * nb_facet_per_element,
                       facet_to_element->storage() + el * nb_facet_per_element +
                           nb_facet_per_element,
                       old_facet_el);
 
         AKANTU_DEBUG_ASSERT(
             facet_to_element->storage() + el * nb_facet_per_element !=
                 facet_to_element->storage() + el * nb_facet_per_element +
                     nb_facet_per_element,
             "Facet not found");
 
         f_update->element = new_facet;
 
         /// update elements connected to facet
         std::vector<Element> first_facet_list = element_to_facet(f);
         element_to_facet.push_back(first_facet_list);
 
         /// set new and original facets as boundary facets
         element_to_facet(new_facet)[0] = element_to_facet(new_facet)[1];
 
         element_to_facet(f)[1] = ElementNull;
         element_to_facet(new_facet)[1] = ElementNull;
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
   return nb_facets_to_double;
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::resetFacetToDouble(Mesh & mesh_facets) {
   AKANTU_DEBUG_IN();
 
   for (UInt g = _not_ghost; g <= _ghost; ++g) {
     GhostType gt = (GhostType)g;
 
     Mesh::type_iterator it = mesh_facets.firstType(_all_dimensions, gt);
     Mesh::type_iterator end = mesh_facets.lastType(_all_dimensions, gt);
     for (; it != end; ++it) {
       ElementType type = *it;
       mesh_facets.getDataPointer<UInt>("facet_to_double", type, gt, 1, false);
 
       mesh_facets.getDataPointer<std::vector<Element>>(
           "facets_to_subfacet_double", type, gt, 1, false);
 
       mesh_facets.getDataPointer<std::vector<Element>>(
           "elements_to_subfacet_double", type, gt, 1, false);
 
       mesh_facets.getDataPointer<std::vector<Element>>(
           "subfacets_to_subsubfacet_double", type, gt, 1, false);
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool subsubfacet_mode>
 void MeshUtils::findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh_facets.getSpatialDimension();
   if (spatial_dimension == 1)
     return;
 
   for (ghost_type_t::iterator gt = ghost_type_t::begin();
        gt != ghost_type_t::end(); ++gt) {
 
     GhostType gt_facet = *gt;
 
     Mesh::type_iterator it =
         mesh_facets.firstType(spatial_dimension - 1, gt_facet);
     Mesh::type_iterator end =
         mesh_facets.lastType(spatial_dimension - 1, gt_facet);
 
     for (; it != end; ++it) {
 
       ElementType type_facet = *it;
 
       Array<UInt> & f_to_double =
           mesh_facets.getData<UInt>("facet_to_double", type_facet, gt_facet);
       UInt nb_facet_to_double = f_to_double.getSize();
       if (nb_facet_to_double == 0)
         continue;
 
       ElementType type_subfacet = Mesh::getFacetType(type_facet);
       GhostType gt_subfacet = _casper;
 
       ElementType type_subsubfacet = Mesh::getFacetType(type_subfacet);
       GhostType gt_subsubfacet = _casper;
 
       Array<UInt> * conn_subfacet = NULL;
       Array<UInt> * sf_to_double = NULL;
       Array<std::vector<Element>> * sf_to_subfacet_double = NULL;
       Array<std::vector<Element>> * f_to_subfacet_double = NULL;
       Array<std::vector<Element>> * el_to_subfacet_double = NULL;
 
       UInt nb_subfacet = Mesh::getNbFacetsPerElement(type_facet);
 
       UInt nb_subsubfacet;
       UInt nb_nodes_per_sf_el;
 
       if (subsubfacet_mode) {
         nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subsubfacet);
         nb_subsubfacet = Mesh::getNbFacetsPerElement(type_subfacet);
       } else
         nb_nodes_per_sf_el = Mesh::getNbNodesPerElement(type_subfacet);
 
       Array<Element> & subfacet_to_facet =
           mesh_facets.getSubelementToElement(type_facet, gt_facet);
 
       Array<std::vector<Element>> & element_to_facet =
           mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
       Array<Element> * subsubfacet_to_subfacet = NULL;
 
       UInt old_nb_facet = subfacet_to_facet.getSize() - nb_facet_to_double;
 
       Element current_facet(type_facet, 0, gt_facet);
       std::vector<Element> element_list;
       std::vector<Element> facet_list;
       std::vector<Element> * subfacet_list;
       if (subsubfacet_mode)
         subfacet_list = new std::vector<Element>;
 
       /// map to filter subfacets
       Array<std::vector<Element>> * facet_to_subfacet = NULL;
 
       /// 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.getSize();
       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.getSize();
       UInt new_nb_cohesive_elements =
           conn_cohesive.getSize() + nb_facet_to_double;
 
       UInt old_nb_facet = element_to_facet.getSize() - 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.getSize();
       new_elements.resize(new_elements_old_size + nb_facet_to_double);
 
       Element c_element(type_cohesive, 0, gt_facet, _ek_cohesive);
       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.getSize();
 
       UInt old_nb_facet = element_to_facet.getSize() - nb_facet_to_double;
       UInt new_nb_facet = element_to_facet.getSize();
 
       UInt old_nb_nodes = position.getSize();
       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.getSize();
       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.getSize();
 
   UInt old_nb_facet =
       mesh_facets.getNbElement(type_facet, gt_facet) - nb_facet_to_double;
 
   Array<UInt> & conn_facet = mesh_facets.getConnectivity(type_facet, gt_facet);
 
   Array<std::vector<Element>> & element_to_facet =
       mesh_facets.getElementToSubelement(type_facet, gt_facet);
 
   /// this ones matter only for segments in 3D
   Array<std::vector<Element>> * el_to_subfacet_double = NULL;
   Array<std::vector<Element>> * f_to_subfacet_double = NULL;
 
   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.getSize();
 
   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.getSize();
 
   /// update subfacet_to_facet vector
   ElementType type_facet = _not_defined;
   GhostType gt_facet = _casper;
   Array<Element> * subfacet_to_facet = NULL;
   UInt nb_subfacet_per_facet = 0;
   UInt old_nb_subfacet = mesh_facets.getNbElement(type_subfacet, gt_subfacet) -
                          nb_subfacet_to_double;
 
   Array<std::vector<Element>> * facet_list = NULL;
   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.getSize();
 
   Array<std::vector<Element>> & facet_to_subfacet =
       mesh_facets.getElementToSubelement(type_subfacet, gt_subfacet);
 
   Array<std::vector<Element>> * facet_to_subfacet_double = NULL;
 
   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.getSize();
   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.getSize();
 
       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.getSize();
       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.getSize();
 
       /// double nodes
       for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
         UInt old_subfacet = sf_to_double(sf);
         nodes_to_double.push_back(conn_subfacet(old_subfacet));
       }
 
       doubleNodes(mesh, nodes_to_double, doubled_nodes);
 
       /// add new nodes in connectivity
       for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
         UInt new_subfacet = old_nb_subfacet + sf;
         UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
 
         conn_subfacet(new_subfacet) = new_node;
       }
 
       /// update facet and element connectivity
       Array<std::vector<Element>> & f_to_subfacet_double =
           mesh_facets.getData<std::vector<Element>>("facets_to_subfacet_double",
                                                     type_subfacet, gt_subfacet);
 
       Array<std::vector<Element>> & el_to_subfacet_double =
           mesh_facets.getData<std::vector<Element>>(
               "elements_to_subfacet_double", type_subfacet, gt_subfacet);
 
       Array<std::vector<Element>> * sf_to_subfacet_double = NULL;
 
       if (spatial_dimension == 3)
         sf_to_subfacet_double = &mesh_facets.getData<std::vector<Element>>(
             "subfacets_to_subsubfacet_double", type_subfacet, gt_subfacet);
 
       for (UInt sf = 0; sf < nb_subfacet_to_double; ++sf) {
         UInt old_node = doubled_nodes(old_nb_doubled_nodes + sf, 0);
         UInt new_node = doubled_nodes(old_nb_doubled_nodes + sf, 1);
 
         updateElementalConnectivity(mesh, old_node, new_node,
                                     el_to_subfacet_double(sf),
                                     &f_to_subfacet_double(sf));
 
         updateElementalConnectivity(mesh_facets, old_node, new_node,
                                     f_to_subfacet_double(sf));
 
         if (spatial_dimension == 3)
           updateElementalConnectivity(mesh_facets, old_node, new_node,
                                       (*sf_to_subfacet_double)(sf));
       }
 
       if (spatial_dimension == 2) {
         updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, true);
         updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, true);
       } else if (spatial_dimension == 3) {
         updateSubfacetToFacet(mesh_facets, type_subfacet, gt_subfacet, false);
         updateFacetToSubfacet(mesh_facets, type_subfacet, gt_subfacet, false);
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::flipFacets(
     Mesh & mesh_facets, const ElementTypeMapArray<UInt> & global_connectivity,
     GhostType gt_facet) {
   AKANTU_DEBUG_IN();
 
   UInt spatial_dimension = mesh_facets.getSpatialDimension();
 
   /// get global connectivity for local mesh
   ElementTypeMapArray<UInt> global_connectivity_tmp("global_connectivity_tmp",
                                                     mesh_facets.getID(),
                                                     mesh_facets.getMemoryID());
 
   global_connectivity_tmp.initialize(
       mesh_facets, _spatial_dimension = spatial_dimension - 1,
       _with_nb_nodes_per_element = true, _with_nb_element = true);
   // mesh_facets.initElementTypeMapArray(global_connectivity_tmp, 1,
   //                                     spatial_dimension - 1, gt_facet,
   //                                     true, _ek_regular, true);
 
   mesh_facets.getGlobalConnectivity(global_connectivity_tmp,
                                     spatial_dimension - 1, gt_facet);
 
   /// 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.getSize();
 
     UInt nb_nodes_per_P1_facet =
         Mesh::getNbNodesPerElement(Mesh::getP1ElementType(type_facet));
 
     auto & global_conn_tmp = global_connectivity_tmp(type_facet, gt_facet);
 
     auto conn_it = connectivity.begin(nb_nodes_per_facet);
     auto gconn_tmp_it = global_conn_tmp.begin(nb_nodes_per_facet);
     auto conn_glob_it = g_connectivity.begin(nb_nodes_per_facet);
     auto subf_to_f = subfacet_to_facet.begin(nb_subfacet_per_facet);
 
     UInt * conn_tmp_pointer = new UInt[nb_nodes_per_facet];
     Vector<UInt> conn_tmp(conn_tmp_pointer, nb_nodes_per_facet);
 
     Element el_tmp;
     Element * subf_tmp_pointer = new Element[nb_subfacet_per_facet];
     Vector<Element> subf_tmp(subf_tmp_pointer, nb_subfacet_per_facet);
 
     for (UInt f = 0; f < nb_facet;
          ++f, ++conn_it, ++gconn_tmp_it, ++subf_to_f, ++conn_glob_it) {
 
       Vector<UInt> & gconn_tmp = *gconn_tmp_it;
       const Vector<UInt> & conn_glob = *conn_glob_it;
       Vector<UInt> & conn_local = *conn_it;
 
       /// skip facet if connectivities are the same
       if (gconn_tmp == conn_glob)
         continue;
 
       /// re-arrange connectivity
       conn_tmp = conn_local;
 
       UInt * begin = conn_glob.storage();
       UInt * end = conn_glob.storage() + nb_nodes_per_facet;
 
       for (UInt n = 0; n < nb_nodes_per_facet; ++n) {
 
         UInt * new_node = std::find(begin, end, gconn_tmp(n));
         AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
 
         UInt new_position = new_node - begin;
 
         conn_local(new_position) = conn_tmp(n);
       }
 
       /// if 3D, check if facets are just rotated
       if (spatial_dimension == 3) {
         /// find first node
         UInt * new_node = std::find(begin, end, gconn_tmp(0));
         AKANTU_DEBUG_ASSERT(new_node != end, "Node not found");
 
         UInt new_position = new_node - begin;
         UInt n = 1;
 
         /// count how many nodes in the received connectivity follow
         /// the same order of those in the local connectivity
         for (; n < nb_nodes_per_P1_facet &&
                gconn_tmp(n) ==
                    conn_glob((new_position + n) % nb_nodes_per_P1_facet);
              ++n)
           ;
 
         /// skip the facet inversion if facet is just rotated
         if (n == nb_nodes_per_P1_facet)
           continue;
       }
 
       /// update data to invert facet
       el_tmp = el_to_f(f)[0];
       el_to_f(f)[0] = el_to_f(f)[1];
       el_to_f(f)[1] = el_tmp;
 
       subf_tmp = (*subf_to_f);
       (*subf_to_f)(0) = subf_tmp(1);
       (*subf_to_f)(1) = subf_tmp(0);
     }
 
     delete[] subf_tmp_pointer;
     delete[] conn_tmp_pointer;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::fillElementToSubElementsData(Mesh & mesh) {
   AKANTU_DEBUG_IN();
 
   if (mesh.getNbElement(mesh.getSpatialDimension() - 1) == 0) {
     AKANTU_DEBUG_INFO("There are not facets, add them in the mesh file or call "
                       "the buildFacet method.");
     return;
   }
 
   UInt spatial_dimension = mesh.getSpatialDimension();
   ElementTypeMapArray<Real> barycenters("barycenter_tmp", mesh.getID(),
                                         mesh.getMemoryID());
   barycenters.initialize(mesh, _nb_component = spatial_dimension,
                          _spatial_dimension = _all_dimensions);
   // mesh.initElementTypeMapArray(barycenters, spatial_dimension,
   // _all_dimensions);
 
   Element element;
   for (auto ghost_type : ghost_types) {
     element.ghost_type = ghost_type;
     for (auto & type : mesh.elementTypes(_all_dimensions, ghost_type)) {
       element.type = type;
 
       UInt nb_element = mesh.getNbElement(type, ghost_type);
       Array<Real> & barycenters_arr = barycenters(type, ghost_type);
       barycenters_arr.resize(nb_element);
       auto bary = barycenters_arr.begin(spatial_dimension);
       auto bary_end = barycenters_arr.end(spatial_dimension);
 
       for (UInt el = 0; bary != bary_end; ++bary, ++el) {
         element.element = el;
         mesh.getBarycenter(element, *bary);
       }
     }
   }
 
   MeshAccessor mesh_accessor(mesh);
   for (Int sp(spatial_dimension); sp >= 1; --sp) {
     if (mesh.getNbElement(sp) == 0)
       continue;
 
     for (auto ghost_type : ghost_types) {
       for (auto & type : mesh.elementTypes(sp, ghost_type)) {
         mesh_accessor.getSubelementToElement(type, ghost_type)
             .resize(mesh.getNbElement(type, ghost_type));
         mesh_accessor.getSubelementToElement(type, ghost_type).clear();
       }
 
       for (auto & type : mesh.elementTypes(sp - 1, ghost_type)) {
         mesh_accessor.getElementToSubelement(type, ghost_type)
             .resize(mesh.getNbElement(type, ghost_type));
         mesh.getElementToSubelement(type, ghost_type).clear();
       }
     }
 
     CSR<Element> nodes_to_elements;
     buildNode2Elements(mesh, nodes_to_elements, sp);
 
     Element facet_element;
 
     for (auto ghost_type : ghost_types) {
       facet_element.ghost_type = ghost_type;
       for (auto & type : mesh.elementTypes(sp - 1, ghost_type)) {
         facet_element.type = type;
 
         auto & element_to_subelement =
             mesh.getElementToSubelement(type, ghost_type);
 
         const auto & connectivity = mesh.getConnectivity(type, ghost_type);
 
         auto fit = connectivity.begin(mesh.getNbNodesPerElement(type));
         auto fend = connectivity.end(mesh.getNbNodesPerElement(type));
 
         UInt fid = 0;
         for (; fit != fend; ++fit, ++fid) {
           const Vector<UInt> & facet = *fit;
           facet_element.element = fid;
           std::map<Element, UInt> element_seen_counter;
           UInt nb_nodes_per_facet =
               mesh.getNbNodesPerElement(Mesh::getP1ElementType(type));
 
           for (UInt n(0); n < nb_nodes_per_facet; ++n) {
 
             auto eit = nodes_to_elements.begin(facet(n));
             auto eend = nodes_to_elements.end(facet(n));
             for (; eit != eend; ++eit) {
               auto & elem = *eit;
               auto cit = element_seen_counter.find(elem);
               if (cit != element_seen_counter.end()) {
                 cit->second++;
               } else {
                 element_seen_counter[elem] = 1;
               }
             }
           }
 
           std::vector<Element> connected_elements;
           auto cit = element_seen_counter.begin();
           auto cend = element_seen_counter.end();
           for (; cit != cend; ++cit) {
             if (cit->second == nb_nodes_per_facet)
               connected_elements.push_back(cit->first);
           }
 
           auto ceit = connected_elements.begin();
           auto ceend = connected_elements.end();
           for (; ceit != ceend; ++ceit)
             element_to_subelement(fid).push_back(*ceit);
 
           for (UInt ce = 0; ce < connected_elements.size(); ++ce) {
             Element & elem = connected_elements[ce];
             Array<Element> & subelement_to_element =
                 mesh_accessor.getSubelementToElement(elem.type,
                                                      elem.ghost_type);
 
             UInt f(0);
             for (; f < mesh.getNbFacetsPerElement(elem.type) &&
                    subelement_to_element(elem.element, f) != ElementNull;
                  ++f)
               ;
 
             AKANTU_DEBUG_ASSERT(
                 f < mesh.getNbFacetsPerElement(elem.type),
                 "The element " << elem << " seems to have too many facets!! ("
                                << f << " < "
                                << mesh.getNbFacetsPerElement(elem.type) << ")");
 
             subelement_to_element(elem.element, f) = facet_element;
           }
         }
       }
     }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool third_dim_points>
 bool MeshUtils::findElementsAroundSubfacet(
     const Mesh & mesh, const Mesh & mesh_facets,
     const Element & starting_element, const Element & end_facet,
     const Vector<UInt> & subfacet_connectivity,
     std::vector<Element> & elem_list, std::vector<Element> & facet_list,
     std::vector<Element> * subfacet_list) {
   AKANTU_DEBUG_IN();
 
   /// preallocated stuff before starting
   bool facet_matched = false;
 
   elem_list.clear();
   facet_list.clear();
 
   if (third_dim_points)
     subfacet_list->clear();
 
   elem_list.push_back(starting_element);
 
   const Array<UInt> * facet_connectivity = NULL;
   const Array<UInt> * sf_connectivity = NULL;
   const Array<Element> * facet_to_element = NULL;
   const Array<Element> * subfacet_to_facet = NULL;
 
   ElementType current_type = _not_defined;
   GhostType current_ghost_type = _casper;
 
   ElementType current_facet_type = _not_defined;
   GhostType current_facet_ghost_type = _casper;
 
   ElementType current_subfacet_type = _not_defined;
   GhostType current_subfacet_ghost_type = _casper;
 
   const Array<std::vector<Element>> * element_to_facet = NULL;
 
   const Element * opposing_el = NULL;
 
   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;
 }
 
 /* -------------------------------------------------------------------------- */
-void MeshUtils::buildSegmentToNodeType(const Mesh & mesh, Mesh & mesh_facets) {
-  buildAllFacets(mesh, mesh_facets, 1);
-
-  UInt spatial_dimension = mesh.getSpatialDimension();
-
-  const ElementTypeMapArray<UInt> & element_to_rank =
-      mesh.getElementSynchronizer().getPrankToElement();
-  Int local_rank = StaticCommunicator::getStaticCommunicator().whoAmI();
-
-  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(1, ghost_type);
-    Mesh::type_iterator end = mesh_facets.lastType(1, ghost_type);
-    for (; it != end; ++it) {
-      ElementType type = *it;
-      UInt nb_segments = mesh_facets.getNbElement(type, ghost_type);
-
-      // allocate the data
-      Array<Int> & segment_to_nodetype = *(mesh_facets.getDataPointer<Int>(
-          "segment_to_nodetype", type, ghost_type));
-
-      std::set<Element> connected_elements;
-      const Array<std::vector<Element>> & segment_to_2Delement =
-          mesh_facets.getElementToSubelement(type, ghost_type);
-
-      // loop over segments
-      for (UInt s = 0; s < nb_segments; ++s) {
-
-        // determine the elements connected to the segment
-        connected_elements.clear();
-        const std::vector<Element> & twoD_elements = segment_to_2Delement(s);
-
-        if (spatial_dimension == 2) {
-          // if 2D just take the elements connected to the segments
-          connected_elements.insert(twoD_elements.begin(), twoD_elements.end());
-        } else if (spatial_dimension == 3) {
-          // if 3D a second loop is needed to get to the 3D elements
-          std::vector<Element>::const_iterator facet = twoD_elements.begin();
-
-          for (; facet != twoD_elements.end(); ++facet) {
-            const std::vector<Element> & threeD_elements =
-                mesh_facets.getElementToSubelement(
-                    facet->type, facet->ghost_type)(facet->element);
-            connected_elements.insert(threeD_elements.begin(),
-                                      threeD_elements.end());
-          }
-        }
-
-        // get the minimum processor rank associated to the connected
-        // elements and verify if ghost and not ghost elements are
-        // found
-        Int minimum_rank = std::numeric_limits<Int>::max();
-
-        // two booleans saying if not ghost and ghost elements are found in the
-        // loop
-        bool ghost_found[2];
-        ghost_found[0] = false;
-        ghost_found[1] = false;
-
-        std::set<Element>::iterator connected_elements_it =
-            connected_elements.begin();
-
-        for (; connected_elements_it != connected_elements.end();
-             ++connected_elements_it) {
-          if (*connected_elements_it == ElementNull)
-            continue;
-          ghost_found[connected_elements_it->ghost_type] = true;
-          const Array<UInt> & el_to_rank_array = element_to_rank(
-              connected_elements_it->type, connected_elements_it->ghost_type);
-          minimum_rank =
-              std::min(minimum_rank,
-                       Int(el_to_rank_array(connected_elements_it->element)));
-        }
-
-        // if no ghost elements are found the segment is local
-        if (!ghost_found[1])
-          segment_to_nodetype(s) = -1;
-        // if no not ghost elements are found the segment is pure ghost
-        else if (!ghost_found[0])
-          segment_to_nodetype(s) = -3;
-        // if the minimum rank is equal to the local rank, the segment is master
-        else if (local_rank == minimum_rank)
-          segment_to_nodetype(s) = -2;
-        // if the minimum rank is less than the local rank, the segment is slave
-        else if (local_rank > minimum_rank)
-          segment_to_nodetype(s) = minimum_rank;
-        else
-          AKANTU_DEBUG_ERROR("The local rank cannot be smaller than the "
-                             "minimum rank if both ghost and not ghost "
-                             "elements are found");
-      }
-    }
-  }
-}
+// void MeshUtils::buildSegmentToNodeType(const Mesh & mesh, Mesh & mesh_facets) {
+//   buildAllFacets(mesh, mesh_facets, 1);
+
+//   UInt spatial_dimension = mesh.getSpatialDimension();
+
+//   const ElementTypeMapArray<UInt> & element_to_rank =
+//       mesh.getElementSynchronizer().getPrankToElement();
+//   Int local_rank = StaticCommunicator::getStaticCommunicator().whoAmI();
+
+//   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(1, ghost_type);
+//     Mesh::type_iterator end = mesh_facets.lastType(1, ghost_type);
+//     for (; it != end; ++it) {
+//       ElementType type = *it;
+//       UInt nb_segments = mesh_facets.getNbElement(type, ghost_type);
+
+//       // allocate the data
+//       Array<Int> & segment_to_nodetype = *(mesh_facets.getDataPointer<Int>(
+//           "segment_to_nodetype", type, ghost_type));
+
+//       std::set<Element> connected_elements;
+//       const Array<std::vector<Element>> & segment_to_2Delement =
+//           mesh_facets.getElementToSubelement(type, ghost_type);
+
+//       // loop over segments
+//       for (UInt s = 0; s < nb_segments; ++s) {
+
+//         // determine the elements connected to the segment
+//         connected_elements.clear();
+//         const std::vector<Element> & twoD_elements = segment_to_2Delement(s);
+
+//         if (spatial_dimension == 2) {
+//           // if 2D just take the elements connected to the segments
+//           connected_elements.insert(twoD_elements.begin(), twoD_elements.end());
+//         } else if (spatial_dimension == 3) {
+//           // if 3D a second loop is needed to get to the 3D elements
+//           std::vector<Element>::const_iterator facet = twoD_elements.begin();
+
+//           for (; facet != twoD_elements.end(); ++facet) {
+//             const std::vector<Element> & threeD_elements =
+//                 mesh_facets.getElementToSubelement(
+//                     facet->type, facet->ghost_type)(facet->element);
+//             connected_elements.insert(threeD_elements.begin(),
+//                                       threeD_elements.end());
+//           }
+//         }
+
+//         // get the minimum processor rank associated to the connected
+//         // elements and verify if ghost and not ghost elements are
+//         // found
+//         Int minimum_rank = std::numeric_limits<Int>::max();
+
+//         // two booleans saying if not ghost and ghost elements are found in the
+//         // loop
+//         bool ghost_found[2];
+//         ghost_found[0] = false;
+//         ghost_found[1] = false;
+
+//         std::set<Element>::iterator connected_elements_it =
+//             connected_elements.begin();
+
+//         for (; connected_elements_it != connected_elements.end();
+//              ++connected_elements_it) {
+//           if (*connected_elements_it == ElementNull)
+//             continue;
+//           ghost_found[connected_elements_it->ghost_type] = true;
+//           const Array<UInt> & el_to_rank_array = element_to_rank(
+//               connected_elements_it->type, connected_elements_it->ghost_type);
+//           minimum_rank =
+//               std::min(minimum_rank,
+//                        Int(el_to_rank_array(connected_elements_it->element)));
+//         }
+
+//         // if no ghost elements are found the segment is local
+//         if (!ghost_found[1])
+//           segment_to_nodetype(s) = -1;
+//         // if no not ghost elements are found the segment is pure ghost
+//         else if (!ghost_found[0])
+//           segment_to_nodetype(s) = -3;
+//         // if the minimum rank is equal to the local rank, the segment is master
+//         else if (local_rank == minimum_rank)
+//           segment_to_nodetype(s) = -2;
+//         // if the minimum rank is less than the local rank, the segment is slave
+//         else if (local_rank > minimum_rank)
+//           segment_to_nodetype(s) = minimum_rank;
+//         else
+//           AKANTU_DEBUG_ERROR("The local rank cannot be smaller than the "
+//                              "minimum rank if both ghost and not ghost "
+//                              "elements are found");
+//       }
+//     }
+//   }
+// }
 
 /* -------------------------------------------------------------------------- */
 UInt MeshUtils::updateLocalMasterGlobalConnectivity(Mesh & mesh,
                                                     UInt local_nb_new_nodes) {
   StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
   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;
 }
 
 /* -------------------------------------------------------------------------- */
 // Deactivating -Wunused-parameter
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
 // is only gnu
 #elif (defined(__GNUC__) || defined(__GNUG__))
 #define GCC_VERSION                                                            \
   (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic push
 #endif
 #pragma GCC diagnostic ignored "-Wunused-parameter"
 #endif
 
 /* -------------------------------------------------------------------------- */
 void MeshUtils::updateElementalConnectivity(
     Mesh & mesh, UInt old_node, UInt new_node,
     const std::vector<Element> & element_list,
     __attribute__((unused)) const std::vector<Element> * facet_list) {
   AKANTU_DEBUG_IN();
 
   ElementType el_type = _not_defined;
   GhostType gt_type = _casper;
   Array<UInt> * conn_elem = NULL;
 #if defined(AKANTU_COHESIVE_ELEMENT)
   const Array<Element> * cohesive_facets = NULL;
 #endif
   UInt nb_nodes_per_element = 0;
   UInt * n_update = NULL;
 
   for (UInt el = 0; el < element_list.size(); ++el) {
     const Element & elem = element_list[el];
     if (elem.type == _not_defined)
       continue;
 
     if (elem.type != el_type || elem.ghost_type != gt_type) {
       el_type = elem.type;
       gt_type = elem.ghost_type;
       conn_elem = &mesh.getConnectivity(el_type, gt_type);
       nb_nodes_per_element = conn_elem->getNbComponent();
 #if defined(AKANTU_COHESIVE_ELEMENT)
       if (elem.kind == _ek_cohesive)
         cohesive_facets =
             &mesh.getMeshFacets().getSubelementToElement(el_type, gt_type);
 #endif
     }
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
     if (elem.kind == _ek_cohesive) {
 
       AKANTU_DEBUG_ASSERT(
           facet_list != NULL,
           "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();
 }
 
 // Reactivating -Wunused-parameter
 #if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 #elif defined(__clang__) // test clang to be sure that when we test for gnu it
 // is only gnu
 #elif defined(__GNUG__)
 #if GCC_VERSION > 40600
 #pragma GCC diagnostic pop
 #else
 #pragma GCC diagnostic warning "-Wunused-parameter"
 #endif
 #endif
 /* -------------------------------------------------------------------------- */
 
 } // namespace akantu
 
 //  LocalWords:  ElementType
diff --git a/src/mesh_utils/mesh_utils.hh b/src/mesh_utils/mesh_utils.hh
index 2c79aaa1a..a63d000a4 100644
--- a/src/mesh_utils/mesh_utils.hh
+++ b/src/mesh_utils/mesh_utils.hh
@@ -1,244 +1,245 @@
 /**
  * @file   mesh_utils.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Leonardo Snozzi <leonardo.snozzi@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Fri Oct 02 2015
  *
  * @brief  All mesh utils necessary for various tasks
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "aka_csr.hh"
 /* -------------------------------------------------------------------------- */
 
 #include <vector>
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MESH_UTILS_HH__
 #define __AKANTU_MESH_UTILS_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 class MeshUtils {
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// build a CSR<UInt> that contains for each node the linearized number of
   /// the connected elements of a given spatial dimension
-  static void buildNode2Elements(const Mesh & mesh, CSR<UInt> & node_to_elem,
-                                 UInt spatial_dimension = _all_dimensions);
+  // static void buildNode2Elements(const Mesh & mesh, CSR<UInt> & node_to_elem,
+  //                                UInt spatial_dimension = _all_dimensions);
+
   /// build a CSR<Element> that contains for each node the list of connected
   /// elements of a given spatial dimension
   static void buildNode2Elements(const Mesh & mesh, CSR<Element> & node_to_elem,
                                  UInt spatial_dimension = _all_dimensions);
 
   /// build a CSR<UInt> that contains for each node the number of
   /// the connected elements of a given ElementType
   static void
   buildNode2ElementsElementTypeMap(const Mesh & mesh, CSR<UInt> & node_to_elem,
                                    const ElementType & type,
                                    const GhostType & ghost_type = _not_ghost);
 
   /// build the facets elements on the boundaries of a mesh
   static void buildFacets(Mesh & mesh);
 
   /// build all the facets elements: boundary and internals and store them in
   /// the mesh_facets for element of dimension from_dimension to to_dimension
   static void buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
                              UInt from_dimension, UInt to_dimension);
 
   /// build all the facets elements: boundary and internals and store them in
   /// the mesh_facets
   static void buildAllFacets(const Mesh & mesh, Mesh & mesh_facets,
                              UInt to_dimension = 0);
 
   /// build facets for a given spatial dimension
   static void buildFacetsDimension(
       const Mesh & mesh, Mesh & mesh_facets, bool boundary_only, UInt dimension,
       const ElementTypeMapArray<UInt> * prank_to_element = nullptr);
 
   /// take the local_connectivity array as the array of local and ghost
   /// connectivity, renumber the nodes and set the connectivity of the mesh
   static void renumberMeshNodes(Mesh & mesh, Array<UInt> & local_connectivities,
                                 UInt nb_local_element, UInt nb_ghost_element,
                                 ElementType type, Array<UInt> & old_nodes);
 
   /// compute pbc pair for a given direction
   static void computePBCMap(const Mesh & mymesh, const UInt dir,
                             std::map<UInt, UInt> & pbc_pair);
   /// compute pbc pair for a surface pair
   static void computePBCMap(const Mesh & mymesh,
                             const std::pair<Surface, Surface> & surface_pair,
                             std::map<UInt, UInt> & pbc_pair);
 
   /// remove not connected nodes /!\ this functions renumbers the nodes.
   static void purifyMesh(Mesh & mesh);
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
   /// function to insert cohesive elements on the selected facets
   /// @return number of facets that have been doubled
   static UInt
   insertCohesiveElements(Mesh & mesh, Mesh & mesh_facets,
                          const ElementTypeMapArray<bool> & facet_insertion,
                          Array<UInt> & doubled_nodes,
                          Array<Element> & new_elements,
                          bool only_double_facets);
 #endif
 
   /// fill the subelement to element and the elements to subelements data
   static void fillElementToSubElementsData(Mesh & mesh);
 
   /// flip facets based on global connectivity
   static void flipFacets(Mesh & mesh_facets,
                          const ElementTypeMapArray<UInt> & global_connectivity,
                          GhostType gt_facet);
 
   /// provide list of elements around a node and check if a given
   /// facet is reached
   template <bool third_dim_points>
   static bool findElementsAroundSubfacet(
       const Mesh & mesh, const Mesh & mesh_facets,
       const Element & starting_element, const Element & end_facet,
       const Vector<UInt> & subfacet_connectivity,
       std::vector<Element> & elem_list, std::vector<Element> & facet_list,
       std::vector<Element> * subfacet_list = nullptr);
 
   /// function to check if a node belongs to a given element
   static inline bool hasElement(const Array<UInt> & connectivity,
                                 const Element & el, const Vector<UInt> & nodes);
 
   /// reset facet_to_double arrays in the Mesh
   static void resetFacetToDouble(Mesh & mesh_facets);
 
   /// associate a node type to each segment in the mesh
-  static void buildSegmentToNodeType(const Mesh & mesh, Mesh & mesh_facets);
+  // static void buildSegmentToNodeType(const Mesh & mesh, Mesh & mesh_facets);
 
   /// update local and master global connectivity when new nodes are added
   static UInt updateLocalMasterGlobalConnectivity(Mesh & mesh,
                                                   UInt old_nb_nodes);
 
 private:
   /// match pairs that are on the associated pbc's
   static void matchPBCPairs(const Mesh & mymesh, const UInt dir,
                             Array<UInt> & selected_left,
                             Array<UInt> & selected_right,
                             std::map<UInt, UInt> & pbc_pair);
 
   /// function used by all the renumbering functions
   static void
   renumberNodesInConnectivity(Array<UInt> & list_nodes, UInt nb_nodes,
                               std::map<UInt, UInt> & renumbering_map);
 
   /// update facet_to_subfacet
   static void updateFacetToSubfacet(Mesh & mesh_facets,
                                     ElementType type_subfacet,
                                     GhostType gt_subfacet, bool facet_mode);
 
   /// update subfacet_to_facet
   static void updateSubfacetToFacet(Mesh & mesh_facets,
                                     ElementType type_subfacet,
                                     GhostType gt_subfacet, bool facet_mode);
 
   /// function to double a given facet and update the list of doubled
   /// nodes
   static void doubleFacet(Mesh & mesh, Mesh & mesh_facets, UInt facet_dimension,
                           Array<UInt> & doubled_nodes, bool facet_mode);
 
   /// function to double a subfacet given start and end index for
   /// local facet_to_subfacet vector, and update the list of doubled
   /// nodes
   template <UInt spatial_dimension>
   static void doubleSubfacet(Mesh & mesh, Mesh & mesh_facets,
                              Array<UInt> & doubled_nodes);
 
   /// double a node
   static void doubleNodes(Mesh & mesh, const std::vector<UInt> & old_nodes,
                           Array<UInt> & doubled_nodes);
 
   /// fill facet_to_double array in the mesh
   /// returns the number of facets to be doubled
   static UInt
   updateFacetToDouble(Mesh & mesh_facets,
                       const ElementTypeMapArray<bool> & facet_insertion);
 
   /// find subfacets to be doubled
   template <bool subsubfacet_mode>
   static void findSubfacetToDouble(Mesh & mesh, Mesh & mesh_facets);
 
   /// double facets (points) in 1D
   static void doublePointFacet(Mesh & mesh, Mesh & mesh_facets,
                                Array<UInt> & doubled_nodes);
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
   /// update cohesive element data
   static void updateCohesiveData(Mesh & mesh, Mesh & mesh_facets,
                                  Array<Element> & new_elements);
 #endif
 
   /// update elemental connectivity after doubling a node
   inline static void
   updateElementalConnectivity(Mesh & mesh, UInt old_node, UInt new_node,
                               const std::vector<Element> & element_list,
                               const std::vector<Element> * facet_list = NULL);
 
   /// double middle nodes if facets are _segment_3
   template <bool third_dim_segments>
   static void updateQuadraticSegments(Mesh & mesh, Mesh & mesh_facets,
                                       ElementType type_facet,
                                       GhostType gt_facet,
                                       Array<UInt> & doubled_nodes);
 
   /// remove elements on a vector
   inline static bool
   removeElementsInVector(const std::vector<Element> & elem_to_remove,
                          std::vector<Element> & elem_list);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "mesh_utils_inline_impl.cc"
 
 } // akantu
 #endif /* __AKANTU_MESH_UTILS_HH__ */
diff --git a/src/synchronizer/master_element_info_per_processor.cc b/src/synchronizer/master_element_info_per_processor.cc
index 44560563c..7699f00d5 100644
--- a/src/synchronizer/master_element_info_per_processor.cc
+++ b/src/synchronizer/master_element_info_per_processor.cc
@@ -1,490 +1,485 @@
 /**
  * @file   master_element_info_per_processor.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Fri Mar 11 14:57:13 2016
  *
  * @brief
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
+#include "aka_zip.hh"
 #include "element_group.hh"
 #include "element_info_per_processor.hh"
 #include "element_synchronizer.hh"
 #include "mesh_utils.hh"
 #include "static_communicator.hh"
 /* -------------------------------------------------------------------------- */
 #include <algorithm>
 #include <iostream>
 #include <map>
+#include <tuple>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 MasterElementInfoPerProc::MasterElementInfoPerProc(
     ElementSynchronizer & synchronizer, UInt message_cnt, UInt root,
     ElementType type, const MeshPartition & partition)
     : ElementInfoPerProc(synchronizer, message_cnt, root, type),
       partition(partition), all_nb_local_element(nb_proc, 0),
       all_nb_ghost_element(nb_proc, 0), all_nb_element_to_send(nb_proc, 0) {
   Vector<UInt> size(5);
   size(0) = (UInt)type;
 
   if (type != _not_defined) {
     nb_nodes_per_element = Mesh::getNbNodesPerElement(type);
     nb_element = mesh.getNbElement(type);
     const Array<UInt> & partition_num =
         this->partition.getPartition(this->type, _not_ghost);
     const CSR<UInt> & ghost_partition =
         this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
     for (UInt el = 0; el < nb_element; ++el) {
       this->all_nb_local_element[partition_num(el)]++;
       for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
            part != ghost_partition.end(el); ++part) {
         this->all_nb_ghost_element[*part]++;
       }
       this->all_nb_element_to_send[partition_num(el)] +=
           ghost_partition.getNbCols(el) + 1;
     }
 
     /// tag info
     std::vector<std::string> tag_names;
     this->getMeshData().getTagNames(tag_names, type);
     this->nb_tags = tag_names.size();
 
     size(4) = nb_tags;
 
     for (UInt p = 0; p < nb_proc; ++p) {
       if (p != root) {
         size(1) = this->all_nb_local_element[p];
         size(2) = this->all_nb_ghost_element[p];
         size(3) = this->all_nb_element_to_send[p];
         AKANTU_DEBUG_INFO(
             "Sending connectivities informations to proc "
             << p << " TAG("
             << Tag::genTag(this->rank, this->message_count, Tag::_SIZES)
             << ")");
         comm.send(size, p,
                   Tag::genTag(this->rank, this->message_count, Tag::_SIZES));
       } else {
         this->nb_local_element = this->all_nb_local_element[p];
         this->nb_ghost_element = this->all_nb_ghost_element[p];
       }
     }
   } else {
     for (UInt p = 0; p < this->nb_proc; ++p) {
       if (p != this->root) {
         AKANTU_DEBUG_INFO(
             "Sending empty connectivities informations to proc "
             << p << " TAG("
             << Tag::genTag(this->rank, this->message_count, Tag::_SIZES)
             << ")");
         comm.send(size, p,
                   Tag::genTag(this->rank, this->message_count, Tag::_SIZES));
       }
     }
   }
 }
 
 /* ------------------------------------------------------------------------ */
 void MasterElementInfoPerProc::synchronizeConnectivities() {
   const Array<UInt> & partition_num =
       this->partition.getPartition(this->type, _not_ghost);
   const CSR<UInt> & ghost_partition =
       this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
   std::vector<Array<UInt>> buffers(this->nb_proc);
 
   auto conn_it = this->mesh.getConnectivity(this->type, _not_ghost)
                      .begin(this->nb_nodes_per_element);
   auto conn_end = this->mesh.getConnectivity(this->type, _not_ghost)
                       .end(this->nb_nodes_per_element);
 
   /// copying the local connectivity
   auto part_it = partition_num.begin();
   for (; conn_it != conn_end; ++conn_it, ++part_it) {
     const auto & conn = *conn_it;
     for (UInt i = 0; i < conn.size(); ++i) {
       buffers[*part_it].push_back(conn[i]);
     }
   }
 
   /// copying the connectivity of ghost element
   conn_it = this->mesh.getConnectivity(this->type, _not_ghost)
                 .begin(this->nb_nodes_per_element);
   for (UInt el = 0; conn_it != conn_end; ++el, ++conn_it) {
     for (auto part = ghost_partition.begin(el); part != ghost_partition.end(el);
          ++part) {
       UInt proc = *part;
       const Vector<UInt> & conn = *conn_it;
       for (UInt i = 0; i < conn.size(); ++i) {
         buffers[proc].push_back(conn[i]);
       }
     }
   }
 
 #ifndef AKANTU_NDEBUG
   for (UInt p = 0; p < this->nb_proc; ++p) {
     UInt size = this->nb_nodes_per_element *
                 (this->all_nb_local_element[p] + this->all_nb_ghost_element[p]);
     AKANTU_DEBUG_ASSERT(
         buffers[p].getSize() == size,
         "The connectivity data packed in the buffer are not correct");
   }
 #endif
 
   /// send all connectivity and ghost information to all processors
   std::vector<CommunicationRequest> requests;
   for (UInt p = 0; p < this->nb_proc; ++p) {
     if (p != this->root) {
       AKANTU_DEBUG_INFO(
           "Sending connectivities to proc "
           << p << " TAG("
           << Tag::genTag(this->rank, this->message_count, Tag::_CONNECTIVITY)
           << ")");
       requests.push_back(comm.asyncSend(
           buffers[p], p,
           Tag::genTag(this->rank, this->message_count, Tag::_CONNECTIVITY)));
     }
   }
 
   Array<UInt> & old_nodes = this->getNodesGlobalIds();
 
   /// create the renumbered connectivity
   AKANTU_DEBUG_INFO("Renumbering local connectivities");
   MeshUtils::renumberMeshNodes(mesh, buffers[root], all_nb_local_element[root],
                                all_nb_ghost_element[root], type, old_nodes);
 
   comm.waitAll(requests);
   comm.freeCommunicationRequest(requests);
 }
 
 /* ------------------------------------------------------------------------ */
 void MasterElementInfoPerProc::synchronizePartitions() {
   const Array<UInt> & partition_num =
       this->partition.getPartition(this->type, _not_ghost);
   const CSR<UInt> & ghost_partition =
       this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
   std::vector<Array<UInt>> buffers(this->partition.getNbPartition());
 
   /// splitting the partition information to send them to processors
   Vector<UInt> count_by_proc(nb_proc, 0);
   for (UInt el = 0; el < nb_element; ++el) {
     UInt proc = partition_num(el);
     buffers[proc].push_back(ghost_partition.getNbCols(el));
 
     UInt i(0);
     for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
          part != ghost_partition.end(el); ++part, ++i) {
       buffers[proc].push_back(*part);
     }
   }
 
   for (UInt el = 0; el < nb_element; ++el) {
     UInt i(0);
     for (CSR<UInt>::const_iterator part = ghost_partition.begin(el);
          part != ghost_partition.end(el); ++part, ++i) {
       buffers[*part].push_back(partition_num(el));
     }
   }
 
 #ifndef AKANTU_NDEBUG
   for (UInt p = 0; p < this->nb_proc; ++p) {
     AKANTU_DEBUG_ASSERT(
         buffers[p].getSize() ==
             (this->all_nb_ghost_element[p] + this->all_nb_element_to_send[p]),
         "Data stored in the buffer are most probably wrong");
   }
 #endif
 
   std::vector<CommunicationRequest> requests;
   /// last data to compute the communication scheme
   for (UInt p = 0; p < this->nb_proc; ++p) {
     if (p != this->root) {
       AKANTU_DEBUG_INFO(
           "Sending partition informations to proc "
           << p << " TAG("
           << Tag::genTag(this->rank, this->message_count, Tag::_PARTITIONS)
           << ")");
       requests.push_back(comm.asyncSend(
           buffers[p], p,
           Tag::genTag(this->rank, this->message_count, Tag::_PARTITIONS)));
     }
   }
 
   if (Mesh::getSpatialDimension(this->type) ==
       this->mesh.getSpatialDimension()) {
     AKANTU_DEBUG_INFO("Creating communications scheme");
     this->fillCommunicationScheme(buffers[this->rank]);
   }
 
   comm.waitAll(requests);
   comm.freeCommunicationRequest(requests);
 }
 
 /* -------------------------------------------------------------------------- */
 void MasterElementInfoPerProc::synchronizeTags() {
   AKANTU_DEBUG_IN();
 
   if (this->nb_tags == 0) {
     AKANTU_DEBUG_OUT();
     return;
   }
 
   UInt mesh_data_sizes_buffer_length;
   MeshData & mesh_data = this->getMeshData();
 
   /// tag info
   std::vector<std::string> tag_names;
   mesh_data.getTagNames(tag_names, type);
   // Make sure the tags are sorted (or at least not in random order),
   // because they come from a map !!
   std::sort(tag_names.begin(), tag_names.end());
 
   // Sending information about the tags in mesh_data: name, data type and
   // number of components of the underlying array associated to the current
   // type
   DynamicCommunicationBuffer mesh_data_sizes_buffer;
   std::vector<std::string>::const_iterator names_it = tag_names.begin();
   std::vector<std::string>::const_iterator names_end = tag_names.end();
   for (; names_it != names_end; ++names_it) {
     mesh_data_sizes_buffer << *names_it;
     mesh_data_sizes_buffer << mesh_data.getTypeCode(*names_it);
     mesh_data_sizes_buffer << mesh_data.getNbComponent(*names_it, type);
   }
 
   mesh_data_sizes_buffer_length = mesh_data_sizes_buffer.getSize();
   AKANTU_DEBUG_INFO(
       "Broadcasting the size of the information about the mesh data tags: ("
       << mesh_data_sizes_buffer_length << ").");
   comm.broadcast(mesh_data_sizes_buffer_length, root);
   AKANTU_DEBUG_INFO(
       "Broadcasting the information about the mesh data tags, addr "
       << (void *)mesh_data_sizes_buffer.storage());
 
   if (mesh_data_sizes_buffer_length != 0)
     comm.broadcast(mesh_data_sizes_buffer, root);
 
   if (mesh_data_sizes_buffer_length != 0) {
     // Sending the actual data to each processor
     DynamicCommunicationBuffer * buffers =
         new DynamicCommunicationBuffer[nb_proc];
     std::vector<std::string>::const_iterator names_it = tag_names.begin();
     std::vector<std::string>::const_iterator names_end = tag_names.end();
 
     // Loop over each tag for the current type
     for (; names_it != names_end; ++names_it) {
       // Type code of the current tag (i.e. the tag named *names_it)
       this->fillTagBuffer(buffers, *names_it);
     }
 
     std::vector<CommunicationRequest> requests;
     for (UInt p = 0; p < nb_proc; ++p) {
       if (p != root) {
         AKANTU_DEBUG_INFO("Sending "
                           << buffers[p].getSize()
                           << " bytes of mesh data to proc " << p << " TAG("
                           << Tag::genTag(this->rank, this->message_count,
                                          Tag::_MESH_DATA)
                           << ")");
 
         requests.push_back(comm.asyncSend(
             buffers[p], p,
             Tag::genTag(this->rank, this->message_count, Tag::_MESH_DATA)));
       }
     }
 
     names_it = tag_names.begin();
     // Loop over each tag for the current type
     for (; names_it != names_end; ++names_it) {
       // Reinitializing the mesh data on the master
       this->fillMeshData(buffers[root], *names_it,
                          mesh_data.getTypeCode(*names_it),
                          mesh_data.getNbComponent(*names_it, type));
     }
 
     comm.waitAll(requests);
     comm.freeCommunicationRequest(requests);
     requests.clear();
     delete[] buffers;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename T>
 void MasterElementInfoPerProc::fillTagBufferTemplated(
     DynamicCommunicationBuffer * buffers, const std::string & tag_name) {
   MeshData & mesh_data = this->getMeshData();
 
   const Array<T> & data = mesh_data.getElementalDataArray<T>(tag_name, type);
   const Array<UInt> & partition_num =
       this->partition.getPartition(this->type, _not_ghost);
   const CSR<UInt> & ghost_partition =
       this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
   // Not possible to use the iterator because it potentially triggers the
   // creation of complex
   // type templates (such as akantu::Vector< std::vector<Element> > which don't
   // implement the right interface
   // (e.g. operator<< in that case).
   // typename Array<T>::template const_iterator< Vector<T> > data_it  =
   // data.begin(data.getNbComponent());
   // typename Array<T>::template const_iterator< Vector<T> > data_end =
   // data.end(data.getNbComponent());
 
   const T * data_it = data.storage();
   const T * data_end = data.storage() + data.getSize() * data.getNbComponent();
   const UInt * part = partition_num.storage();
 
   /// copying the data, element by element
   for (; data_it != data_end; ++part) {
     for (UInt j(0); j < data.getNbComponent(); ++j, ++data_it) {
       buffers[*part] << *data_it;
     }
   }
 
   data_it = data.storage();
   /// copying the data for the ghost element
   for (UInt el(0); data_it != data_end;
        data_it += data.getNbComponent(), ++el) {
     CSR<UInt>::const_iterator it = ghost_partition.begin(el);
     CSR<UInt>::const_iterator end = ghost_partition.end(el);
     for (; it != end; ++it) {
       UInt proc = *it;
       for (UInt j(0); j < data.getNbComponent(); ++j) {
         buffers[proc] << data_it[j];
       }
     }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 void MasterElementInfoPerProc::fillTagBuffer(
     DynamicCommunicationBuffer * buffers, const std::string & tag_name) {
   MeshData & mesh_data = this->getMeshData();
 
 #define AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA(r, extra_param, elem)          \
   case BOOST_PP_TUPLE_ELEM(2, 0, elem): {                                      \
     this->fillTagBufferTemplated<BOOST_PP_TUPLE_ELEM(2, 1, elem)>(buffers,     \
                                                                   tag_name);   \
     break;                                                                     \
   }
 
   MeshDataTypeCode data_type_code = mesh_data.getTypeCode(tag_name);
   switch (data_type_code) {
     BOOST_PP_SEQ_FOR_EACH(AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA, ,
                           AKANTU_MESH_DATA_TYPES)
   default:
     AKANTU_DEBUG_ERROR("Could not obtain the type of tag" << tag_name << "!");
     break;
   }
 #undef AKANTU_DISTRIBUTED_SYNHRONIZER_TAG_DATA
 }
 
 /* -------------------------------------------------------------------------- */
 void MasterElementInfoPerProc::synchronizeGroups() {
   AKANTU_DEBUG_IN();
 
   DynamicCommunicationBuffer * buffers =
       new DynamicCommunicationBuffer[nb_proc];
 
-  typedef std::vector<std::vector<std::string>> ElementToGroup;
+  using ElementToGroup = std::vector<std::vector<std::string>>;
   ElementToGroup element_to_group;
   element_to_group.resize(nb_element);
 
-  GroupManager::const_element_group_iterator egi = mesh.element_group_begin();
-  GroupManager::const_element_group_iterator ege = mesh.element_group_end();
+  auto egi = mesh.element_group_begin();
+  auto ege = mesh.element_group_end();
   for (; egi != ege; ++egi) {
     ElementGroup & eg = *(egi->second);
 
     std::string name = egi->first;
 
-    ElementGroup::const_element_iterator eit =
-        eg.element_begin(type, _not_ghost);
-    ElementGroup::const_element_iterator eend =
-        eg.element_end(type, _not_ghost);
-    for (; eit != eend; ++eit) {
-      element_to_group[*eit].push_back(name);
+    for (const auto & element : eg.getElements(type, _not_ghost)) {
+      element_to_group[element].push_back(name);
     }
 
-    eit = eg.element_begin(type, _not_ghost);
-    if (eit != eend)
+    auto eit = eg.begin(type, _not_ghost);
+    if (eit != eg.end(type, _not_ghost))
       const_cast<Array<UInt> &>(eg.getElements(type)).empty();
   }
 
-  const Array<UInt> & partition_num =
+  const auto & partition_num =
       this->partition.getPartition(this->type, _not_ghost);
-  const CSR<UInt> & ghost_partition =
+  const auto & ghost_partition =
       this->partition.getGhostPartitionCSR()(this->type, _not_ghost);
 
-  /// preparing the buffers
-  const UInt * part = partition_num.storage();
-
   /// copying the data, element by element
   ElementToGroup::const_iterator data_it = element_to_group.begin();
   ElementToGroup::const_iterator data_end = element_to_group.end();
-  for (; data_it != data_end; ++part, ++data_it) {
-    buffers[*part] << *data_it;
+  for (auto pair : zip(partition_num, element_to_group)) {
+    buffers[std::get<0>(pair)] << std::get<1>(pair);
   }
 
   data_it = element_to_group.begin();
   /// copying the data for the ghost element
   for (UInt el(0); data_it != data_end; ++data_it, ++el) {
     CSR<UInt>::const_iterator it = ghost_partition.begin(el);
     CSR<UInt>::const_iterator end = ghost_partition.end(el);
     for (; it != end; ++it) {
       UInt proc = *it;
       buffers[proc] << *data_it;
     }
   }
 
   std::vector<CommunicationRequest> requests;
   for (UInt p = 0; p < this->nb_proc; ++p) {
     if (p == this->rank)
       continue;
     AKANTU_DEBUG_INFO("Sending element groups to proc "
                       << p << " TAG("
                       << Tag::genTag(this->rank, p, Tag::_ELEMENT_GROUP)
                       << ")");
     requests.push_back(comm.asyncSend(
         buffers[p], p, Tag::genTag(this->rank, p, Tag::_ELEMENT_GROUP)));
   }
 
   this->fillElementGroupsFromBuffer(buffers[this->rank]);
 
   comm.waitAll(requests);
   comm.freeCommunicationRequest(requests);
   requests.clear();
   delete[] buffers;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 
-} // akantu
+} // namespace akantu
diff --git a/test/test_common/test_grid.cc b/test/test_common/test_grid.cc
index 3edc9d699..6dff392f9 100644
--- a/test/test_common/test_grid.cc
+++ b/test/test_common/test_grid.cc
@@ -1,108 +1,107 @@
 /**
  * @file   test_grid.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
  * @date last modification: Thu Aug 06 2015
  *
  * @brief  Test the grid object
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_grid_dynamic.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   const UInt spatial_dimension = 2;
   akantu::initialize(argc, argv);
 
   Mesh circle(spatial_dimension);
   circle.read("circle.msh");
 
-  circle.computeBoundingBox();
   const Vector<Real> & l = circle.getLocalLowerBounds();
   const Vector<Real> & u = circle.getLocalUpperBounds();
 
   Real spacing[spatial_dimension] = {0.2, 0.2};
 
   Vector<Real> s(spacing, spatial_dimension);
 
   Vector<Real> c = u;
   c += l;
   c /= 2.;
 
   SpatialGrid<Element> grid(spatial_dimension, s, c);
 
   Vector<Real> bary(spatial_dimension);
   Element el;
   el.ghost_type = _not_ghost;
 
   Mesh::type_iterator it        = circle.firstType(spatial_dimension);
   Mesh::type_iterator last_type = circle.lastType (spatial_dimension);
   for(; it != last_type; ++it) {
     UInt nb_element = circle.getNbElement(*it);
     el.type = *it;
 
     for (UInt e = 0; e < nb_element; ++e) {
       circle.getBarycenter(e, el.type, bary.storage());
       el.element = e;
       grid.insert(el, bary);
     }
   }
 
   std::cout << grid << std::endl;
   Mesh mesh(spatial_dimension, "save");
   grid.saveAsMesh(mesh);
   mesh.write("grid.msh");
 
   Vector<Real> pos(spatial_dimension);
 
   //  const SpatialGrid<Element>::CellID & id = grid.getCellID(pos);
 
 // #if !defined AKANTU_NDEBUG
 //   SpatialGrid<Element>::neighbor_cells_iterator nit = grid.beginNeighborCells(id);
 //   SpatialGrid<Element>::neighbor_cells_iterator nend = grid.endNeighborCells(id);
 //   for(;nit != nend; ++nit) {
 //     std::cout << std::endl;
 //     const SpatialGrid<Element>::Cell & cell = grid.getCell(*nit);
 //     SpatialGrid<Element>::Cell::const_iterator cit = cell.begin();
 //     SpatialGrid<Element>::Cell::position_iterator pit = cell.begin_pos();
 //     SpatialGrid<Element>::Cell::const_iterator cend = cell.end();
 //     for (; cit != cend; ++cit, ++pit) {
 //       std::cout << *cit << " " << *pit << std::endl;
 //     }
 //   }
 // #endif
 
 
   akantu::finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_fe_engine/test_fe_engine_gauss_integration.cc b/test/test_fe_engine/test_fe_engine_gauss_integration.cc
index 225b15096..815cc9ae8 100644
--- a/test/test_fe_engine/test_fe_engine_gauss_integration.cc
+++ b/test/test_fe_engine/test_fe_engine_gauss_integration.cc
@@ -1,204 +1,203 @@
 /**
  * @file   test_fe_engine_precomputation.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
  * @date last modification: Mon Jul 13 2015
  *
  * @brief test integration on elements, this test consider that mesh is a cube
  *
  * @section 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 "shape_lagrange.hh"
 #include "integrator_gauss.hh"
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange> FEM;
 const ElementType type = TYPE;
 
 //                        cst           x           x^2           x^3
 //                        x^4          x^5
 Real alpha[3][6] = {{0.40062394, 0.13703225, 0.51731446, 0.87830084, 0.5410543,
                      0.71842292}, // x
                     {0.41861835, 0.11080576, 0.49874043, 0.49077504, 0.85073835,
                      0.66259755}, // y
                     {0.92620845, 0.7503478, 0.62962232, 0.31662719, 0.64069644,
                      0.30878135}}; // z
 
 static Vector<Real> eval_poly(UInt degree, const Vector<Real> & x) {
   Vector<Real> res(x.size());
   for (UInt i = 0; i < degree + 1; ++i) {
     for (UInt d = 0; d < x.size(); ++d) {
       res(d) += std::pow(x(d), i) * alpha[d][i];
     }
   }
   return res;
 }
 
 static Vector<Real> eval_int(UInt degree, const Vector<Real> & a,
                              const Vector<Real> & b) {
   Vector<Real> res(a.size());
   for (UInt i = 0; i < degree + 1; ++i) {
     for (UInt d = 0; d < a.size(); ++d) {
       res(d) += (std::pow(b(d), i + 1) - std::pow(a(d), i + 1)) * alpha[d][i] / Real(i + 1);
     }
   }
 
   if (a.size() == 3) {
     res(_x) *= std::abs(b(_y) - a(_y)) * std::abs(b(_z) - a(_z));
     res(_y) *= std::abs(b(_x) - a(_x)) * std::abs(b(_z) - a(_z));
     res(_z) *= std::abs(b(_y) - a(_y)) * std::abs(b(_x) - a(_x));
   } else if (a.size() == 2) {
     res(_x) *= std::abs(b(_y) - a(_y));
     res(_y) *= std::abs(b(_x) - a(_x));
   }
 
   return res;
 }
 
 template <UInt degree>
 static Vector<Real> integrate_poly(UInt poly_degree, FEM & fem) {
   Mesh & mesh = fem.getMesh();
   UInt dim = mesh.getSpatialDimension();
 
   Matrix<Real> integration_points =
       fem.getIntegrator().getIntegrationPoints<type, degree>();
 
   // Vector<Real> integration_weights =
   //     fem.getIntegrator().getIntegrationWeights<type, degree>();
 
   // for (UInt i = 0; i < integration_points.cols(); ++i) {
   //   std::cout << "q(" << i << ") = " << Vector<Real>(integration_points(i))
   //   << " - w(" << i << ") = "<< integration_weights[i] << std::endl;
   // }
 
   UInt nb_integration_points = integration_points.cols();
   UInt nb_element = mesh.getNbElement(type);
 
   UInt shapes_size = ElementClass<type>::getShapeSize();
   Array<Real> shapes(0, shapes_size);
   fem.getShapeFunctions().computeShapesOnIntegrationPoints<type>(
       mesh.getNodes(), integration_points, shapes, _not_ghost);
 
   UInt vect_size = nb_integration_points * nb_element;
   Array<Real> integration_points_pos(vect_size, dim);
   fem.getShapeFunctions().interpolateOnIntegrationPoints<type>(
       mesh.getNodes(), integration_points_pos, dim, shapes);
 
   Array<Real> polynomial(vect_size, dim);
 
   Array<Real>::vector_iterator P_it = polynomial.begin(dim);
   Array<Real>::vector_iterator P_end = polynomial.end(dim);
   Array<Real>::const_vector_iterator x_it = integration_points_pos.begin(dim);
 
   for (; P_it != P_end; ++P_it, ++x_it) {
     *P_it = eval_poly(poly_degree, *x_it);
      //   std::cout << "Q = " << *x_it << std::endl;
      //   std::cout << "P(Q) = " << *P_it << std::endl;
   }
 
   Vector<Real> res(dim);
 
   Array<Real> polynomial_1d(vect_size, 1);
   for (UInt d = 0; d < dim; ++d) {
     Array<Real>::const_vector_iterator P_it = polynomial.begin(dim);
     Array<Real>::const_vector_iterator P_end = polynomial.end(dim);
     Array<Real>::scalar_iterator P1_it = polynomial_1d.begin();
     for (; P_it != P_end; ++P_it, ++P1_it) {
       *P1_it = (*P_it)(d);
       // std::cout << "P(Q, d) = " << *P1_it << std::endl;
     }
     res(d) = fem.getIntegrator().integrate<type, degree>(polynomial_1d);
   }
 
   return res;
 }
 
 int main(int argc, char * argv[]) {
   akantu::initialize(argc, argv);
 
   const UInt dim = ElementClass<type>::getSpatialDimension();
   Mesh mesh(dim);
 
   std::stringstream meshfilename;
   meshfilename << type << ".msh";
   mesh.read(meshfilename.str());
 
   FEM fem(mesh, dim, "my_fem");
 
-  mesh.computeBoundingBox();
   const Vector<Real> & lower = mesh.getLowerBounds();
   const Vector<Real> & upper = mesh.getUpperBounds();
 
   bool ok = true;
 
   for (UInt d = 0; d < 6; ++d) {
     Vector<Real> res(dim);
     switch (d) {
     case 0:
       res = integrate_poly<1>(d, fem);
       break;
     case 1:
       res = integrate_poly<1>(d, fem);
       break;
     case 2:
       res = integrate_poly<2>(d, fem);
       break;
     case 3:
       res = integrate_poly<3>(d, fem);
       break;
     case 4:
       res = integrate_poly<4>(d, fem);
       break;
     case 5:
       res = integrate_poly<5>(d, fem);
       break;
     }
 
     Vector<Real> exact(dim);
     exact = eval_int(d, lower, upper);
 
     Vector<Real> error(dim);
     error = exact - res;
 
     Real error_n = error.norm<L_inf>();
     if (error_n > 5e-14) {
       std::cout << d << " -> Resultat " << res << " - ";
       std::cout << "Exact" << exact << " -- ";
       std::cout << error << " {" << error_n << "}" << std::endl;
       ok = false;
     }
   }
 
   finalize();
 
   if (ok)
     return 0;
   else
     return 1;
 }
diff --git a/test/test_fe_engine/test_inverse_map.cc b/test/test_fe_engine/test_inverse_map.cc
index 5aef24bce..9ecdcb234 100644
--- a/test/test_fe_engine/test_inverse_map.cc
+++ b/test/test_fe_engine/test_inverse_map.cc
@@ -1,106 +1,106 @@
 /**
  * @file   test_inverse_map.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Fri Sep 03 2010
  * @date last modification: Thu Oct 15 2015
  *
  * @brief  test of the fem class
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "fe_engine.hh"
-#include "shape_lagrange.hh"
 #include "integrator_gauss.hh"
+#include "shape_lagrange.hh"
 /* -------------------------------------------------------------------------- */
 #include <cstdlib>
 #include <iostream>
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
-int main(int argc, char *argv[]) {
+int main(int argc, char * argv[]) {
   akantu::initialize(argc, argv);
 
   debug::setDebugLevel(dblTest);
   const ElementType type = TYPE;
   UInt dim = ElementClass<type>::getSpatialDimension();
 
   Mesh my_mesh(dim);
 
-  my_mesh.computeBoundingBox();
   const Vector<Real> & lower = my_mesh.getLowerBounds();
   const Vector<Real> & upper = my_mesh.getUpperBounds();
 
-  std::stringstream meshfilename; meshfilename << type << ".msh";
+  std::stringstream meshfilename;
+  meshfilename << type << ".msh";
   my_mesh.read(meshfilename.str());
 
   UInt nb_elements = my_mesh.getNbElement(type);
   ///
-  FEEngineTemplate<IntegratorGauss,ShapeLagrange> *fem =
-    new FEEngineTemplate<IntegratorGauss,ShapeLagrange>(my_mesh, dim, "my_fem");
+  FEEngineTemplate<IntegratorGauss, ShapeLagrange> * fem =
+      new FEEngineTemplate<IntegratorGauss, ShapeLagrange>(my_mesh, dim,
+                                                           "my_fem");
 
   fem->initShapeFunctions();
 
   UInt nb_quad_points = fem->getNbIntegrationPoints(type);
 
   /// get the quadrature points coordinates
-  Array<Real> coord_on_quad(nb_quad_points*nb_elements,
-			     my_mesh.getSpatialDimension(),
-			     "coord_on_quad");
-
-  fem->interpolateOnIntegrationPoints(my_mesh.getNodes(),
-				     coord_on_quad,
-				     my_mesh.getSpatialDimension(),
-				     type);
+  Array<Real> coord_on_quad(nb_quad_points * nb_elements,
+                            my_mesh.getSpatialDimension(), "coord_on_quad");
 
+  fem->interpolateOnIntegrationPoints(my_mesh.getNodes(), coord_on_quad,
+                                      my_mesh.getSpatialDimension(), type);
 
   /// loop over the quadrature points
-  Array<Real>::iterator< Vector<Real> > it = coord_on_quad.begin(dim);
+  Array<Real>::iterator<Vector<Real>> it = coord_on_quad.begin(dim);
   Vector<Real> natural_coords(dim);
 
   Matrix<Real> quad = GaussIntegrationElement<type>::getQuadraturePoints();
 
-  for(UInt el = 0 ; el < nb_elements ; ++el){
-    for(UInt q = 0 ; q < nb_quad_points ; ++q){
+  for (UInt el = 0; el < nb_elements; ++el) {
+    for (UInt q = 0; q < nb_quad_points; ++q) {
       fem->inverseMap(*it, el, type, natural_coords);
       for (UInt i = 0; i < dim; ++i) {
-	__attribute__ ((unused)) const Real eps = 1e-13;
-	AKANTU_DEBUG_ASSERT(std::abs((natural_coords(i) - quad(i,q))/(upper(i)-lower(i))) < eps,
-			    "real coordinates inversion test failed:"
-			    << natural_coords(i) << " - " << quad(i, q)
-			    << " = " << (natural_coords(i) - quad(i, q))/(upper(i)-lower(i)));
+        __attribute__((unused)) const Real eps = 1e-13;
+        AKANTU_DEBUG_ASSERT(
+            std::abs((natural_coords(i) - quad(i, q)) / (upper(i) - lower(i))) <
+                eps,
+            "real coordinates inversion test failed:"
+                << natural_coords(i) << " - " << quad(i, q) << " = "
+                << (natural_coords(i) - quad(i, q)) / (upper(i) - lower(i)));
       }
       ++it;
     }
   }
 
-  std::cout << "inverse completed over " << nb_elements << " elements" << std::endl;
+  std::cout << "inverse completed over " << nb_elements << " elements"
+            << std::endl;
 
   delete fem;
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/CMakeLists.txt b/test/test_mesh_utils/CMakeLists.txt
index 70f83bed2..f96c07092 100644
--- a/test/test_mesh_utils/CMakeLists.txt
+++ b/test/test_mesh_utils/CMakeLists.txt
@@ -1,50 +1,55 @@
 #===============================================================================
 # @file   CMakeLists.txt
 #
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date creation: Fri Oct 22 2010
 # @date last modification: Fri Sep 18 2015
 #
 # @brief  configuration for MeshUtils tests
 #
 # @section LICENSE
 #
 # Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
 # Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
 # Solides)
 #
 # Akantu is free  software: you can redistribute it and/or  modify it under the
 # terms  of the  GNU Lesser  General Public  License as  published by  the Free
 # Software Foundation, either version 3 of the License, or (at your option) any
 # later version.
 #
 # Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
 # details.
 #
 # You should  have received  a copy  of the GNU  Lesser General  Public License
 # along with Akantu. If not, see <http://www.gnu.org/licenses/>.
 #
 # @section DESCRIPTION
 #
 #===============================================================================
 
 #===============================================================================
 # List of tests
 #===============================================================================
 add_akantu_test(test_mesh_io "Test mesh io object")
 add_akantu_test(test_pbc_tweak "Test pbc facilities")
 add_akantu_test(test_buildfacets "Tests for the generation of facets")
 add_akantu_test(test_segment_nodetype "segment_nodetype")
 
 register_test(test_purify_mesh
   SOURCES test_purify_mesh.cc
   FILES_TO_COPY purify_mesh.msh
   PACKAGE core
   )
 
-add_akantu_test(test_mesh_partitionate "Test mesh partition creation")
-
+add_mesh(test_mesh_iterators_mesh iterators_mesh.geo 3 1 OUTPUT iterators_mesh.msh)
+register_test(test_mesh_iterators
+  SOURCES test_mesh_iterators.cc
+  PACKAGE core
+  DEPENDS test_mesh_iterators_mesh
+  )
 
+add_akantu_test(test_mesh_partitionate "Test mesh partition creation")
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
index 9f814dc7b..2934e326c 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_20.cc
@@ -1,143 +1,143 @@
 /**
  * @file   test_buildfacets_hexahedron_20.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with hexahedrons
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 3;
   const ElementType type = _hexahedron_20;
 
   Mesh mesh(spatial_dimension);
   mesh.read("hexahedron_20.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   // debug::setDebugLevel(dblDump);
   // std::cout << mesh << std::endl;
   // std::cout << mesh_facets << std::endl;
 
   const ElementType type_facet = mesh.getFacetType(type);
   const ElementType type_subfacet = mesh.getFacetType(type_facet);
   const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
 
 
   std::cout << "ElementToSubelement3" << std::endl;
   for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subsubfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
   const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement3" << std::endl;
   for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
     std::cout << type << " " << i << " connected to ";
     for (UInt j = 0; j < 6; ++j){
       std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 4; ++j){
       std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
index 1ea23ee9c..21f6a9261 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_hexahedron_8.cc
@@ -1,144 +1,144 @@
 /**
  * @file   test_buildfacets_hexahedron_8.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with hexahedrons
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 3;
   const ElementType type = _hexahedron_8;
 
   Mesh mesh(spatial_dimension);
   mesh.read("hexahedron_8.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   // debug::setDebugLevel(dblDump);
   // std::cout << mesh << std::endl;
   // std::cout << mesh_facets << std::endl;
 
   const ElementType type_facet = mesh.getFacetType(type);
   const ElementType type_subfacet = mesh.getFacetType(type_facet);
   const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
 
 
   std::cout << "ElementToSubelement3" << std::endl;
   for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subsubfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
   const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
 
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement3" << std::endl;
   for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
     std::cout << type << " " << i << " connected to ";
     for (UInt j = 0; j < 6; ++j){
       std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 4; ++j){
       std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
index 05aa17362..e9d6975a8 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_linear.cc
@@ -1,128 +1,128 @@
 /**
  * @file   test_buildfacets_mixed2d_linear.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Fri Sep 18 2015
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with quadrangles
  * and triangles
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 2;
   const ElementType type1 = _quadrangle_4;
   const ElementType type2 = _triangle_3;
 
   Mesh mesh(spatial_dimension);
   mesh.read("mixed2d_linear.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   const ElementType type_facet = mesh.getFacetType(type1);
   const ElementType type_subfacet = mesh.getFacetType(type_facet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
 
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type1);
   const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type2);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
 
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2_1.getSize(); ++i) {
     std::cout << type1 << " " << i << " connected to ";
     for (UInt j = 0; j < 4; ++j){
       std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   for (UInt i = 0; i < subel_to_el2_2.getSize(); ++i) {
     std::cout << type2 << " " << i << " connected to ";
     for (UInt j = 0; j < 3; ++j){
       std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
index 96bbd9bda..e13f63e65 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed2d_quadratic.cc
@@ -1,128 +1,128 @@
 /**
  * @file   test_buildfacets_mixed2d_quadratic.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Fri Sep 18 2015
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with quadrangles
  * and triangles
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 2;
   const ElementType type1 = _quadrangle_8;
   const ElementType type2 = _triangle_6;
 
   Mesh mesh(spatial_dimension);
   mesh.read("mixed2d_quadratic.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   const ElementType type_facet = mesh.getFacetType(type1);
   const ElementType type_subfacet = mesh.getFacetType(type_facet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
 
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type1);
   const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type2);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
 
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2_1.getSize(); ++i) {
     std::cout << type1 << " " << i << " connected to ";
     for (UInt j = 0; j < 4; ++j){
       std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   for (UInt i = 0; i < subel_to_el2_2.getSize(); ++i) {
     std::cout << type2 << " " << i << " connected to ";
     for (UInt j = 0; j < 3; ++j){
       std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
index 13fd0dd0e..452d24767 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_linear.cc
@@ -1,167 +1,167 @@
 /**
  * @file   test_buildfacets_mixed3d_linear.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with hexahedrons
  * and pentahedrons
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 3;
   const ElementType type1 = _hexahedron_8;
   const ElementType type2 = _pentahedron_6;
 
   Mesh mesh(spatial_dimension);
   mesh.read("mixed3d_linear.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   const ElementType type_facet1 = mesh.getFacetType(type1);
   const ElementType type_facet2 = mesh.getFacetType(type2);
   const ElementType type_subfacet = mesh.getFacetType(type_facet1);
   const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel3_1 = mesh_facets.getElementToSubelement(type_facet1);
   const Array< std::vector<Element> > & el_to_subel3_2 = mesh_facets.getElementToSubelement(type_facet2);
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
 
   std::cout << "ElementToSubelement3" << std::endl;
   for (UInt i = 0; i < el_to_subel3_1.getSize(); ++i) {
     std::cout << type_facet1 << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel3_1(i)[j].type << " " << el_to_subel3_1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   for (UInt i = 0; i < el_to_subel3_2.getSize(); ++i) {
     std::cout << type_facet2 << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel3_2(i)[j].type << " " << el_to_subel3_2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subsubfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el3_1 = mesh_facets.getSubelementToElement(type1);
   const Array<Element> & subel_to_el3_2 = mesh_facets.getSubelementToElement(type2);
   const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type_facet1);
   const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type_facet2);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement3" << std::endl;
   for (UInt i = 0; i < subel_to_el3_1.getSize(); ++i) {
     std::cout << type1 << " " << i << " connected to ";
     for (UInt j = 0; j < 6; ++j){
       std::cout << subel_to_el3_1(i, j).type << " " << subel_to_el3_1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   for (UInt i = 0; i < subel_to_el3_2.getSize(); ++i) {
     std::cout << type2 << " " << i << " connected to ";
     for (UInt j = 0; j < 5; ++j){
       std::cout << subel_to_el3_2(i, j).type << " " << subel_to_el3_2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2_1.getSize(); ++i) {
     std::cout << type_facet1 << " " << i << " connected to ";
     for (UInt j = 0; j < 4; ++j){
       std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   for (UInt i = 0; i < subel_to_el2_2.getSize(); ++i) {
     std::cout << type_facet2 << " " << i << " connected to ";
     for (UInt j = 0; j < 3; ++j){
       std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
index 4ebdd56d5..ab397a3d0 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_mixed3d_quadratic.cc
@@ -1,169 +1,169 @@
 /**
  * @file   test_buildfacets_mixed3d_quadratic.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with hexahedrons
  * and pentahedrons
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 3;
   const ElementType type1 = _hexahedron_20;
   const ElementType type2 = _pentahedron_15;
 
   Mesh mesh(spatial_dimension);
   mesh.read("mixed3d_quadratic.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   const ElementType type_facet1 = mesh.getFacetType(type1);
   const ElementType type_facet2 = mesh.getFacetType(type2);
   const ElementType type_subfacet = mesh.getFacetType(type_facet1);
   const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel3_1 = mesh_facets.getElementToSubelement(type_facet1);
   const Array< std::vector<Element> > & el_to_subel3_2 = mesh_facets.getElementToSubelement(type_facet2);
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
 
   std::cout << "ElementToSubelement3" << std::endl;
   for (UInt i = 0; i < el_to_subel3_1.getSize(); ++i) {
     std::cout << type_facet1 << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel3_1(i)[j].type << " " << el_to_subel3_1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   for (UInt i = 0; i < el_to_subel3_2.getSize(); ++i) {
     std::cout << type_facet2 << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel3_2(i)[j].type << " " << el_to_subel3_2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subsubfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el3_1 = mesh_facets.getSubelementToElement(type1);
   const Array<Element> & subel_to_el3_2 = mesh_facets.getSubelementToElement(type2);
   const Array<Element> & subel_to_el2_1 = mesh_facets.getSubelementToElement(type_facet1);
   const Array<Element> & subel_to_el2_2 = mesh_facets.getSubelementToElement(type_facet2);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement3" << std::endl;
   for (UInt i = 0; i < subel_to_el3_1.getSize(); ++i) {
     std::cout << type1 << " " << i << " connected to ";
     for (UInt j = 0; j < 6; ++j){
       std::cout << subel_to_el3_1(i, j).type << " " << subel_to_el3_1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   for (UInt i = 0; i < subel_to_el3_2.getSize(); ++i) {
     std::cout << type2 << " " << i << " connected to ";
     for (UInt j = 0; j < 5; ++j){
       std::cout << subel_to_el3_2(i, j).type << " " << subel_to_el3_2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2_1.getSize(); ++i) {
     std::cout << type_facet1 << " " << i << " connected to ";
     for (UInt j = 0; j < 4; ++j){
       std::cout << subel_to_el2_1(i, j).type << " " << subel_to_el2_1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2_2.getSize(); ++i) {
     std::cout << type_facet2 << " " << i << " connected to ";
     for (UInt j = 0; j < 3; ++j){
       std::cout << subel_to_el2_2(i, j).type << " " << subel_to_el2_2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
index 208ed4af1..1b63049d6 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_15.cc
@@ -1,148 +1,148 @@
 /**
  * @file   test_buildfacets_pentahedron_15.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Mon Sep 28 2015
  *
  * @brief  Test for cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 3;
   const ElementType type = _pentahedron_15;
 
   Mesh mesh(spatial_dimension);
   mesh.read("pentahedron_15.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   Vector<ElementType> types_facet = mesh.getAllFacetTypes(type);
   const ElementType type_subfacet = mesh.getFacetType(types_facet(0));
   const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   for (UInt ft = 0; ft < types_facet.size(); ++ft) {
     ElementType type_facet = types_facet(ft);
     Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
 
     std::cout << "ElementToSubelement3" << std::endl;
     for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
       std::cout << type_facet << " " << i << " connected to ";
       for (UInt j = 0; j < 2; ++j){
 	std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
       }
       std::cout << " " << std::endl;
     }
   }
 
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subsubfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement3" << std::endl;
   for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
     std::cout << type << " " << i << " connected to ";
     for (UInt j = 0; j < subel_to_el3.getNbComponent(); ++j){
       std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   for (UInt ft = 0; ft < types_facet.size(); ++ft) {
     ElementType type_facet = types_facet(ft);
     Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
 
     std::cout << "SubelementToElement2" << std::endl;
     for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
       std::cout << type_facet << " " << i << " connected to ";
       for (UInt j = 0; j < subel_to_el2.getNbComponent(); ++j){
 	std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
       }
       std::cout << " " << std::endl;
     }
   }
   
 
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < subel_to_el1.getNbComponent(); ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
index b11759516..36b8b0033 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_pentahedron_6.cc
@@ -1,148 +1,148 @@
 /**
  * @file   test_buildfacets_pentahedron_6.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Mon Sep 28 2015
  *
  * @brief  Test for cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 3;
   const ElementType type = _pentahedron_6;
 
   Mesh mesh(spatial_dimension);
   mesh.read("pentahedron_6.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   Vector<ElementType> types_facet = mesh.getAllFacetTypes(type);
   const ElementType type_subfacet = mesh.getFacetType(types_facet(0));
   const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   for (UInt ft = 0; ft < types_facet.size(); ++ft) {
     ElementType type_facet = types_facet(ft);
     Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
 
     std::cout << "ElementToSubelement3" << std::endl;
     for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
       std::cout << type_facet << " " << i << " connected to ";
       for (UInt j = 0; j < 2; ++j){
 	std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
       }
       std::cout << " " << std::endl;
     }
   }
 
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subsubfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement3" << std::endl;
   for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
     std::cout << type << " " << i << " connected to ";
     for (UInt j = 0; j < subel_to_el3.getNbComponent(); ++j){
       std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   for (UInt ft = 0; ft < types_facet.size(); ++ft) {
     ElementType type_facet = types_facet(ft);
     Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
 
     std::cout << "SubelementToElement2" << std::endl;
     for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
       std::cout << type_facet << " " << i << " connected to ";
       for (UInt j = 0; j < subel_to_el2.getNbComponent(); ++j){
 	std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
       }
       std::cout << " " << std::endl;
     }
   }
   
 
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < subel_to_el1.getNbComponent(); ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
index 52d73dd7b..c8c002fe8 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_4.cc
@@ -1,116 +1,116 @@
 /**
  * @file   test_buildfacets_quadrangle_4.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Fri Sep 18 2015
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with quadrangles
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 2;
   const ElementType type = _quadrangle_4;
 
   Mesh mesh(spatial_dimension);
   mesh.read("quadrangle_4.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   const ElementType type_facet = mesh.getFacetType(type);
   const ElementType type_subfacet = mesh.getFacetType(type_facet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
 
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
     std::cout << type << " " << i << " connected to ";
     for (UInt j = 0; j < 4; ++j){
       std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
index 0072e9aa5..513ac474d 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_quadrangle_8.cc
@@ -1,116 +1,116 @@
 /**
  * @file   test_buildfacets_quadrangle_8.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Fri Sep 18 2015
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with quadrangles
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 2;
   const ElementType type = _quadrangle_8;
 
   Mesh mesh(spatial_dimension);
   mesh.read("quadrangle_8.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   const ElementType type_facet = mesh.getFacetType(type);
   const ElementType type_subfacet = mesh.getFacetType(type_facet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
 
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
     std::cout << type << " " << i << " connected to ";
     for (UInt j = 0; j < 4; ++j){
       std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
index 70495db8b..8b9767f68 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_tetrahedron_10.cc
@@ -1,143 +1,143 @@
 /**
  * @file   test_buildfacets_tetrahedron_10.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Tue May 08 2012
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test for cohesive elements
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 3;
   const ElementType type = _tetrahedron_10;
 
   Mesh mesh(spatial_dimension);
   mesh.read("tetrahedron_10.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   // debug::setDebugLevel(dblDump);
   // std::cout << mesh << std::endl;
   // std::cout << mesh_facets << std::endl;
 
   const ElementType type_facet = mesh.getFacetType(type);
   const ElementType type_subfacet = mesh.getFacetType(type_facet);
   const ElementType type_subsubfacet = mesh.getFacetType(type_subfacet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel3 = mesh_facets.getElementToSubelement(type_facet);
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_subfacet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subsubfacet);
 
 
   std::cout << "ElementToSubelement3" << std::endl;
   for (UInt i = 0; i < el_to_subel3.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel3(i)[j].type << " " << el_to_subel3(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel2(i).size(); ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subsubfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el3 = mesh_facets.getSubelementToElement(type);
   const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type_facet);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_subfacet);
 
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement3" << std::endl;
   for (UInt i = 0; i < subel_to_el3.getSize(); ++i) {
     std::cout << type << " " << i << " connected to ";
     for (UInt j = 0; j < 4; ++j){
       std::cout << subel_to_el3(i, j).type << " " << subel_to_el3(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 3; ++j){
       std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
index 383648403..604241e37 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_3.cc
@@ -1,116 +1,116 @@
 /**
  * @file   test_buildfacets_triangle_3.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Fri Sep 18 2015
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with triangles
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 2;
   const ElementType type = _triangle_3;
 
   Mesh mesh(spatial_dimension);
   mesh.read("triangle_3.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   const ElementType type_facet = mesh.getFacetType(type);
   const ElementType type_subfacet = mesh.getFacetType(type_facet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
 
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
     std::cout << type << " " << i << " connected to ";
     for (UInt j = 0; j < 3; ++j){
       std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
index 5e0a5f12d..b28d0c719 100644
--- a/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
+++ b/test/test_mesh_utils/test_buildfacets/test_buildfacets_triangle_6.cc
@@ -1,116 +1,116 @@
 /**
  * @file   test_buildfacets_triangle_6.cc
  *
  * @author Mauro Corrado <mauro.corrado@epfl.ch>
  *
  * @date creation: Fri Sep 18 2015
  * @date last modification: Sat Sep 19 2015
  *
  * @brief  Test to check the building of the facets. Mesh with triangles
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 #include <fstream>
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_utils.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 2;
   const ElementType type = _triangle_6;
 
   Mesh mesh(spatial_dimension);
   mesh.read("triangle_6.msh");
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
 
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   const ElementType type_facet = mesh.getFacetType(type);
   const ElementType type_subfacet = mesh.getFacetType(type_facet);
 
   /* ------------------------------------------------------------------------ */
   /* Element to Subelement testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array< std::vector<Element> > & el_to_subel2 = mesh_facets.getElementToSubelement(type_facet);
   const Array< std::vector<Element> > & el_to_subel1 = mesh_facets.getElementToSubelement(type_subfacet);
 
 
   std::cout << "ElementToSubelement2" << std::endl;
   for (UInt i = 0; i < el_to_subel2.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << el_to_subel2(i)[j].type << " " << el_to_subel2(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "ElementToSubelement1" << std::endl;
   for (UInt i = 0; i < el_to_subel1.getSize(); ++i) {
     std::cout << type_subfacet << " " << i << " connected to ";
     for (UInt j = 0; j < el_to_subel1(i).size(); ++j){
       std::cout << el_to_subel1(i)[j].type << " " << el_to_subel1(i)[j].element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Subelement to Element testing                                            */
   /* ------------------------------------------------------------------------ */
 
   const Array<Element> & subel_to_el2 = mesh_facets.getSubelementToElement(type);
   const Array<Element> & subel_to_el1 = mesh_facets.getSubelementToElement(type_facet);
 
   std::cout << " " << std::endl;
   std::cout << "SubelementToElement2" << std::endl;
   for (UInt i = 0; i < subel_to_el2.getSize(); ++i) {
     std::cout << type << " " << i << " connected to ";
     for (UInt j = 0; j < 3; ++j){
       std::cout << subel_to_el2(i, j).type << " " << subel_to_el2(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
   std::cout << "SubelementToElement1" << std::endl;
   for (UInt i = 0; i < subel_to_el1.getSize(); ++i) {
     std::cout << type_facet << " " << i << " connected to ";
     for (UInt j = 0; j < 2; ++j){
       std::cout << subel_to_el1(i, j).type << " " << subel_to_el1(i, j).element << ", ";
     }
     std::cout << " " << std::endl;
   }
 
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt b/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt
index aea1a0789..01a5ad4b6 100644
--- a/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt
+++ b/test/test_mesh_utils/test_segment_nodetype/CMakeLists.txt
@@ -1,34 +1,34 @@
 #===============================================================================
 # @file   CMakeLists.txt
 #
 # @author Marco Vocialta <marco.vocialta@epfl.ch>
 #
 # @date creation: Fri Sep 18 2015
 #
 # @brief  CMakeLists for segment nodetype tests
 #
 # @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/>.
 #
 #===============================================================================
 
-register_test(test_segment_nodetype
-  SOURCES test_segment_nodetype.cc
-  FILES_TO_COPY mesh.msh
-  PACKAGE parallel
-  )
+# register_test(test_segment_nodetype
+#   SOURCES test_segment_nodetype.cc
+#   FILES_TO_COPY mesh.msh
+#   PACKAGE parallel
+#   )
diff --git a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
index 07cff2289..a3d7bb111 100644
--- a/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
+++ b/test/test_mesh_utils/test_segment_nodetype/test_segment_nodetype.cc
@@ -1,97 +1,97 @@
 /**
  * @file   test_segment_nodetype.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Sep 18 2015
  *
  * @brief  Test to verify that the node type is correctly associated to
  * the segments in parallel
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "element_synchronizer.hh"
 #include "mesh_utils.hh"
 
 /* -------------------------------------------------------------------------- */
 using namespace akantu;
 
 int main(int argc, char * argv[]) {
   initialize(argc, argv);
 
   UInt spatial_dimension = 3;
   Mesh mesh(spatial_dimension);
 
   StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   // partition the mesh
   if (prank == 0) {
     mesh.read("mesh.msh");
   }
 
   mesh.distribute();
 
   // compute the node types for each segment
-  Mesh mesh_facets(mesh.initMeshFacets());
+  Mesh & mesh_facets = mesh.initMeshFacets();
   MeshUtils::buildSegmentToNodeType(mesh, mesh_facets);
 
   // verify that the number of segments per node type makes sense
   std::map<Int, UInt> nb_facets_per_nodetype;
   UInt nb_segments = 0;
 
   for (auto ghost_type : ghost_types) {
     const Array<Int> & segment_to_nodetype =
         mesh_facets.getData<Int>("segment_to_nodetype", _segment_2, ghost_type);
 
     // count the number of segments per node type
     for (auto & stn : segment_to_nodetype) {
       if (nb_facets_per_nodetype.find(stn) == nb_facets_per_nodetype.end())
         nb_facets_per_nodetype[stn] = 1;
       else
         ++nb_facets_per_nodetype[stn];
     }
     nb_segments += segment_to_nodetype.getSize();
   }
 
   // checking the solution
   if (nb_segments != 24)
     AKANTU_DEBUG_ERROR("The number of segments is wrong");
 
   if (prank == 0) {
     if (nb_facets_per_nodetype[-1] != 3 || nb_facets_per_nodetype[-2] != 9 ||
         nb_facets_per_nodetype[-3] != 12)
       AKANTU_DEBUG_ERROR(
           "The segments of processor 0 have the wrong node type");
 
     if (nb_facets_per_nodetype.size() > 3)
       AKANTU_DEBUG_ERROR("Processor 0 cannot have any slave segment");
   }
 
   if (prank == psize - 1 &&
       nb_facets_per_nodetype.find(-2) != nb_facets_per_nodetype.end())
     AKANTU_DEBUG_ERROR("The last processor must not have any master facets");
 
   finalize();
   return 0;
 }
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit.cc b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit.cc
index 1e199d191..8641b1041 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit.cc
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit.cc
@@ -1,313 +1,312 @@
 /**
  * @file   patch_test_explicit.cc
  *
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Sat Apr 16 2011
  * @date last modification: Thu Oct 15 2015
  *
  * @brief  patch test for elastic material in solid mechanics model
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You 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 <fstream>
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 Real alpha[3][4] = {{0.01, 0.02, 0.03, 0.04},
                     {0.05, 0.06, 0.07, 0.08},
                     {0.09, 0.10, 0.11, 0.12}};
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, bool plane_strain>
 static Matrix<Real> prescribed_strain() {
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
   Matrix<Real> strain(spatial_dimension, spatial_dimension);
 
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       strain(i, j) = alpha[i][j + 1];
     }
   }
   return strain;
 }
 
 template <ElementType type, bool is_plane_strain>
 static Matrix<Real> prescribed_stress() {
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
   Matrix<Real> stress(spatial_dimension, spatial_dimension);
 
   // plane strain in 2d
   Matrix<Real> strain(spatial_dimension, spatial_dimension);
   Matrix<Real> pstrain;
   pstrain = prescribed_strain<type, is_plane_strain>();
   Real nu = 0.3;
   Real E = 2.1e11;
   Real trace = 0;
 
   /// symetric part of the strain tensor
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j)
       strain(i, j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     trace += strain(i, i);
 
   if (spatial_dimension == 1) {
     stress(0, 0) = E * strain(0, 0);
   } else {
     if (is_plane_strain) {
       Real Ep = E / (1 + nu);
       for (UInt i = 0; i < spatial_dimension; ++i)
         for (UInt j = 0; j < spatial_dimension; ++j) {
           stress(i, j) = Ep * strain(i, j);
           if (i == j)
             stress(i, j) += Ep * (nu / (1 - 2 * nu)) * trace;
         }
     } else {
       Real Ep = E / (1 + nu);
       for (UInt i = 0; i < spatial_dimension; ++i)
         for (UInt j = 0; j < spatial_dimension; ++j) {
           stress(i, j) = Ep * strain(i, j);
           if (i == j)
             stress(i, j) += (nu * E) / (1 - (nu * nu)) * trace;
         }
     }
   }
 
   return stress;
 }
 
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
   std::string input_file;
   if (PLANE_STRAIN)
     input_file = "material_check_stress_plane_strain.dat";
   else
     input_file = "material_check_stress_plane_stress.dat";
 
   initialize(input_file, argc, argv);
 
   debug::setDebugLevel(dblWarning);
   UInt dim = ElementClass<TYPE>::getSpatialDimension();
   const ElementType element_type = TYPE;
 
   UInt damping_steps = 600000;
   UInt damping_interval = 50;
   Real damping_ratio = 0.99;
 
   UInt additional_steps = 20000;
   UInt max_steps = damping_steps + additional_steps;
 
   /// load mesh
   Mesh my_mesh(dim);
 
   std::stringstream filename;
   filename << TYPE << ".msh";
   my_mesh.read(filename.str());
 
   UInt nb_nodes = my_mesh.getNbNodes();
 
   /// declaration of model
   SolidMechanicsModel my_model(my_mesh);
   /// model initialization
   my_model.initFull();
 
   std::cout << my_model.getMaterial(0) << std::endl;
   Real time_step = my_model.getStableTimeStep() / 100.;
   my_model.setTimeStep(time_step);
   my_model.assembleMassLumped();
 
   std::cout << "The number of time steps is: " << max_steps << " (" << time_step
             << "s)" << std::endl;
 
   // boundary conditions
   const Array<Real> & coordinates = my_mesh.getNodes();
   Array<Real> & displacement = my_model.getDisplacement();
   Array<bool> & boundary = my_model.getBlockedDOFs();
 
   MeshUtils::buildFacets(my_mesh);
 
   my_mesh.createBoundaryGroupFromGeometry();
 
   // Loop over (Sub)Boundar(ies) to block the nodes
   for (GroupManager::const_element_group_iterator it(
            my_mesh.element_group_begin());
        it != my_mesh.element_group_end(); ++it)
-    for (ElementGroup::const_node_iterator nodes_it(it->second->node_begin());
-         nodes_it != it->second->node_end(); ++nodes_it)
+    for (const auto & node : it->second->getNodeGroup())
       for (UInt i = 0; i < dim; ++i)
-        boundary(*nodes_it, i) = true;
+        boundary(node, i) = true;
 
   // set the position of all nodes to the static solution
   for (UInt n = 0; n < nb_nodes; ++n) {
     for (UInt i = 0; i < dim; ++i) {
       displacement(n, i) = alpha[i][0];
       for (UInt j = 0; j < dim; ++j) {
         displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
       }
     }
   }
 
   Array<Real> & velocity = my_model.getVelocity();
 
   std::ofstream energy;
   std::stringstream energy_filename;
   energy_filename << "energy_" << TYPE << ".csv";
   energy.open(energy_filename.str().c_str());
   energy << "id,time,ekin" << std::endl;
   Real ekin_mean = 0.;
 
 //#define DEBUG_TEST
 #ifdef DEBUG_TEST
   my_model.solveStep();
   my_model.addDumpField("strain");
   my_model.addDumpField("stress");
   my_model.addDumpField("external_force");
   my_model.addDumpField("internal_force");
   my_model.addDumpField("velocity");
   my_model.addDumpField("acceleration");
   my_model.addDumpField("displacement");
   my_model.dump();
 #endif
   /* ------------------------------------------------------------------------ */
   /* Main loop                                                                */
   /* ------------------------------------------------------------------------ */
   UInt s;
   for (s = 1; s <= max_steps; ++s) {
     if (s % 10000 == 0)
       std::cout << "passing step " << s << "/" << max_steps << " ("
                 << s * time_step << "s)" << std::endl;
 
     // damp velocity in order to find equilibrium
     if ((s < damping_steps) && (s % damping_interval == 0)) {
       velocity *= damping_ratio;
     }
 
     if (s % 1000 == 0) {
       ekin_mean = ekin_mean / 1000.;
       std::cout << "Ekin mean = " << ekin_mean << std::endl;
       if (ekin_mean < 1e-10)
         break;
       ekin_mean = 0.;
     }
 
     my_model.solveStep();
 
     akantu::Real ekin = my_model.getEnergy("kinetic");
     ekin_mean += ekin;
 
     if (s % 1000 == 0)
       energy << s << "," << s * time_step << "," << ekin << std::endl;
   }
 
   energy.close();
 
   UInt nb_quadrature_points =
       my_model.getFEEngine().getNbIntegrationPoints(TYPE);
   Array<Real> & stress_vect = const_cast<Array<Real> &>(
       my_model.getMaterial(0).getStress(element_type));
   Array<Real> & strain_vect =
       const_cast<Array<Real> &>(my_model.getMaterial(0).getGradU(element_type));
 
   Array<Real>::matrix_iterator stress_it = stress_vect.begin(dim, dim);
   Array<Real>::matrix_iterator strain_it = strain_vect.begin(dim, dim);
 
   Matrix<Real> presc_stress;
   presc_stress = prescribed_stress<TYPE, PLANE_STRAIN>();
   Matrix<Real> presc_strain;
   presc_strain = prescribed_strain<TYPE, PLANE_STRAIN>();
 
   UInt nb_element = my_mesh.getNbElement(TYPE);
 
   Real strain_tolerance = 1e-13;
   Real stress_tolerance = 1e-13;
 
   for (UInt el = 0; el < nb_element; ++el) {
     for (UInt q = 0; q < nb_quadrature_points; ++q) {
       Matrix<Real> & stress = *stress_it;
       Matrix<Real> & strain = *strain_it;
 
       Matrix<Real> diff(dim, dim);
 
       diff = strain;
       diff -= presc_strain;
       Real strain_error = diff.norm<L_inf>() / strain.norm<L_inf>();
 
       if (strain_error > strain_tolerance) {
         std::cerr << "strain error: " << strain_error << " > "
                   << strain_tolerance << std::endl;
         std::cerr << "strain: " << strain << std::endl
                   << "prescribed strain: " << presc_strain << std::endl;
         return EXIT_FAILURE;
       } else {
         std::cerr << "strain error: " << strain_error << " < "
                   << strain_tolerance << std::endl;
       }
 
       diff = stress;
       diff -= presc_stress;
       Real stress_error = diff.norm<L_inf>() / stress.norm<L_inf>();
 
       if (stress_error > stress_tolerance) {
         std::cerr << "stress error: " << stress_error << " > "
                   << stress_tolerance << std::endl;
         std::cerr << "stress: " << stress << std::endl
                   << "prescribed stress: " << presc_stress << std::endl;
         return EXIT_FAILURE;
       } else {
         std::cerr << "stress error: " << stress_error << " < "
                   << stress_tolerance << std::endl;
       }
 
       ++stress_it;
       ++strain_it;
     }
   }
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     for (UInt i = 0; i < dim; ++i) {
       Real disp = alpha[i][0];
       for (UInt j = 0; j < dim; ++j) {
         disp += alpha[i][j + 1] * coordinates(n, j);
       }
 
       if (!(std::abs(displacement(n, i) - disp) < 1e-7)) {
         std::cerr << "displacement(" << n << ", " << i
                   << ")=" << displacement(n, i) << " should be equal to "
                   << disp << "(" << displacement(n, i) - disp << ")"
                   << std::endl;
         return EXIT_FAILURE;
       }
     }
   }
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit_anisotropic.cc b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit_anisotropic.cc
index fde87d4e0..e3d06c526 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit_anisotropic.cc
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/explicit/patch_test_explicit_anisotropic.cc
@@ -1,314 +1,312 @@
 /**
  * @file   patch_test_explicit_anisotropic.cc
  *
  * @author Till Junge <till.junge@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Cyprien Wolff <cyprien.wolff@epfl.ch>
  *
  * @date creation: Sat Apr 16 2011
  * @date last modification: Thu Oct 15 2015
  *
  * @brief  patch test for elastic material in solid mechanics model
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You 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 <fstream>
 /* -------------------------------------------------------------------------- */
 
 
 using namespace akantu;
 
 Real alpha[3][4] = {{0.01, 0.02, 0.03, 0.04},
                     {0.05, 0.06, 0.07, 0.08},
                     {0.09, 0.10, 0.11, 0.12}};
 
 // Stiffness tensor, rotated by hand
 Real C[3][3][3][3] = {
     {{{112.93753505, 1.85842452538e-10, -4.47654358027e-10},
       {1.85847317471e-10, 54.2334345331, -3.69840984824},
       {-4.4764768395e-10, -3.69840984824, 56.848605217}},
      {{1.85847781609e-10, 25.429294233, -3.69840984816},
       {25.429294233, 3.31613847493e-10, -8.38797920011e-11},
       {-3.69840984816, -8.38804581349e-11, -1.97875715813e-10}},
      {{-4.47654358027e-10, -3.69840984816, 28.044464917},
       {-3.69840984816, 2.09374961813e-10, 9.4857455224e-12},
       {28.044464917, 9.48308098714e-12, -2.1367885239e-10}}},
     {{{1.85847781609e-10, 25.429294233, -3.69840984816},
       {25.429294233, 3.31613847493e-10, -8.38793479119e-11},
       {-3.69840984816, -8.38795699565e-11, -1.97876381947e-10}},
      {{54.2334345331, 3.31617400207e-10, 2.09372075233e-10},
       {3.3161562385e-10, 115.552705733, -3.15093728886e-10},
       {2.09372075233e-10, -3.15090176173e-10, 54.2334345333}},
      {{-3.69840984824, -8.38795699565e-11, 9.48219280872e-12},
       {-8.38795699565e-11, -3.1509195253e-10, 25.4292942335},
       {9.48441325477e-12, 25.4292942335, 3.69840984851}}},
     {{{-4.47653469848e-10, -3.69840984816, 28.044464917},
       {-3.69840984816, 2.09374073634e-10, 9.48752187924e-12},
       {28.044464917, 9.48552347779e-12, -2.1367885239e-10}},
      {{-3.69840984824, -8.3884899027e-11, 9.48219280872e-12},
       {-8.3884899027e-11, -3.150972816e-10, 25.4292942335},
       {9.48041645188e-12, 25.4292942335, 3.69840984851}},
      {{56.848605217, -1.97875493768e-10, -2.13681516925e-10},
       {-1.97877270125e-10, 54.2334345333, 3.69840984851},
       {-2.13683293282e-10, 3.69840984851, 112.93753505}}}};
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type> static Matrix<Real> prescribed_grad_u() {
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
   Matrix<Real> grad_u(spatial_dimension, spatial_dimension);
 
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       grad_u(i, j) = alpha[i][j + 1];
     }
   }
   return grad_u;
 }
 
 template <ElementType type> static Matrix<Real> prescribed_stress() {
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
   Matrix<Real> stress(spatial_dimension, spatial_dimension);
 
   // plane strain in 2d
   Matrix<Real> strain(spatial_dimension, spatial_dimension);
   Matrix<Real> pstrain;
   pstrain = prescribed_grad_u<type>();
   Real trace = 0;
 
   /// symetric part of the strain tensor
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j)
       strain(i, j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     trace += strain(i, i);
 
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       stress(i, j) = 0;
       for (UInt k = 0; k < spatial_dimension; ++k) {
         for (UInt l = 0; l < spatial_dimension; ++l) {
           stress(i, j) += C[i][j][k][l] * strain(k, l);
         }
       }
     }
   }
   return stress;
 }
 
 #define TYPE _tetrahedron_4
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
   initialize("material_anisotropic.dat", argc, argv);
 
   UInt dim = ElementClass<TYPE>::getSpatialDimension();
   const ElementType element_type = TYPE;
 
   UInt damping_steps = 600000;
   UInt damping_interval = 50;
   Real damping_ratio = 0.99;
 
   UInt additional_steps = 20000;
   UInt max_steps = damping_steps + additional_steps;
 
   /// load mesh
   Mesh my_mesh(dim);
 
   std::stringstream filename;
   filename << TYPE << ".msh";
   my_mesh.read(filename.str());
 
   UInt nb_nodes = my_mesh.getNbNodes();
 
   /// declaration of model
   SolidMechanicsModel model(my_mesh);
   /// model initialization
   model.initFull();
 
   std::cout << model.getMaterial(0) << std::endl;
   Real time_step = model.getStableTimeStep() / 5.;
   model.setTimeStep(time_step);
 
   std::cout << "The number of time steps is: " << max_steps << " (" << time_step
             << "s)" << std::endl;
 
   // boundary conditions
   const Array<Real> & coordinates = my_mesh.getNodes();
   Array<Real> & displacement = model.getDisplacement();
   Array<bool> & boundary = model.getBlockedDOFs();
 
   MeshUtils::buildFacets(my_mesh);
 
   my_mesh.createBoundaryGroupFromGeometry();
 
   // Loop over (Sub)Boundar(ies)
   // Loop over (Sub)Boundar(ies)
   for (GroupManager::const_element_group_iterator it(
            my_mesh.element_group_begin());
        it != my_mesh.element_group_end(); ++it) {
-    for (ElementGroup::const_node_iterator nodes_it(it->second->node_begin());
-         nodes_it != it->second->node_end(); ++nodes_it) {
-      UInt n(*nodes_it);
-      std::cout << "Node " << *nodes_it << std::endl;
+    for (const auto & n : it->second->getNodeGroup()) {
+      std::cout << "Node " << n << std::endl;
       for (UInt i = 0; i < dim; ++i) {
         displacement(n, i) = alpha[i][0];
         for (UInt j = 0; j < dim; ++j) {
           displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
         }
         boundary(n, i) = true;
       }
     }
   }
 
   // Actually, loop over all nodes, since I wanna test a static solution
   for (UInt n = 0; n < nb_nodes; ++n) {
     for (UInt i = 0; i < dim; ++i) {
       displacement(n, i) = alpha[i][0];
       for (UInt j = 0; j < dim; ++j) {
         displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
       }
     }
   }
 
   Array<Real> & velocity = model.getVelocity();
 
   std::ofstream energy;
   std::stringstream energy_filename;
   energy_filename << "energy_" << TYPE << ".csv";
   energy.open(energy_filename.str().c_str());
   energy << "id,time,ekin" << std::endl;
   Real ekin_mean = 0.;
 
   /* ------------------------------------------------------------------------ */
   /* Main loop                                                                */
   /* ------------------------------------------------------------------------ */
   UInt s;
   for (s = 1; s <= max_steps; ++s) {
     if (s % 10000 == 0)
       std::cout << "passing step " << s << "/" << max_steps << " ("
                 << s * time_step << "s)" << std::endl;
 
     // damp velocity in order to find equilibrium
     if ((s < damping_steps) && (s % damping_interval == 0)) {
       velocity *= damping_ratio;
     }
 
     if (s % 1000 == 0) {
       ekin_mean = ekin_mean / 1000.;
       std::cout << "Ekin mean = " << ekin_mean << std::endl;
       if (ekin_mean < 1e-10)
         break;
       ekin_mean = 0.;
     }
 
     model.solveStep();
 
     Real ekin = model.getEnergy("kinetic");
     ekin_mean += ekin;
 
     if (s % 1000 == 0)
       energy << s << "," << s * time_step << "," << ekin << std::endl;
   }
 
   energy.close();
 
   UInt nb_quadrature_points = model.getFEEngine().getNbIntegrationPoints(TYPE);
   Array<Real> & stress_vect =
       const_cast<Array<Real> &>(model.getMaterial(0).getStress(element_type));
   Array<Real> & gradu_vect =
       const_cast<Array<Real> &>(model.getMaterial(0).getGradU(element_type));
 
   Array<Real>::iterator<Matrix<Real>> stress_it = stress_vect.begin(dim, dim);
   Array<Real>::iterator<Matrix<Real>> gradu_it = gradu_vect.begin(dim, dim);
 
   Matrix<Real> presc_stress;
   presc_stress = prescribed_stress<TYPE>();
   Matrix<Real> presc_gradu;
   presc_gradu = prescribed_grad_u<TYPE>();
 
   UInt nb_element = my_mesh.getNbElement(TYPE);
 
   Real gradu_tolerance = 1e-9;
   Real stress_tolerance = 1e-2;
   if (s > max_steps) {
     stress_tolerance = 1e-4;
     gradu_tolerance = 1e-7;
   }
 
   for (UInt el = 0; el < nb_element; ++el) {
     for (UInt q = 0; q < nb_quadrature_points; ++q) {
       Matrix<Real> & stress = *stress_it;
       Matrix<Real> & gradu = *gradu_it;
 
       for (UInt i = 0; i < dim; ++i) {
         for (UInt j = 0; j < dim; ++j) {
           if (!(std::abs(gradu(i, j) - presc_gradu(i, j)) < gradu_tolerance)) {
             std::cerr << "gradu[" << i << "," << j << "] = " << gradu(i, j)
                       << " but should be = " << presc_gradu(i, j) << " (-"
                       << std::abs(gradu(i, j) - presc_gradu(i, j))
                       << ") [el : " << el << " - q : " << q << "]" << std::endl;
             std::cerr << gradu << presc_gradu << std::endl;
             return EXIT_FAILURE;
           }
 
           if (!(std::abs(stress(i, j) - presc_stress(i, j)) <
                 stress_tolerance)) {
             std::cerr << "stress[" << i << "," << j << "] = " << stress(i, j)
                       << " but should be = " << presc_stress(i, j) << " (-"
                       << std::abs(stress(i, j) - presc_stress(i, j))
                       << ") [el : " << el << " - q : " << q << "]" << std::endl;
             std::cerr << stress << presc_stress << std::endl;
             return EXIT_FAILURE;
           }
         }
       }
 
       ++stress_it;
       ++gradu_it;
     }
   }
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     for (UInt i = 0; i < dim; ++i) {
       Real disp = alpha[i][0];
       for (UInt j = 0; j < dim; ++j) {
         disp += alpha[i][j + 1] * coordinates(n, j);
       }
 
       if (!(std::abs(displacement(n, i) - disp) < 1e-7)) {
         std::cerr << "displacement(" << n << ", " << i
                   << ")=" << displacement(n, i) << " should be equal to "
                   << disp << "(" << displacement(n, i) - disp << ")"
                   << std::endl;
         return EXIT_FAILURE;
       }
     }
   }
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc b/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc
index 173cf03b1..499f183db 100644
--- a/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc
+++ b/test/test_model/test_solid_mechanics_model/patch_tests/implicit/patch_test_implicit.cc
@@ -1,249 +1,247 @@
 /**
  * @file   patch_test_implicit.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sat Apr 16 2011
  * @date last modification: Thu Oct 15 2015
  *
  * @brief  patch test for elastic material in solid mechanics model
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "non_linear_solver.hh"
 #include "solid_mechanics_model.hh"
 #include "sparse_matrix.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 Real alpha[3][4] = {{0.01, 0.02, 0.03, 0.04},
                     {0.05, 0.06, 0.07, 0.08},
                     {0.09, 0.10, 0.11, 0.12}};
 
 /* -------------------------------------------------------------------------- */
 template <ElementType type, bool is_plane_strain>
 static Matrix<Real> prescribed_strain() {
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
   Matrix<Real> strain(spatial_dimension, spatial_dimension);
 
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       strain(i, j) = alpha[i][j + 1];
     }
   }
   return strain;
 }
 
 template <ElementType type, bool is_plane_strain>
 static Matrix<Real> prescribed_stress() {
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
   Matrix<Real> stress(spatial_dimension, spatial_dimension);
 
   // plane strain in 2d
   Matrix<Real> strain(spatial_dimension, spatial_dimension);
   Matrix<Real> pstrain;
   pstrain = prescribed_strain<type, is_plane_strain>();
   Real nu = 0.3;
   Real E = 2.1e11;
   Real trace = 0;
 
   /// symetric part of the strain tensor
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j)
       strain(i, j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
 
   for (UInt i = 0; i < spatial_dimension; ++i)
     trace += strain(i, i);
 
   Real lambda = nu * E / ((1 + nu) * (1 - 2 * nu));
   Real mu = E / (2 * (1 + nu));
 
   if (!is_plane_strain) {
     std::cout << "toto" << std::endl;
     lambda = nu * E / (1 - nu * nu);
   }
 
   if (spatial_dimension == 1) {
     stress(0, 0) = E * strain(0, 0);
   } else {
     for (UInt i = 0; i < spatial_dimension; ++i)
       for (UInt j = 0; j < spatial_dimension; ++j) {
         stress(i, j) = (i == j) * lambda * trace + 2 * mu * strain(i, j);
       }
   }
 
   return stress;
 }
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 int main(int argc, char * argv[]) {
   std::string input_file;
   if (PLANE_STRAIN)
     input_file = "material_check_stress_plane_strain.dat";
   else
     input_file = "material_check_stress_plane_stress.dat";
 
   initialize(input_file, argc, argv);
 
   UInt dim = ElementClass<TYPE>::getSpatialDimension();
   const ElementType element_type = TYPE;
 
   /// load mesh
   Mesh mesh(dim);
 
   std::stringstream filename;
   filename << TYPE << ".msh";
   mesh.read(filename.str());
 
   UInt nb_nodes = mesh.getNbNodes();
 
   /// declaration of model
   SolidMechanicsModel model(mesh);
   /// model initialization
   model.initFull(_analysis_method = _static);
 
   const Array<Real> & coordinates = mesh.getNodes();
   Array<Real> & displacement = model.getDisplacement();
   Array<bool> & boundary = model.getBlockedDOFs();
   MeshUtils::buildFacets(mesh);
 
   mesh.createBoundaryGroupFromGeometry();
 
   // Loop over (Sub)Boundar(ies)
   for (GroupManager::const_element_group_iterator it(
            mesh.element_group_begin());
        it != mesh.element_group_end(); ++it) {
-    for (ElementGroup::const_node_iterator nodes_it(it->second->node_begin());
-         nodes_it != it->second->node_end(); ++nodes_it) {
-      UInt n(*nodes_it);
-      std::cout << "Node " << *nodes_it << std::endl;
+    for (const auto & n : it->second->getNodeGroup()) {
+      std::cout << "Node " << n << std::endl;
       for (UInt i = 0; i < dim; ++i) {
         displacement(n, i) = alpha[i][0];
         for (UInt j = 0; j < dim; ++j) {
           displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
         }
         boundary(n, i) = true;
       }
     }
   }
 
   /* ------------------------------------------------------------------------ */
   /* Static solve                                                             */
   /* ------------------------------------------------------------------------ */
   auto & solver = model.getNonLinearSolver();
   solver.set("max_iterations", 2);
   solver.set("threshold", 2e-4);
   solver.set("convergence_type", _scc_residual);
 
   model.solveStep();
   model.getDOFManager().getMatrix("K").saveMatrix("clown_matrix.mtx");
 
   /* ------------------------------------------------------------------------ */
   /* Checks                                                                   */
   /* ------------------------------------------------------------------------ */
   UInt nb_quadrature_points =
       model.getFEEngine().getNbIntegrationPoints(element_type);
 
   Array<Real> & stress_vect =
       const_cast<Array<Real> &>(model.getMaterial(0).getStress(element_type));
   Array<Real> & strain_vect =
       const_cast<Array<Real> &>(model.getMaterial(0).getGradU(element_type));
 
   Array<Real>::matrix_iterator stress_it = stress_vect.begin(dim, dim);
   Array<Real>::matrix_iterator strain_it = strain_vect.begin(dim, dim);
 
   Matrix<Real> presc_stress;
   presc_stress = prescribed_stress<TYPE, PLANE_STRAIN>();
   Matrix<Real> presc_strain;
   presc_strain = prescribed_strain<TYPE, PLANE_STRAIN>();
 
   UInt nb_element = mesh.getNbElement(TYPE);
 
   Real strain_tolerance = 1e-13;
   Real stress_tolerance = 1e-13;
 
   for (UInt el = 0; el < nb_element; ++el) {
     for (UInt q = 0; q < nb_quadrature_points; ++q) {
       Matrix<Real> & stress = *stress_it;
       Matrix<Real> & strain = *strain_it;
 
       Matrix<Real> diff(dim, dim);
 
       diff = strain;
       diff -= presc_strain;
       Real strain_error = diff.norm<L_inf>() / strain.norm<L_inf>();
 
       if (strain_error > strain_tolerance) {
         std::cerr << "strain error: " << strain_error << " > "
                   << strain_tolerance << std::endl;
         std::cerr << "strain: " << strain << std::endl
                   << "prescribed strain: " << presc_strain << std::endl;
         return EXIT_FAILURE;
       } else {
         std::cerr << "strain error: " << strain_error << " < "
                   << strain_tolerance << std::endl;
       }
 
       diff = stress;
       diff -= presc_stress;
       Real stress_error = diff.norm<L_inf>() / stress.norm<L_inf>();
 
       if (stress_error > stress_tolerance) {
         std::cerr << "stress error: " << stress_error << " > "
                   << stress_tolerance << std::endl;
         std::cerr << "stress: " << stress << std::endl
                   << "prescribed stress: " << presc_stress << std::endl;
         return EXIT_FAILURE;
       } else {
         std::cerr << "stress error: " << stress_error << " < "
                   << stress_tolerance << std::endl;
       }
 
       ++stress_it;
       ++strain_it;
     }
   }
 
   for (UInt n = 0; n < nb_nodes; ++n) {
     for (UInt i = 0; i < dim; ++i) {
       Real disp = alpha[i][0];
       for (UInt j = 0; j < dim; ++j) {
         disp += alpha[i][j + 1] * coordinates(n, j);
       }
 
       if (!(std::abs(displacement(n, i) - disp) < 2e-15)) {
         std::cerr << "displacement(" << n << ", " << i
                   << ")=" << displacement(n, i) << " should be equal to "
                   << disp << std::endl;
         return EXIT_FAILURE;
       }
     }
   }
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc
index 345c7de54..f8755cf90 100644
--- a/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc
+++ b/test/test_model/test_solid_mechanics_model/test_cohesive/test_cohesive_1d_element/test_cohesive_1d_element.cc
@@ -1,122 +1,121 @@
 /**
  * @file   test_cohesive_1d_element.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 14 2013
  * @date last modification: Sun Oct 19 2014
  *
  * @brief  Test for 1D cohesive elements
  *
  * @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 "solid_mechanics_model_cohesive.hh"
 
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char * argv[]) {
   initialize("material.dat", argc, argv);
 
   const UInt max_steps = 2000;
   const Real strain_rate = 4;
 
   UInt spatial_dimension = 1;
   Mesh mesh(spatial_dimension, "mesh");
   mesh.read("bar.msh");
 
   SolidMechanicsModelCohesive model(mesh);
   model.initFull(
       SolidMechanicsModelCohesiveOptions(_explicit_lumped_mass, true));
 
   Real time_step = model.getStableTimeStep() * 0.01;
   model.setTimeStep(time_step);
   std::cout << "Time step: " << time_step << std::endl;
 
   model.assembleMassLumped();
 
-  mesh.computeBoundingBox();
   Real posx_max = mesh.getUpperBounds()(0);
   Real posx_min = mesh.getLowerBounds()(0);
 
   /// initial conditions
   Array<Real> & velocity = model.getVelocity();
   const Array<Real> & position = mesh.getNodes();
   UInt nb_nodes = mesh.getNbNodes();
 
   for (UInt n = 0; n < nb_nodes; ++n)
     velocity(n) = strain_rate * (position(n) - (posx_max + posx_min) / 2.);
 
   /// boundary conditions
   Array<bool> & boundary = model.getBlockedDOFs();
   Array<Real> & displacement = model.getDisplacement();
   Real disp_increment = strain_rate * (posx_max - posx_min) / 2. * time_step;
 
   for (UInt node = 0; node < mesh.getNbNodes(); ++node) {
     if (Math::are_float_equal(position(node), posx_min)) { // left side
       boundary(node) = true;
     }
     if (Math::are_float_equal(position(node), posx_max)) { // right side
       boundary(node) = true;
     }
   }
 
   model.synchronizeBoundaries();
   model.assembleInternalForces();
 
   for (UInt s = 1; s <= max_steps; ++s) {
 
     model.checkCohesiveStress();
     model.solveStep();
 
     UInt nb_cohesive_elements = mesh.getNbElement(_cohesive_1d_2);
 
     if (s % 10 == 0) {
       std::cout << "passing step " << s << "/" << max_steps
                 << ", number of cohesive elemets:" << nb_cohesive_elements
                 << std::endl;
     }
 
     /// update external work and boundary conditions
     for (UInt n = 0; n < mesh.getNbNodes(); ++n) {
       if (Math::are_float_equal(position(n), posx_min)) // left side
         displacement(n) -= disp_increment;
 
       if (Math::are_float_equal(position(n), posx_max)) // right side
         displacement(n) += disp_increment;
     }
   }
 
   Real Ed = model.getEnergy("dissipated");
   Real Edt = 100 * 3;
 
   std::cout << Ed << std::endl;
   if (Ed < Edt * 0.999 || Ed > Edt * 1.001 || std::isnan(Ed)) {
     std::cout << "The dissipated energy is incorrect" << std::endl;
     finalize();
     return EXIT_FAILURE;
   }
 
   finalize();
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc
index 9fab6b8ca..952d1bb85 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_interpolate_stress.cc
@@ -1,181 +1,181 @@
 /**
  * @file   test_interpolate_stress.cc
  *
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Thu Jun 07 2012
  * @date last modification: Thu Oct 15 2015
  *
  * @brief  Test for the stress interpolation function
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #include <fstream>
 #include <iostream>
 #include <limits>
 
 /* -------------------------------------------------------------------------- */
 #include "solid_mechanics_model.hh"
 
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 Real function(Real x, Real y, Real z) { return 100. + 2. * x + 3. * y + 4 * z; }
 
 int main(int argc, char * argv[]) {
   initialize("../material.dat", argc, argv);
 
   debug::setDebugLevel(dblWarning);
 
   const UInt spatial_dimension = 3;
   const ElementType type = _tetrahedron_10;
 
   Mesh mesh(spatial_dimension);
   mesh.read("interpolation.msh");
   const ElementType type_facet = mesh.getFacetType(type);
 
-  Mesh mesh_facets(mesh.initMeshFacets("mesh_facets"));
+  Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets");
   MeshUtils::buildAllFacets(mesh, mesh_facets);
 
   SolidMechanicsModel model(mesh);
 
   /// model initialization
   model.initFull();
 
   Array<Real> & position = mesh.getNodes();
   UInt nb_facet = mesh_facets.getNbElement(type_facet);
   UInt nb_element = mesh.getNbElement(type);
 
   /// compute quadrature points positions on facets
   typedef FEEngineTemplate<IntegratorGauss, ShapeLagrange> MyFEEngineType;
 
   model.registerFEEngineObject<MyFEEngineType>("FacetsFEEngine", mesh_facets,
                                                spatial_dimension - 1);
   model.getFEEngine("FacetsFEEngine").initShapeFunctions();
 
   UInt nb_quad_per_facet =
       model.getFEEngine("FacetsFEEngine").getNbIntegrationPoints(type_facet);
   UInt nb_tot_quad = nb_quad_per_facet * nb_facet;
 
   Array<Real> quad_facets(nb_tot_quad, spatial_dimension);
 
   model.getFEEngine("FacetsFEEngine")
       .interpolateOnIntegrationPoints(position, quad_facets, spatial_dimension,
                                       type_facet);
 
   Array<Element> & facet_to_element = mesh_facets.getSubelementToElement(type);
   UInt nb_facet_per_elem = facet_to_element.getNbComponent();
 
   ElementTypeMapArray<Real> element_quad_facet;
   element_quad_facet.alloc(nb_element * nb_facet_per_elem * nb_quad_per_facet,
                            spatial_dimension, type);
 
   ElementTypeMapArray<Real> interpolated_stress("interpolated_stress", "");
   interpolated_stress.initialize(
       mesh, _nb_component = spatial_dimension * spatial_dimension,
       _spatial_dimension = spatial_dimension);
 
   Array<Real> & interp_stress = interpolated_stress(type);
   interp_stress.resize(nb_element * nb_facet_per_elem * nb_quad_per_facet);
 
   Array<Real> & el_q_facet = element_quad_facet(type);
 
   for (UInt el = 0; el < nb_element; ++el) {
     for (UInt f = 0; f < nb_facet_per_elem; ++f) {
       UInt global_facet = facet_to_element(el, f).element;
 
       for (UInt q = 0; q < nb_quad_per_facet; ++q) {
         for (UInt s = 0; s < spatial_dimension; ++s) {
           el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
                          f * nb_quad_per_facet + q,
                      s) = quad_facets(global_facet * nb_quad_per_facet + q, s);
         }
       }
     }
   }
 
   /// compute quadrature points position of the elements
   UInt nb_quad_per_element = model.getFEEngine().getNbIntegrationPoints(type);
   UInt nb_tot_quad_el = nb_quad_per_element * nb_element;
 
   Array<Real> quad_elements(nb_tot_quad_el, spatial_dimension);
 
   model.getFEEngine().interpolateOnIntegrationPoints(position, quad_elements,
                                                      spatial_dimension, type);
 
   /// assign some values to stresses
   Array<Real> & stress =
       const_cast<Array<Real> &>(model.getMaterial(0).getStress(type));
 
   for (UInt q = 0; q < nb_tot_quad_el; ++q) {
     for (UInt s = 0; s < spatial_dimension * spatial_dimension; ++s) {
       stress(q, s) = s * function(quad_elements(q, 0), quad_elements(q, 1),
                                   quad_elements(q, 2));
     }
   }
 
   /// interpolate stresses on facets' quadrature points
   model.getMaterial(0).initElementalFieldInterpolation(element_quad_facet);
   model.getMaterial(0).interpolateStress(interpolated_stress);
 
   Real tolerance = 1.e-10;
 
   /// check results
   for (UInt el = 0; el < nb_element; ++el) {
     for (UInt f = 0; f < nb_facet_per_elem; ++f) {
 
       for (UInt q = 0; q < nb_quad_per_facet; ++q) {
         for (UInt s = 0; s < spatial_dimension * spatial_dimension; ++s) {
 
           Real x = el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
                                   f * nb_quad_per_facet + q,
                               0);
           Real y = el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
                                   f * nb_quad_per_facet + q,
                               1);
           Real z = el_q_facet(el * nb_facet_per_elem * nb_quad_per_facet +
                                   f * nb_quad_per_facet + q,
                               2);
 
           Real theoretical = s * function(x, y, z);
 
           Real numerical =
               interp_stress(el * nb_facet_per_elem * nb_quad_per_facet +
                                 f * nb_quad_per_facet + q,
                             s);
 
           if (std::abs(theoretical - numerical) > tolerance) {
             std::cout << "Theoretical and numerical values aren't coincident!"
                       << std::endl;
             return EXIT_FAILURE;
           }
         }
       }
     }
   }
 
   std::cout << "OK: Stress interpolation test passed." << std::endl;
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc
index 325e3881e..9eeeaa40c 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_material_thermal.cc
@@ -1,101 +1,100 @@
 /**
  * @file   test_material_thermal.cc
  *
  * @author Lucas Frerot <lucas.frerot@epfl.ch>
  *
  * @date creation: Wed Aug 04 2010
  * @date last modification: Sun Oct 19 2014
  *
  * @brief  test of the class akantu::MaterialThermal
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 
 /* -------------------------------------------------------------------------- */
 #include "non_linear_solver.hh"
 #include "solid_mechanics_model.hh"
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char * argv[]) {
   debug::setDebugLevel(dblWarning);
   initialize("material_thermal.dat", argc, argv);
 
   Math::setTolerance(1.e-13);
 
   Mesh mesh(2);
   mesh.read("square.msh");
 
   SolidMechanicsModel model(mesh);
   model.initFull(_analysis_method = _static);
 
-  mesh.computeBoundingBox();
   const Vector<Real> & min = mesh.getLowerBounds();
   const Vector<Real> & max = mesh.getUpperBounds();
 
   Array<Real> & pos = mesh.getNodes();
   Array<bool> & boundary = model.getBlockedDOFs();
   Array<Real> & disp = model.getDisplacement();
 
   for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
     if (Math::are_float_equal(pos(i, 0), min(0))) {
       boundary(i, 0) = true;
     }
 
     if (Math::are_float_equal(pos(i, 1), min(1))) {
       boundary(i, 1) = true;
     }
   }
 
   model.setBaseName("test_material_thermal");
   model.addDumpField("displacement");
   model.addDumpField("strain");
   model.addDumpField("stress");
   model.addDumpField("delta_T");
 
   auto & solver = model.getNonLinearSolver("static");
   solver.set("max_iterations", 2);
   solver.set("threshold", 1e-10);
 
   model.solveStep();
 
   for (UInt i = 0; i < mesh.getNbNodes(); ++i) {
     if (Math::are_float_equal(pos(i, 0), max(0)) &&
         Math::are_float_equal(pos(i, 1), max(1))) {
       if (!Math::are_float_equal(disp(i, 0), 1.0) ||
           !Math::are_float_equal(disp(i, 1), 1.0)) {
         AKANTU_DEBUG_ERROR("Test not passed");
         return EXIT_FAILURE;
       }
     }
   }
 
   model.dump();
 
   finalize();
 
   std::cout << "Test passed" << std::endl;
   return EXIT_SUCCESS;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_materials/test_multi_material_elastic.cc b/test/test_model/test_solid_mechanics_model/test_materials/test_multi_material_elastic.cc
index a354718ad..b087bfb75 100644
--- a/test/test_model/test_solid_mechanics_model/test_materials/test_multi_material_elastic.cc
+++ b/test/test_model/test_solid_mechanics_model/test_materials/test_multi_material_elastic.cc
@@ -1,92 +1,92 @@
 #include <solid_mechanics_model.hh>
 #include "non_linear_solver.hh"
 
 using namespace akantu;
 
 int main(int argc, char *argv[]) {
   initialize("test_multi_material_elastic.dat", argc, argv);
 
   UInt spatial_dimension = 2;
   Mesh mesh(spatial_dimension);
 
   mesh.read("test_multi_material_elastic.msh");
-  mesh.createGroupsFromMeshData<std::string>("physical_names");
 
   SolidMechanicsModel model(mesh);
 
   MeshDataMaterialSelector<std::string> mat_sel("physical_names", model);
   model.setMaterialSelector(mat_sel);
 
   model.initFull(_analysis_method = _static);
 
   model.applyBC(BC::Dirichlet::FlagOnly(_y), "ground");
   model.applyBC(BC::Dirichlet::FlagOnly(_x), "corner");
 
   Vector<Real> trac(spatial_dimension, 0.);
   trac(_y) = 1.;
   model.applyBC(BC::Neumann::FromTraction(trac), "air");
 
-  model.addDumpField("force");
-  model.addDumpField("residual");
+  model.addDumpField("external_force");
+  model.addDumpField("internal_force");
   model.addDumpField("blocked_dofs");
   model.addDumpField("displacement");
   model.addDumpField("stress");
   model.addDumpField("grad_u");
 
   //model.dump();
   auto & solver = model.getNonLinearSolver("static");
   solver.set("max_iterations", 1);
   solver.set("threshold", 1e-8);
   solver.set("convergence_type", _scc_residual);
 
+  model.solveStep();
   //model.dump();
 
   std::map<std::string, Matrix<Real>> ref_strain;
   ref_strain["strong"] = Matrix<Real>(spatial_dimension, spatial_dimension, 0.);
   ref_strain["strong"](_y, _y) = .5;
 
   ref_strain["weak"] = Matrix<Real>(spatial_dimension, spatial_dimension, 0.);
   ref_strain["weak"](_y, _y) = 1;
 
   Matrix<Real> ref_stress(spatial_dimension, spatial_dimension, 0.);
   ref_stress(_y, _y) = 1.;
 
   std::vector<std::string> mats = {"strong", "weak"};
 
   typedef Array<Real>::const_matrix_iterator mat_it;
   auto check = [](mat_it it, mat_it end, const Matrix<Real> & ref) -> bool {
     for(;it != end; ++it) {
       Real dist = (*it - ref).norm<L_2>();
 
       //std::cout << *it << " " << dist << " " << (dist < 1e-10 ? "OK" : "Not OK") << std::endl;
 
       if (dist > 1e-10) return false;
     }
 
     return true;
   };
 
   auto tit = mesh.firstType(spatial_dimension);
   auto tend = mesh.lastType(spatial_dimension);
   for (; tit != tend; ++tit) {
     auto & type = *tit;
 
     for(auto mat_id : mats) {
       auto & stress = model.getMaterial(mat_id).getStress(type);
       auto & grad_u = model.getMaterial(mat_id).getGradU(type);
 
       auto sit = stress.begin(spatial_dimension, spatial_dimension);
       auto send = stress.end(spatial_dimension, spatial_dimension);
 
       auto git = grad_u.begin(spatial_dimension, spatial_dimension);
       auto gend = grad_u.end(spatial_dimension, spatial_dimension);
 
       if(!check(sit, send, ref_stress)) AKANTU_DEBUG_ERROR("The stresses are not correct");
       if(!check(git, gend, ref_strain[mat_id])) AKANTU_DEBUG_ERROR("The grad_u are not correct");
     }
   }
 
   finalize();
 
    return 0;
 }
diff --git a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
index 5b363ef62..2b1fafe0d 100644
--- a/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
+++ b/test/test_model/test_solid_mechanics_model/test_solid_mechanics_model_material_eigenstrain.cc
@@ -1,203 +1,201 @@
 /**
  * @file   test_solid_mechanics_model_material_eigenstrain.cc
  *
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Sat Apr 16 2011
  * @date last modification: Wed Aug 12 2015
  *
  * @brief  test the internal field prestrain
  *
  * @section 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 "non_linear_solver.hh"
 
 
 using namespace akantu;
 
 Real alpha [3][4] = { { 0.01, 0.02, 0.03, 0.04 },
 		      { 0.05, 0.06, 0.07, 0.08 },
 		      { 0.09, 0.10, 0.11, 0.12 } };
 
 /* -------------------------------------------------------------------------- */
 template<ElementType type>
 static Matrix<Real> prescribed_strain() {
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
   Matrix<Real> strain(spatial_dimension, spatial_dimension);
 
   for (UInt i = 0; i < spatial_dimension; ++i) {
     for (UInt j = 0; j < spatial_dimension; ++j) {
       strain(i, j) = alpha[i][j + 1];
     }
   }
   return strain;
 }
 
 template<ElementType type>
 static Matrix<Real> prescribed_stress(Matrix<Real> prescribed_eigengradu) {
   UInt spatial_dimension = ElementClass<type>::getSpatialDimension();
   Matrix<Real> stress(spatial_dimension, spatial_dimension);
 
   //plane strain in 2d
   Matrix<Real> strain(spatial_dimension, spatial_dimension);
   Matrix<Real> pstrain;
   pstrain = prescribed_strain<type>();
   Real nu = 0.3;
   Real E  = 2.1e11;
   Real trace = 0;
 
   /// symetric part of the strain tensor
   for (UInt i = 0; i < spatial_dimension; ++i)
     for (UInt j = 0; j < spatial_dimension; ++j)
       strain(i,j) = 0.5 * (pstrain(i, j) + pstrain(j, i));
 
   // elastic strain is equal to elastic strain minus the eigenstrain
   strain -= prescribed_eigengradu;
   for (UInt i = 0; i < spatial_dimension; ++i) trace += strain(i,i);
 
   Real lambda   = nu * E / ((1 + nu) * (1 - 2*nu));
   Real mu       = E / (2 * (1 + nu));
 
   if(spatial_dimension == 1) {
     stress(0, 0) =  E * strain(0, 0);
   } else {
     for (UInt i = 0; i < spatial_dimension; ++i)
       for (UInt j = 0; j < spatial_dimension; ++j) {
 	stress(i, j) =  (i == j)*lambda*trace + 2*mu*strain(i, j);
       }
   }
 
   return stress;
 }
 
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 int main(int argc, char *argv[]) {
   initialize("material_elastic_plane_strain.dat", argc, argv);
 
   UInt dim = 3;
   const ElementType element_type = _tetrahedron_4;
 
   Matrix<Real> prescribed_eigengradu(dim, dim);
   prescribed_eigengradu.set(0.1);
 
   /// load mesh
   Mesh mesh(dim);
   mesh.read("cube_3d_tet_4.msh");
 
   /// declaration of model
   SolidMechanicsModel  model(mesh);
   /// model initialization
   model.initFull(_analysis_method = _static);
 
   //model.getNewSolver("static", _tsst_static, _nls_newton_raphson_modified);
   auto & solver = model.getNonLinearSolver("static");
   solver.set("threshold", 2e-4);
   solver.set("max_iterations", 2);
   solver.set("convergence_type", _scc_residual);
 
   const Array<Real> & coordinates = mesh.getNodes();
   Array<Real> & displacement = model.getDisplacement();
   Array<bool> & boundary = model.getBlockedDOFs();
   MeshUtils::buildFacets(mesh);
 
   mesh.createBoundaryGroupFromGeometry();
 
   // Loop over (Sub)Boundar(ies)
   for(GroupManager::const_element_group_iterator it(mesh.element_group_begin());
       it != mesh.element_group_end(); ++it) {
-    for(ElementGroup::const_node_iterator nodes_it(it->second->node_begin());
-        nodes_it!= it->second->node_end(); ++nodes_it) {
-      UInt n(*nodes_it);
-      std::cout << "Node " << *nodes_it << std::endl;
+    for(const auto & n : it->second->getNodeGroup()) {
+      std::cout << "Node " << n << std::endl;
       for (UInt i = 0; i < dim; ++i) {
         displacement(n, i) = alpha[i][0];
         for (UInt j = 0; j < dim; ++j) {
           displacement(n, i) += alpha[i][j + 1] * coordinates(n, j);
         }
         boundary(n, i) = true;
       }
     }
   }
 
   /* ------------------------------------------------------------------------ */
   /* Apply eigenstrain in each element                                          */
   /* ------------------------------------------------------------------------ */
   Array<Real> & eigengradu_vect =
     model.getMaterial(0).getInternal<Real>("eigen_grad_u")(element_type);
   auto eigengradu_it = eigengradu_vect.begin(dim, dim);
   auto eigengradu_end = eigengradu_vect.end(dim, dim);
 
   for (; eigengradu_it != eigengradu_end; ++eigengradu_it) {
     *eigengradu_it = prescribed_eigengradu;
   }
 
   /* ------------------------------------------------------------------------ */
   /* Static solve                                                             */
   /* ------------------------------------------------------------------------ */
   model.solveStep();
 
   std::cout << "Converged in " << Int(solver.get("nb_iterations"))
             << " (" << Real(solver.get("error")) << ")" << std::endl;
 
   /* ------------------------------------------------------------------------ */
   /* Checks                                                                   */
   /* ------------------------------------------------------------------------ */
   const Array<Real> & stress_vect = model.getMaterial(0).getStress(element_type);
 
   auto stress_it = stress_vect.begin(dim, dim);
   auto stress_end = stress_vect.end(dim, dim);
 
   Matrix<Real> presc_stress;
   presc_stress = prescribed_stress<element_type>(prescribed_eigengradu);
 
   Real stress_tolerance = 1e-13;
 
   for (; stress_it != stress_end; ++stress_it) {
     const auto & stress = *stress_it;
     Matrix<Real> diff(dim, dim);
 
     diff  = stress;
     diff -= presc_stress;
     Real stress_error = diff.norm<L_inf>() / stress.norm<L_inf>();
 
     if(stress_error > stress_tolerance) {
       std::cerr << "stress error: " << stress_error
                 << " > " << stress_tolerance << std::endl;
       std::cerr << "stress: " << stress << std::endl
                 << "prescribed stress: " << presc_stress << std::endl;
       return EXIT_FAILURE;
     } // else {
     //   std::cerr << "stress error: " << stress_error
     //             << " < " << stress_tolerance << std::endl;
     // }
   }
 
   finalize();
 
   return EXIT_SUCCESS;
 }
diff --git a/test/test_synchronizer/test_data_distribution.cc b/test/test_synchronizer/test_data_distribution.cc
index d3c8db9c9..2efd1498e 100644
--- a/test/test_synchronizer/test_data_distribution.cc
+++ b/test/test_synchronizer/test_data_distribution.cc
@@ -1,197 +1,197 @@
 /**
  * @file   test_data_distribution.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Sep 05 2014
  * @date last modification: Sun Oct 19 2014
  *
  * @brief  Test the mesh distribution on creation of a distributed synchonizer
  *
  * @section LICENSE
  *
  * Copyright  (©)  2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "element_group.hh"
 #include "element_synchronizer.hh"
 #include "mesh_partition_mesh_data.hh"
 #include "aka_random_generator.hh"
 
 /* -------------------------------------------------------------------------- */
 
 using namespace akantu;
 
 int main(int argc, char * argv[]) {
   initialize(argc, argv);
 
   const UInt spatial_dimension = 3;
 
   Mesh mesh_group_after(spatial_dimension, "after");
   Mesh mesh_group_before(spatial_dimension, "before");
 
   StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
   Int psize = comm.getNbProc();
   Int prank = comm.whoAmI();
 
   if (prank == 0) {
     mesh_group_before.read("data_split.msh");
     mesh_group_after.read("data_split.msh");
 
     mesh_group_before.registerData<UInt>("global_id");
     mesh_group_after.registerData<UInt>("global_id");
 
     for (Mesh::type_iterator tit = mesh_group_after.firstType(_all_dimensions);
          tit != mesh_group_after.lastType(_all_dimensions); ++tit) {
       Array<UInt> & gidb =
-          *(mesh_group_before.getDataPointer<UInt>("global_id", *tit));
+          mesh_group_before.getDataPointer<UInt>("global_id", *tit);
       Array<UInt> & gida =
-          *(mesh_group_after.getDataPointer<UInt>("global_id", *tit));
+          mesh_group_after.getDataPointer<UInt>("global_id", *tit);
 
       Array<UInt>::scalar_iterator ait = gida.begin();
       Array<UInt>::scalar_iterator bit = gidb.begin();
       Array<UInt>::scalar_iterator end = gida.end();
       for (UInt i = 0; ait != end; ++ait, ++i, ++bit) {
         *bit = i;
         *ait = i;
       }
     }
   }
 
   RandomGenerator<UInt>::seed(1);
   mesh_group_before.distribute();
 
   RandomGenerator<UInt>::seed(1);
   mesh_group_after.distribute();
 
   if (prank == 0)
     std::cout << mesh_group_after;
 
   GroupManager::element_group_iterator grp_ait =
       mesh_group_after.element_group_begin();
   GroupManager::element_group_iterator grp_end =
       mesh_group_after.element_group_end();
   for (; grp_ait != grp_end; ++grp_ait) {
     std::string grp = grp_ait->first;
     const ElementGroup & bgrp = mesh_group_before.getElementGroup(grp);
     const ElementGroup & agrp = *grp_ait->second;
 
     for (ghost_type_t::iterator git = ghost_type_t::begin();
          git != ghost_type_t::end(); ++git) {
       GhostType ghost_type = *git;
 
       for (Mesh::type_iterator tit =
                bgrp.firstType(_all_dimensions, ghost_type);
            tit != bgrp.lastType(_all_dimensions, ghost_type); ++tit) {
-        Array<UInt> & gidb = *(mesh_group_before.getDataPointer<UInt>(
-            "global_id", *tit, ghost_type));
-        Array<UInt> & gida = *(mesh_group_after.getDataPointer<UInt>(
-            "global_id", *tit, ghost_type));
+        Array<UInt> & gidb = mesh_group_before.getDataPointer<UInt>(
+            "global_id", *tit, ghost_type);
+        Array<UInt> & gida = mesh_group_after.getDataPointer<UInt>(
+            "global_id", *tit, ghost_type);
 
         Array<UInt> bgelem(bgrp.getElements(*tit, ghost_type));
         Array<UInt> agelem(agrp.getElements(*tit, ghost_type));
 
         Array<UInt>::scalar_iterator ait = agelem.begin();
         Array<UInt>::scalar_iterator bit = bgelem.begin();
         Array<UInt>::scalar_iterator end = agelem.end();
         for (; ait != end; ++ait, ++bit) {
           *bit = gidb(*bit);
           *ait = gida(*ait);
         }
 
         std::sort(bgelem.begin(), bgelem.end());
         std::sort(agelem.begin(), agelem.end());
 
         if (!std::equal(bgelem.begin(), bgelem.end(), agelem.begin())) {
           std::cerr << "The filters array for the group " << grp
                     << " and for the element type " << *tit << ", "
                     << ghost_type << " do not match" << std::endl;
 
           debug::setDebugLevel(dblTest);
 
           std::cerr << bgelem << std::endl;
           std::cerr << agelem << std::endl;
           debug::debugger.exit(EXIT_FAILURE);
         }
       }
     }
   }
 
   GroupManager::node_group_iterator ngrp_ait =
       mesh_group_after.node_group_begin();
   GroupManager::node_group_iterator ngrp_end =
       mesh_group_after.node_group_end();
   for (; ngrp_ait != ngrp_end; ++ngrp_ait) {
     std::string grp = ngrp_ait->first;
     const NodeGroup & bgrp = mesh_group_before.getNodeGroup(grp);
     const NodeGroup & agrp = *ngrp_ait->second;
 
     const Array<UInt> & gidb = mesh_group_before.getGlobalNodesIds();
     const Array<UInt> & gida = mesh_group_after.getGlobalNodesIds();
 
     Array<UInt> bgnode(0, 1);
     Array<UInt> agnode(0, 1);
 
     Array<UInt>::const_scalar_iterator ait = agrp.begin();
     Array<UInt>::const_scalar_iterator bit = bgrp.begin();
     Array<UInt>::const_scalar_iterator end = agrp.end();
     for (; ait != end; ++ait, ++bit) {
       if (psize > 1) {
         if (mesh_group_before.isLocalOrMasterNode(*bit))
           bgnode.push_back(gidb(*bit));
 
         if (mesh_group_after.isLocalOrMasterNode(*ait))
           agnode.push_back(gida(*ait));
       }
     }
 
     std::sort(bgnode.begin(), bgnode.end());
     std::sort(agnode.begin(), agnode.end());
 
     if (!std::equal(bgnode.begin(), bgnode.end(), agnode.begin())) {
       std::cerr << "The filters array for the group " << grp << " do not match"
                 << std::endl;
 
       debug::setDebugLevel(dblTest);
 
       std::cerr << bgnode << std::endl;
       std::cerr << agnode << std::endl;
       debug::debugger.exit(EXIT_FAILURE);
     }
   }
 
   mesh_group_after.getElementGroup("inside").setBaseName("after_inside");
   mesh_group_after.getElementGroup("inside").dump();
   mesh_group_after.getElementGroup("outside").setBaseName("after_outside");
   mesh_group_after.getElementGroup("outside").dump();
   mesh_group_after.getElementGroup("volume").setBaseName("after_volume");
   mesh_group_after.getElementGroup("volume").dump();
 
   mesh_group_before.getElementGroup("inside").setBaseName("before_inside");
   mesh_group_before.getElementGroup("inside").dump();
   mesh_group_before.getElementGroup("outside").setBaseName("before_outside");
   mesh_group_before.getElementGroup("outside").dump();
   mesh_group_before.getElementGroup("volume").setBaseName("before_volume");
   mesh_group_before.getElementGroup("volume").dump();
 
   finalize();
 
   return EXIT_SUCCESS;
 }