diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 04b727722..c7274da8d 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -1,301 +1,305 @@
 #===============================================================================
 # @file   CMakeLists.txt
 #
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date creation: Fri Dec 12 2014
 # @date last modification: Mon Jan 18 2016
 #
 # @brief  CMake file for the python wrapping of akantu
 #
 # @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/>.
 #
 #===============================================================================
 
 #===============================================================================
 # Configuration
 #===============================================================================
 package_get_all_definitions(AKANTU_DEFS)
 list(REMOVE_ITEM AKANTU_DEFS AKANTU_CORE_CXX11)
 #message(${AKANTU_DEFS})
 set(AKA_DEFS "")
 foreach (def ${AKANTU_DEFS})
   list(APPEND AKA_DEFS "-D${def}")
 endforeach()
 
 set(AKANTU_SWIG_FLAGS -w309,325,401,317,509,503,383,384 ${AKA_DEFS})
 set(AKANTU_SWIG_OUTDIR ${CMAKE_CURRENT_SOURCE_DIR})
 set(AKANTU_SWIG_MODULES swig/akantu.i)
 
 #===============================================================================
 # Swig wrapper
 #===============================================================================
 
 set(SWIG_REQURIED_VERISON 3.0)
 find_package(SWIG ${SWIG_REQURIED_VERISON})
 find_package(PythonInterp 2.7 REQUIRED)
 mark_as_advanced(SWIG_EXECUTABLE)
 
 package_get_all_include_directories(
   AKANTU_LIBRARY_INCLUDE_DIRS
   )
 
 package_get_all_external_informations(
   AKANTU_EXTERNAL_INCLUDE_DIR
   AKANTU_EXTERNAL_LIBRARIES
 )
 
 set(_swig_include_dirs
   ${CMAKE_CURRENT_SOURCE_DIR}/swig
   ${AKANTU_LIBRARY_INCLUDE_DIRS}
   ${PROJECT_BINARY_DIR}/src
   ${AKANTU_EXTERNAL_INCLUDE_DIR}
   )
 
 include(CMakeParseArguments)
 
 function(swig_generate_dependencies _module _depedencies _depedencies_out)
   set(_dependencies_script "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/_swig_generate_dependencies.cmake")
   file(WRITE ${_dependencies_script} "
 set(_include_directories ${_include_directories})
 list(APPEND _include_directories \"./\")
 
 set(_dep)
 set(_files_to_process \${_module})
 while(_files_to_process)
   list(GET _files_to_process 0 _file)
   list(REMOVE_AT _files_to_process 0)
   file(STRINGS \${_file} _file_content REGEX \"^%include *\\\"(.*)\\\"\")
 
   set(_includes)
   foreach(_line \${_file_content})
     string(REGEX REPLACE \"^%include *\\\"(.*)\\\"\" \"\\\\1\" _inc \${_line})
     if(_inc)
       list(APPEND _includes \${_inc})
     endif()
   endforeach()
 
   foreach(_include \${_includes})
     unset(_found)
     foreach(_inc_dir \${_include_directories})
       if(EXISTS \${_inc_dir}/\${_include})
         set(_found \${_inc_dir}/\${_include})
         break()
       endif()
     endforeach()
 
     if(_found)
       list(APPEND _files_to_process \${_found})
       list(APPEND _dep \${_found})
     endif()
   endforeach()
 endwhile()
 
 get_filename_component(_module_we \"\${_module}\" NAME_WE)
 set(_dependencies_file \${CMAKE_CURRENT_BINARY_DIR}\${CMAKE_FILES_DIRECTORY}/_swig_\${_module_we}_depends.cmake)
 file(WRITE \"\${_dependencies_file}\"
   \"set(_swig_\${_module_we}_depends\")
 foreach(_d \${_dep})
   file(APPEND \"\${_dependencies_file}\" \"
   \${_d}\")
 endforeach()
 file(APPEND \"\${_dependencies_file}\" \"
   )\")
 ")
 
   get_filename_component(_module_absolute "${_module}" ABSOLUTE)
   get_filename_component(_module_we "${_module}" NAME_WE)
 
   set(_dependencies_file ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/_swig_${_module_we}_depends.cmake)
 
   if(EXISTS ${_dependencies_file})
     include(${_dependencies_file})
   else()
     execute_process(COMMAND ${CMAKE_COMMAND}
       -D_module=${_module_absolute}
       -P ${_dependencies_script}
       WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
     include(${_dependencies_file})
   endif()
 
   set(${_depedencies_out} ${_swig_${_module_we}_depends} PARENT_SCOPE)
 
   add_custom_command(OUTPUT ${_dependencies_file}
     COMMAND ${CMAKE_COMMAND}
     -D_module=${_module_absolute}
     -P ${_dependencies_script}
     COMMENT "Scanning dependencies for swig module ${_module_we}"
     WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
     MAIN_DEPENDENCY ${_module_absolute}
     DEPENDS ${_swig_${_module_we}_depends}
     )
 
   set(${_depedencies} ${_dependencies_file} PARENT_SCOPE)
 endfunction()
 
 function(swig_generate_wrappers project _wrappers_cpp _wrappers_py)
   cmake_parse_arguments(_swig_opt "" "OUTPUT_DIR;DEPENDENCIES" "EXTRA_FLAGS;INCLUDE_DIRECTORIES" ${ARGN})
 
   if(_swig_opt_OUTPUT_DIR)
     set(_output_dir ${_swig_opt_OUTPUT_DIR})
   else()
     set(_output_dir ${CMAKE_CURRENT_BINARY_DIR})
   endif()
 
   set(_swig_wrappers)
   get_directory_property(_include_directories INCLUDE_DIRECTORIES)
   list(APPEND _include_directories ${_swig_opt_INCLUDE_DIRECTORIES})
   if(_include_directories)
     string(REPLACE ";" ";-I" _swig_include_directories "${_include_directories}")
   endif()
 
   foreach(_module ${_swig_opt_UNPARSED_ARGUMENTS})
     swig_generate_dependencies(${_module} _module_dependencies _depends_out)
     if(_swig_opt_DEPENDENCIES)
       set(${_swig_opt_DEPENDENCIES} ${_depends_out} PARENT_SCOPE)
     endif()
 
     get_filename_component(_module_absolute "${_module}" ABSOLUTE)
     get_filename_component(_module_path "${_module_absolute}" PATH)
     get_filename_component(_module_name "${_module}" NAME)
     get_filename_component(_module_we "${_module}" NAME_WE)
     set(_wrapper "${_output_dir}/${_module_we}_wrapper.cpp")
     set(_extra_wrapper "${_output_dir}/${_module_we}.py")
     set(_extra_wrapper_bin "${CMAKE_CURRENT_BINARY_DIR}/${_module_we}.py")
 
     if(SWIG_FOUND)
       set_source_files_properties("${_wrapper}" PROPERTIES GENERATED 1)
       set_source_files_properties("${_extra_wrapper}" PROPERTIES GENERATED 1)
 
       set(_dependencies_file ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/_swig_${_module_we}_depends.cmake)
 
       set(_ouput "${_wrapper}" "${_extra_wrapper}")
       add_custom_command(
         OUTPUT ${_ouput}
         COMMAND "${SWIG_EXECUTABLE}"
         ARGS -python -c++
         ${_swig_opt_EXTRA_FLAGS}
         -outdir ${_output_dir}
         -I${_swig_include_directories} -I${_module_path}
         -o "${_wrapper}"
         "${_module_absolute}"
         COMMAND ${CMAKE_COMMAND} -E copy_if_different ${_extra_wrapper} ${_extra_wrapper_bin}
         #	MAIN_DEPENDENCY "${_module_absolute}"
         DEPENDS ${_module_dependencies}
         COMMENT "Generating swig wrapper ${_module} -> ${_wrapper}"
         )
 
       list(APPEND _swig_wrappers ${_wrapper})
       list(APPEND _swig_wrappers_py "${_extra_wrapper_bin}")
     else()
       if(NOT EXISTS ${_wrapper} OR NOT EXISTS "${_extra_wrapper}")
         message(FATAL_ERROR "The file ${_wrapper} and/or ${_extra_wrapper} does "
           "not exists and they cannot be generated. Install swig ${SWIG_REQURIED_VERISON} "
           " in order to generate them. Or get them from a different machine, "
           "in order to be able to compile the python interface")
       else()
         list(APPEND _swig_wrappers "${_wrapper}")
         list(APPEND _swig_wrappers_py "${_extra_wrapper_bin}")
       endif()
     endif()
   endforeach()
 
   add_custom_target(${project}_generate_swig_wrappers DEPENDS ${_swig_wrappers})
 
   set(${_wrappers_cpp} ${_swig_wrappers} PARENT_SCOPE)
   set(${_wrappers_py} ${_swig_wrappers_py} PARENT_SCOPE)
 endfunction()
 
 
 swig_generate_wrappers(akantu AKANTU_SWIG_WRAPPERS_CPP AKANTU_WRAPPERS_PYTHON
   ${AKANTU_SWIG_MODULES}
   EXTRA_FLAGS ${AKANTU_SWIG_FLAGS}
   DEPENDENCIES _deps
   INCLUDE_DIRECTORIES ${_swig_include_dirs})
 
 if(AKANTU_SWIG_WRAPPERS_CPP)
   string(REPLACE ";" "', '" _ext_files "${AKANTU_SWIG_WRAPPERS_CPP}")
   string(REPLACE ";" "', '" _inc_dirs "${_swig_include_dirs}")
-  string(STRIP "${AKANTU_EXTRA_CXX_FLAGS}" _tmp_flags)
-  string(REGEX REPLACE " +" "', '" _flags "${_tmp_flags} -Wno-maybe-uninitialized")
+  if (AKANTU_EXTRA_CXX_FLAGS)
+    string(STRIP "${AKANTU_EXTRA_CXX_FLAGS}" _tmp_flags)
+    string(REGEX REPLACE " +" "', '" _flags "${_tmp_flags} -Wno-maybe-uninitialized")
+  else()
+    set(_flags "-Wno-maybe-uninitialized")
+  endif()
 
   if(CMAKE_VERBOSE_MAKEFILE)
     set(_quiet)
   else()
     set(_quiet --quiet)
   endif()
 
   file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/setup.py "
 from distutils.core import setup
 from distutils.core import setup, Extension
 import os
 
 
 os.environ['CC'] = '${CMAKE_CXX_COMPILER}'
 os.environ['CXX'] = '${CMAKE_CXX_COMPILER}'
 setup(name='akantu',
       license='LGPLv3',
       version='${AKANTU_VERSION}',
       py_modules=['akantu'],
       ext_modules=[Extension('_akantu', ['${_ext_files}'],
                              include_dirs=['${_inc_dirs}'],
                              language='c++',
                              libraries=['akantu'],
                              library_dirs=['${PROJECT_BINARY_DIR}/src'],
-                             extra_compile_args=['${_flags}'])],
+                             extra_compile_args=['${_flags}', '-std=c++14'])],
       )
 ")
 
   add_custom_target(_akantu ALL
     COMMAND ${PYTHON_EXECUTABLE} ./setup.py ${_quiet} --no-user-cfg build_ext --inplace
     WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
     DEPENDS ${AKANTU_SWIG_WRAPPERS_CPP} akantu
     COMMENT "Building akantu's python interface"
     )
 
   set_directory_properties(PROPERTIES
     ADDITIONAL_MAKE_CLEAN_FILES
       ${CMAKE_CURRENT_BINARY_DIR}/_akantu${CMAKE_SHARED_MODULE_SUFFIX})
 
   # add_library(_akantu MODULE ${AKANTU_SWIG_WRAPPERS_CPP})
   # target_link_libraries(_akantu akantu)
 
   # set_target_properties(_akantu PROPERTIES PREFIX "")
 
   # list(APPEND AKANTU_EXPORT_LIST _akantu)
 
   # install(TARGETS _akantu
   #   EXPORT ${AKANTU_TARGETS_EXPORT}
   #   LIBRARY DESTINATION lib COMPONENT python NAMELINK_SKIP # for real systems
   #   ARCHIVE DESTINATION lib COMPONENT python
   #   RUNTIME DESTINATION bin COMPONENT python # for windows ...
   #   )
 
   # install(FILES ${AKANTU_WRAPPERS_PYTHON}
   #   DESTINATION lib COMPONENT python
   #   )
 
   install(CODE "execute_process(
     COMMAND ${PYTHON_EXECUTABLE} ./setup.py ${_quiet} install --prefix=${AKANTU_PYTHON_INSTALL_PREFIX}
     WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
     )"
     COMPONENT python)
 
   package_declare_extra_files_to_package(python_interface ${_deps} ${PROJECT_SOURCE_DIR}/python/${AKANTU_SWIG_MODULES})
 endif()
diff --git a/python/swig/aka_array.i b/python/swig/aka_array.i
index 117f261fb..5012a68a5 100644
--- a/python/swig/aka_array.i
+++ b/python/swig/aka_array.i
@@ -1,248 +1,251 @@
 /**
  * @file   aka_array.i
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 12 2014
  * @date last modification: Wed Nov 11 2015
  *
  * @brief  wrapper for arrays
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 %{
 #define SWIG_FILE_WITH_INIT
 #include "aka_array.hh"
 #include "aka_types.hh"
 %}
 
 %include "typemaps.i"
 
 namespace akantu {
   %ignore Array::operator=;
   %ignore Array::operator[];
   %ignore Array::operator();
   %ignore Array::set;
   %ignore Array::begin;
   %ignore Array::end;
   %ignore Array::begin_reinterpret;
   %ignore Array::end_reinterpret;
+  %ignore ArrayBase::getSize;
+  %ignore Array::operator*=;
+  %ignore Array::operator*;
 };
 
 %include "aka_array.hh"
 
 namespace akantu {
   %ignore TensorProxy::operator=;
   %ignore TensorProxy::operator[];
   %ignore TensorProxy::operator();
   %ignore Tensor3Proxy::operator=;
   %ignore Tensor3Proxy::operator[];
   %ignore Tensor3Proxy::operator();
   %ignore TensorStorage::operator=;
   %ignore TensorStorage::operator[];
   %ignore TensorStorage::operator();
   %ignore VectorProxy::operator=;
   %ignore VectorProxy::operator[];
   %ignore VectorProxy::operator();
   %ignore MatrixProxy::operator=;
   %ignore MatrixProxy::operator[];
   %ignore MatrixProxy::operator();
   %ignore Matrix::operator=;
   %ignore Matrix::operator[];
   %ignore Matrix::operator();
   %ignore Tensor3::operator=;
   %ignore Tensor3::operator[];
   %ignore Tensor3::operator();
   %ignore Vector::operator=;
   %ignore Vector::operator[];
   %ignore Vector::operator();
   %ignore Vector::solve;
 };
 
 %include "aka_types.hh"
 
 namespace akantu {
   %template(RArray) Array<akantu::Real, true>;
   %template(UArray) Array<akantu::UInt, true>;
   %template(BArray) Array<bool, true>;
   %template(RVector) Vector<akantu::Real>;
 };
 
 %include "numpy.i"
 %init %{
   import_array();
 %}
 
 %inline %{
   namespace akantu{
     template <typename T>
       class ArrayForPython : public Array<T>{
 
     public:
     ArrayForPython(T * wrapped_memory,
-		   UInt size = 0,
+		   UInt size_ = 0,
 		   UInt nb_component = 1,
 		   const ID & id = "")
       : Array<T>(0,nb_component,id){
 	this->values = wrapped_memory;
-	this->size = size;
+	this->size_ = size_;
       };
 
       ~ArrayForPython(){
 	this->values = NULL;
       };
 
       void resize(UInt new_size){
-	AKANTU_DEBUG_ASSERT(this->size == new_size,"cannot resize a temporary vector");
+	AKANTU_DEBUG_ASSERT(this->size_ == new_size,"cannot resize a temporary vector");
       }
     };
   }
  template <typename T> int getPythonDataTypeCode(){ AKANTU_EXCEPTION("undefined type");}
  template <> int getPythonDataTypeCode<bool>(){
    int data_typecode = NPY_NOTYPE;
    size_t s = sizeof(bool);
    switch(s) {
    case 1: data_typecode = NPY_BOOL; break;
    case 2: data_typecode = NPY_UINT16; break;
    case 4: data_typecode = NPY_UINT32; break;
    case 8: data_typecode = NPY_UINT64; break;
    }
    return data_typecode;
  }
 
  template <> int getPythonDataTypeCode<double>(){return NPY_DOUBLE;}
  template <> int getPythonDataTypeCode<long double>(){return NPY_LONGDOUBLE;}
  template <> int getPythonDataTypeCode<float>(){return NPY_FLOAT;}
  template <> int getPythonDataTypeCode<unsigned long>(){
    int data_typecode = NPY_NOTYPE;
    size_t s = sizeof(unsigned long);
    switch(s) {
    case 2: data_typecode  = NPY_UINT16;  break;
    case 4: data_typecode  = NPY_UINT32; break;
    case 8: data_typecode  = NPY_UINT64; break;
    }
    return data_typecode;
  }
  template <> int getPythonDataTypeCode<akantu::UInt>(){
    int data_typecode = NPY_NOTYPE;
    size_t s = sizeof(akantu::UInt);
    switch(s) {
    case 2: data_typecode  = NPY_UINT16;  break;
    case 4: data_typecode  = NPY_UINT32; break;
    case 8: data_typecode  = NPY_UINT64; break;
    }
    return data_typecode;
  }
  template <> int getPythonDataTypeCode<int>(){
    int data_typecode = NPY_NOTYPE;
    size_t s = sizeof(int);
    switch(s) {
    case 2: data_typecode = NPY_INT16; break;
    case 4: data_typecode = NPY_INT32; break;
    case 8: data_typecode = NPY_INT64; break;
    }
    return data_typecode;
  }
 
  int getSizeOfPythonType(int type_num){
    switch (type_num){
    case NPY_INT16 : return 2;break;
    case NPY_UINT16: return 2;break;
    case NPY_INT32 : return 4;break;
    case NPY_UINT32: return 4;break;
    case NPY_INT64 : return 8;break;
    case NPY_UINT64: return 8;break;
    case NPY_FLOAT:  return sizeof(float);break;
    case NPY_DOUBLE:  return sizeof(double);break;
    case NPY_LONGDOUBLE:  return sizeof(long double);break;
    }
    return 0;
  }
 
  std::string getPythonTypeName(int type_num){
    switch (type_num){
    case NPY_INT16 : return "NPY_INT16" ;break;
    case NPY_UINT16: return "NPY_UINT16";break;
    case NPY_INT32 : return "NPY_INT32" ;break;
    case NPY_UINT32: return "NPY_UINT32";break;
    case NPY_INT64 : return "NPY_INT64" ;break;
    case NPY_UINT64: return "NPY_UINT64";break;
    case NPY_FLOAT:  return "NPY_FLOAT" ;break;
    case NPY_DOUBLE: return "NPY_DOUBLE";break;
    case NPY_LONGDOUBLE: return "NPY_LONGDOUBLE";break;
    }
    return 0;
  }
 
  template <typename T> void checkDataType(int type_num){
    AKANTU_DEBUG_ASSERT(type_num == getPythonDataTypeCode<T>(),
 		       "incompatible types between numpy and input function: " <<
 		       type_num << " != " << getPythonDataTypeCode<T>() << std::endl <<
 		       getSizeOfPythonType(type_num) << " != " << sizeof(T) <<
 		       std::endl <<
 		       "The numpy array is of type " << getPythonTypeName(type_num));
  }
 
  %}
 
 
 %define %akantu_array_typemaps(DATA_TYPE)
 
 %typemap(out, fragment="NumPy_Fragments") (akantu::Array< DATA_TYPE > &)
 {
 
   int data_typecode = getPythonDataTypeCode< DATA_TYPE >();
-  npy_intp dims[2] = {npy_intp($1->getSize()), npy_intp($1->getNbComponent())};
+  npy_intp dims[2] = {npy_intp($1->size()), npy_intp($1->getNbComponent())};
   PyObject* obj = PyArray_SimpleNewFromData(2, dims, data_typecode, $1->storage());
   PyArrayObject* array = (PyArrayObject*) obj;
   if (!array) SWIG_fail;
   $result = SWIG_Python_AppendOutput($result, obj);
 }
 
 %typemap(in) akantu::Array< DATA_TYPE > &
 {
   if (!PyArray_Check($input)) {
     AKANTU_EXCEPTION("incompatible input which is not a numpy");
   }
   else {
     PyArray_Descr * numpy_type = (PyArray_Descr*)PyArray_DESCR((PyArrayObject*)$input);
     int type_num = numpy_type->type_num;
     checkDataType< DATA_TYPE >(type_num);
     UInt _n = PyArray_NDIM((PyArrayObject*)$input);
     if (_n != 2) AKANTU_EXCEPTION("incompatible numpy dimension " << _n);
     npy_intp * ndims = PyArray_DIMS((PyArrayObject*)$input);
     akantu::UInt sz = ndims[0];
     akantu::UInt nb_components = ndims[1];
     PyArrayIterObject *iter = (PyArrayIterObject *)PyArray_IterNew($input);
     if (iter == NULL) AKANTU_EXCEPTION("Python internal error");
     $1 = new akantu::ArrayForPython< DATA_TYPE >((DATA_TYPE*)(iter->dataptr),sz,nb_components,"tmp_array_for_python");
   }
 }
 %enddef
 
 
 %akantu_array_typemaps(double      )
 %akantu_array_typemaps(float       )
 %akantu_array_typemaps(unsigned int)
 %akantu_array_typemaps(unsigned long)
 %akantu_array_typemaps(int         )
 %akantu_array_typemaps(bool        )
diff --git a/python/swig/aka_common.i b/python/swig/aka_common.i
index 95984de36..239a2fbc6 100644
--- a/python/swig/aka_common.i
+++ b/python/swig/aka_common.i
@@ -1,124 +1,125 @@
 /**
  * @file   aka_common.i
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 12 2014
  * @date last modification: Wed Jan 13 2016
  *
  * @brief  wrapper to aka_common.hh
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 %{
-  #include "aka_common.hh"
-  #include "aka_csr.hh"
-  #include "element.hh"
+#include "aka_common.hh"
+#include "aka_csr.hh"
+#include "element.hh"
 %}
 
 namespace akantu {
   %ignore getStaticParser;
   %ignore getUserParser;
+  %ignore ghost_types;
   %ignore initialize(int & argc, char ** & argv);
   %ignore initialize(const std::string & input_file, int & argc, char ** & argv);
   extern const Array<UInt> empty_filter;
 
 }
 
 %typemap(in) (int argc, char *argv[]) {
   int i = 0;
   if (!PyList_Check($input)) {
     PyErr_SetString(PyExc_ValueError, "Expecting a list");
     return NULL;
   }
 
   $1 = PyList_Size($input);
   $2 = new char *[$1+1];
 
   for (i = 0; i < $1; i++) {
     PyObject *s = PyList_GetItem($input,i);
     if (!PyString_Check(s)) {
         free($2);
         PyErr_SetString(PyExc_ValueError, "List items must be strings");
         return NULL;
     }
     $2[i] = PyString_AsString(s);
   }
   $2[i] = 0;
 }
 
 %typemap(freearg) (int argc, char *argv[]) {
 %#if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 %#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
 %#elif (defined(__GNUC__) || defined(__GNUG__))
 %#  if __cplusplus > 199711L
 %#    pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
 %#  endif
 %#endif
 
   delete [] $2;
 
 %#if defined(__INTEL_COMPILER)
 //#pragma warning ( disable : 383 )
 %#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
 %#elif (defined(__GNUC__) || defined(__GNUG__))
 %#  if __cplusplus > 199711L
 %#    pragma GCC diagnostic pop
 %#  endif
 %#endif
 }
 
 %inline %{
   namespace akantu {
 #if defined(AKANTU_USE_MPI)
     const int MPI=1;
 #else
     const int MPI=0;
 #endif
     void _initializeWithArgv(const std::string & input_file, int argc, char *argv[]) {
       initialize(input_file, argc, argv);
     }
   }
 %}
 
 %pythoncode %{
   import sys as _aka_sys
   def initialize(input_file="", argv=_aka_sys.argv):
       if _aka_sys.modules[__name__].MPI == 1:
          try:
            from mpi4py import MPI
          except ImportError:
            pass
 
       _initializeWithArgv(input_file, argv)
 
 %}
 
 %include "aka_config.hh"
 %include "aka_common.hh"
 %include "aka_element_classes_info.hh"
 %include "element.hh"
 
 
 
diff --git a/python/swig/material.i b/python/swig/material.i
index 904b44bfa..c1d3b152c 100644
--- a/python/swig/material.i
+++ b/python/swig/material.i
@@ -1,49 +1,50 @@
 /**
  * @file   material.i
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @brief  material wrapper
  *
  * @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 "solid_mechanics_model.hh"
   #include "material_python.hh"
 %}
 
 namespace akantu {
   %ignore Material::onNodesAdded;
   %ignore Material::onNodesRemoved;
   %ignore Material::onElementsAdded;
   %ignore Material::onElementsRemoved;
   %ignore Material::onElementsChanged;
+  %ignore Material::getParam;
 }
 
 %include "material.hh"
 
 
 %extend akantu::Material {
    Array<Real> & getArrayReal(const ID & id, const ElementType & type,
                               const GhostType & ghost_type = _not_ghost) {
       return $self->getArray<Real>(id, type, ghost_type);
    }
 }
diff --git a/python/swig/mesh.i b/python/swig/mesh.i
index 57ede82de..53b7e2561 100644
--- a/python/swig/mesh.i
+++ b/python/swig/mesh.i
@@ -1,177 +1,177 @@
 /**
  * @file   mesh.i
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 12 2014
  * @date last modification: Wed Jan 13 2016
  *
  * @brief  mesh wrapper
  *
  * @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"
 #include "node_group.hh"
 #include "solid_mechanics_model.hh"
 #include "dumpable_inline_impl.hh"
 
 using akantu::IntegrationPoint;
 using akantu::Vector;
 using akantu::ElementTypeMapArray;
 using akantu::MatrixProxy;
 using akantu::Matrix;
 using akantu::UInt;
 using akantu::Real;
 using akantu::Array;
 using akantu::SolidMechanicsModel;
 %}
 
 
 namespace akantu {
   %ignore NewNodesEvent;
   %ignore RemovedNodesEvent;
   %ignore NewElementsEvent;
   %ignore RemovedElementsEvent;
   %ignore MeshEventHandler;
   %ignore MeshEvent< UInt >;
   %ignore MeshEvent< Element >;
   %ignore Mesh::extractNodalCoordinatesFromPBCElement;
   %ignore Mesh::getGroupDumer;
   %ignore Mesh::getFacetLocalConnectivity;
   %ignore Mesh::getAllFacetTypes;
   %ignore Mesh::getCommunicator;
 }
 
 print_self(Mesh)
 
 // Swig considers enums to be ints, and it creates a conflict with two versions of getNbElement()
 %rename(getNbElementByDimension)
 akantu::Mesh::getNbElement(const UInt spatial_dimension = _all_dimensions,
                            const GhostType& ghost_type = _not_ghost,
                            const ElementKind& kind = _ek_not_defined) const;
 
 %extend akantu::Mesh {
 
   void resizeMesh(UInt nb_nodes, UInt nb_element, const ElementType & type) {
     Array<Real> & nodes = const_cast<Array<Real> &>($self->getNodes());
     nodes.resize(nb_nodes);
 
     $self->addConnectivityType(type);
     Array<UInt> & connectivity = const_cast<Array<UInt> &>($self->getConnectivity(type));
     connectivity.resize(nb_element);
   }
 
 #if defined(AKANTU_COHESIVE_ELEMENT)
   Array<Real> & getCohesiveBarycenter(SpacialDirection dir) {
     UInt spatial_dimension = $self->getSpatialDimension();
     ElementTypeMapArray<Real> & barycenter =
         $self->registerData<Real>("barycenter");
     $self->initElementTypeMapArray(barycenter, 1, spatial_dimension, false,
                                    akantu::_ek_cohesive, true);
     akantu::ElementType type = *($self->firstType(
         spatial_dimension, akantu::_not_ghost, akantu::_ek_cohesive));
 
     Vector<Real> bary(spatial_dimension);
     Array<Real> & bary_coh = barycenter(type);
     for (UInt i = 0; i < $self->getNbElement(type); ++i) {
       bary.clear();
       $self->getBarycenter(i, type, bary.storage());
       bary_coh(i) = bary(dir);
     }
     return bary_coh;
   }
 #endif
 }
 
 %extend akantu::GroupManager {
   void createGroupsFromStringMeshData(const std::string & dataset_name) {
     $self->createGroupsFromMeshData<std::string>(dataset_name);
   }
 
   void createGroupsFromUIntMeshData(const std::string & dataset_name) {
     $self->createGroupsFromMeshData<akantu::UInt>(dataset_name);
   }
 }
 
 %extend akantu::NodeGroup {
   akantu::Array<akantu::Real> & getGroupedNodes(akantu::Array<akantu::Real, true> & surface_array, Mesh & mesh) {
     akantu::Array<akantu::UInt> group_node = $self->getNodes();
     akantu::Array<akantu::Real> & full_array = mesh.getNodes();
-    surface_array.resize(group_node.getSize());
+    surface_array.resize(group_node.size());
 
-    for (UInt i = 0; i < group_node.getSize(); ++i) {
+    for (UInt i = 0; i < group_node.size(); ++i) {
       for (UInt cmp = 0; cmp < full_array.getNbComponent(); ++cmp) {
 
         surface_array(i,cmp) = full_array(group_node(i),cmp);
       }
     }
 
     akantu::Array<akantu::Real> & res(surface_array);
     return res;
   }
 
   akantu::Array<akantu::Real> & getGroupedArray(akantu::Array<akantu::Real, true> & surface_array, akantu::SolidMechanicsModel & model, int type) {
     akantu::Array<akantu::Real> * full_array;
 
     switch (type) {
 
     case 0 : full_array = new akantu::Array<akantu::Real>(model.getDisplacement());
       break;
     case 1 : full_array = new akantu::Array<akantu::Real>(model.getVelocity());
       break;
     case 2 : full_array = new akantu::Array<akantu::Real>(model.getForce());
       break;
     }
     akantu::Array<akantu::UInt> group_node = $self->getNodes();
-    surface_array.resize(group_node.getSize());
+    surface_array.resize(group_node.size());
 
-    for (UInt i = 0; i < group_node.getSize(); ++i) {
+    for (UInt i = 0; i < group_node.size(); ++i) {
       for (UInt cmp = 0; cmp < full_array->getNbComponent(); ++cmp) {
 
         surface_array(i,cmp) = (*full_array)(group_node(i),cmp);
       }
     }
 
     akantu::Array<akantu::Real> & res(surface_array);
     return res;
   }
 }
 
 %include "group_manager.hh"
 
 %include "element_group.hh"
 %include "node_group.hh"
 %include "dumper_iohelper.hh"
 %include "dumpable_iohelper.hh"
 %include "mesh.hh"
 
 namespace akantu{
 %extend Dumpable {
     void addDumpFieldExternalReal(const std::string & field_id,
                                   const Array<Real> & field){
       $self->addDumpFieldExternal<Real>(field_id,field);
     }
   }
  }
diff --git a/python/swig/mesh_utils.i b/python/swig/mesh_utils.i
index e5984ff34..31a551364 100644
--- a/python/swig/mesh_utils.i
+++ b/python/swig/mesh_utils.i
@@ -1,40 +1,43 @@
 /**
  * @file   mesh_utils.i
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 12 2014
  * @date last modification: Thu Jul 23 2015
  *
  * @brief  mesh_utils wrapper
  *
  * @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/>.
  *
  */
 
-namespace akantu {
-  %ignore MeshPartition::getPartitions;
-  %ignore MeshPartition::getPartition;
-  %ignore MeshPartition::getGhostPartitionCSR;
-}
+%{
+#include "mesh_utils.hh"
+%}
+/* namespace akantu { */
+/*   %ignore MeshPartition::getPartitions; */
+/*   %ignore MeshPartition::getPartition; */
+/*   %ignore MeshPartition::getGhostPartitionCSR; */
+/* } */
 
-%include "mesh_partition.hh"
+/* %include "mesh_partition.hh" */
 %include "mesh_utils.hh"
 
diff --git a/python/swig/model.i b/python/swig/model.i
index 8775f3504..d08eaa605 100644
--- a/python/swig/model.i
+++ b/python/swig/model.i
@@ -1,80 +1,85 @@
 /**
  * @file   model.i
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Aurelia Isabel Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 12 2014
  * @date last modification: Wed Nov 11 2015
  *
  * @brief  model wrapper
  *
  * @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 "boundary_condition_python_functor.hh"
 %}
 
 
 namespace akantu {
   %ignore Model::createSynchronizerRegistry;
+  %ignore Model::getSynchronizerRegistry;
   %ignore Model::createParallelSynch;
   %ignore Model::getDOFSynchronizer;
-  //%ignore Model::getSynchronizerRegistry;
   %ignore Model::registerFEEngineObject;
   %ignore Model::unregisterFEEngineObject;
   %ignore Model::getFEEngineBoundary;
   //  %ignore Model::getFEEngine;
   %ignore Model::getFEEngineClass;
   %ignore Model::getFEEngineClassBoundary;
   %ignore Model::setParser;
-
+  %ignore Model::updateDataForNonLocalCriterion;
   %ignore IntegrationPoint::operator=;
 
   %ignore FEEngine::getNbIntegrationPoints;
   %ignore FEEngine::getShapes;
   %ignore FEEngine::getShapesDerivatives;
   %ignore FEEngine::getIntegrationPoints;
   %ignore FEEngine::getIGFEMElementTypes;
   %ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,ElementTypeMapArray<Real> &,const ElementTypeMapArray<UInt> *) const;
   %ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,ElementTypeMapArray<Real> &) const;
   %ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,Array<Real> &,UInt,const ElementType&,const GhostType &,const Array< UInt > &) const;
   %ignore FEEngine::interpolateOnIntegrationPoints(const Array<Real> &,Array<Real> &,UInt,const ElementType&,const GhostType &) const;
-
+  %ignore FEEngine::onNodesAdded;
+  %ignore FEEngine::onNodesRemoved;
+  %ignore FEEngine::onElementsAdded;
+  %ignore FEEngine::onElementsChanged;
+  %ignore FEEngine::onElementsRemoved;
+  %ignore FEEngine::elementTypes;
 }
 
 %include "sparse_matrix.i"
 %include "fe_engine.hh"
 
 %rename(FreeBoundaryDirichlet) akantu::BC::Dirichlet::FreeBoundary;
 %rename(FreeBoundaryNeumann) akantu::BC::Neumann::FreeBoundary;
 %rename(PythonBoundary) akantu::BC::Dirichlet::PythonFunctor;
 
 %include "boundary_condition_functor.hh"
 %include "boundary_condition.hh"
 %include "boundary_condition_python_functor.hh"
 %include "communication_buffer.hh"
 %include "data_accessor.hh"
-%include "synchronizer.hh"
-%include "synchronizer_registry.hh"
+//%include "synchronizer.hh"
+//%include "synchronizer_registry.hh"
 %include "model.hh"
 
diff --git a/python/swig/solid_mechanics_model.i b/python/swig/solid_mechanics_model.i
index f9fe96049..492a77085 100644
--- a/python/swig/solid_mechanics_model.i
+++ b/python/swig/solid_mechanics_model.i
@@ -1,225 +1,204 @@
 /**
  * @file   solid_mechanics_model.i
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Fabian Barras <fabian.barras@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Fri Dec 12 2014
  * @date last modification: Wed Jan 06 2016
  *
  * @brief  solid mechanics model wrapper
  *
  * @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 "solid_mechanics_model.hh"
   #include "sparse_matrix.hh"
   #include "boundary_condition.hh"
   #include "boundary_condition_functor.hh"
   #include "boundary_condition_python_functor.hh"
   #include "material_selector.hh"
   #include "material_python.hh"
 %}
 
 namespace akantu {
   %ignore SolidMechanicsModel::initFEEngineBoundary;
   %ignore SolidMechanicsModel::initParallel;
   %ignore SolidMechanicsModel::initArrays;
   %ignore SolidMechanicsModel::initModel;
   %ignore SolidMechanicsModel::initPBC;
 
 
   ignore SolidMechanicsModel::initExplicit;
   %ignore SolidMechanicsModel::isExplicit;
   %ignore SolidMechanicsModel::updateCurrentPosition;
   %ignore SolidMechanicsModel::updateAcceleration;
   %ignore SolidMechanicsModel::updateIncrement;
   %ignore SolidMechanicsModel::updatePreviousDisplacement;
   %ignore SolidMechanicsModel::saveStressAndStrainBeforeDamage;
   %ignore SolidMechanicsModel::updateEnergiesAfterDamage;
   %ignore SolidMechanicsModel::solveLumped;
   %ignore SolidMechanicsModel::explicitPred;
   %ignore SolidMechanicsModel::explicitCorr;
 
   %ignore SolidMechanicsModel::initSolver;
   %ignore SolidMechanicsModel::initImplicit;
   %ignore SolidMechanicsModel::initialAcceleration;
 
 
   %ignore SolidMechanicsModel::testConvergence;
   %ignore SolidMechanicsModel::testConvergenceIncrement;
   %ignore SolidMechanicsModel::testConvergenceResidual;
   %ignore SolidMechanicsModel::initVelocityDampingMatrix;
 
   %ignore SolidMechanicsModel::getNbDataForElements;
   %ignore SolidMechanicsModel::packElementData;
   %ignore SolidMechanicsModel::unpackElementData;
   %ignore SolidMechanicsModel::getNbDataToPack;
   %ignore SolidMechanicsModel::getNbDataToUnpack;
   %ignore SolidMechanicsModel::packData;
   %ignore SolidMechanicsModel::unpackData;
 
   %ignore SolidMechanicsModel::setMaterialSelector;
   %ignore SolidMechanicsModel::getSolver;
   %ignore SolidMechanicsModel::getSynchronizer;
 
   %ignore Dumpable::registerExternalDumper;
   %ignore Material::onNodesAdded;
   %ignore Material::onNodesRemoved;
   %ignore Material::onElementsAdded;
   %ignore Material::onElementsRemoved;
   %ignore Material::onElementsChanged;
 }
 
 %template(SolidMechanicsBoundaryCondition) akantu::BoundaryCondition<akantu::SolidMechanicsModel>;
 
 %include "dumpable.hh"
 
 print_self(SolidMechanicsModel)
 
 %include "material.i"
 %include "solid_mechanics_model.hh"
 
 
+%inline %{
+  namespace akantu{
+    void registerNewPythonMaterial(PyObject * obj, const akantu::ID & mat_type) {
+
+
+      MaterialFactory::getInstance().registerAllocator(
+          mat_type,
+          [obj](UInt, const ID &, SolidMechanicsModel & model,
+                const ID & id) -> std::unique_ptr<Material>
+          {
+            return std::make_unique<MaterialPython>(model, obj, id);
+          }
+        );
+    }
+  }
+%}
+
 %extend akantu::SolidMechanicsModel {
 
   /* ------------------------------------------------------------------------ */
   void setPhysicalNamesMaterialSelector(){
     akantu::MeshDataMaterialSelector<std::string> * selector = new
       akantu::MeshDataMaterialSelector<std::string>("physical_names", *self);
     self->setMaterialSelector(*selector);
   }
   
   /* ------------------------------------------------------------------------ */
-  bool testConvergenceSccRes(Real tolerance) {
-    Real error = 0;
-    bool res = self->testConvergence<akantu::_scc_residual>(tolerance, error);
-    return res;
+  void getResidual() {
+    AKANTU_EXCEPTION("Deprecated function. You should replace:\n"
+                     "model.getResidual()\n"
+                     "with\n"
+                     "model.getInternalForce()\n");
   }
 
-  /* ------------------------------------------------------------------------ */
-  void solveStaticDisplacement(Real tolerance, UInt max_iteration) {
-    $self->solveStatic<akantu::_scm_newton_raphson_tangent_not_computed,
-                       akantu::_scc_residual>(tolerance, max_iteration);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  /// register an empty material of a given type
   void registerNewPythonMaterial(PyObject * obj, const akantu::ID & mat_type) {
-    std::pair<akantu::Parser::const_section_iterator,
-              akantu::Parser::const_section_iterator>
-        sub_sect = akantu::getStaticParser().getSubSections(akantu::_st_material);
-
-    akantu::Parser::const_section_iterator it = sub_sect.first;
-    for (; it != sub_sect.second; ++it) {
-      if (it->getName() == mat_type) {
-
-        AKANTU_DEBUG_ASSERT($self->materials_names_to_id.find(mat_type) ==
-                            $self->materials_names_to_id.end(),
-                            "A material with this name '"
-                            << mat_type << "' has already been registered. "
-                            << "Please use unique names for materials");
-
-        UInt mat_count = $self->materials.size();
-        $self->materials_names_to_id[mat_type] = mat_count;
-
-        std::stringstream sstr_mat;
-        sstr_mat << $self->getID() << ":" << mat_count << ":" << mat_type;
-        akantu::ID mat_id = sstr_mat.str();
-
-        akantu::Material * material = new akantu::MaterialPython(*$self, obj, mat_id);
-        $self->materials.push_back(material);
-
-        material->parseSection(*it);
-      }
-    }
+    AKANTU_EXCEPTION("Deprecated function. You should replace:\n"
+                     "model.registerNewPythonMaterial(obj, mat_id)\n"
+                     "with\n"
+                     "akantu.registerNewPythonMaterial(obj, mat_id)\n\n"
+                     "This MUST be done before instanciating the model.");
+
+      /* std::pair<akantu::Parser::const_section_iterator, */
+    /*           akantu::Parser::const_section_iterator> */
+    /*     sub_sect = akantu::getStaticParser().getSubSections(akantu::_st_material); */
+
+    /* akantu::Parser::const_section_iterator it = sub_sect.first; */
+    /* for (; it != sub_sect.second; ++it) { */
+    /*   if (it->getName() == mat_type) { */
+
+    /*     AKANTU_DEBUG_ASSERT($self->materials_names_to_id.find(mat_type) == */
+    /*                         $self->materials_names_to_id.end(), */
+    /*                         "A material with this name '" */
+    /*                         << mat_type << "' has already been registered. " */
+    /*                         << "Please use unique names for materials"); */
+
+    /*     UInt mat_count = $self->materials.size(); */
+    /*     $self->materials_names_to_id[mat_type] = mat_count; */
+
+    /*     std::stringstream sstr_mat; */
+    /*     sstr_mat << $self->getID() << ":" << mat_count << ":" << mat_type; */
+    /*     akantu::ID mat_id = sstr_mat.str(); */
+
+    /*     akantu::Material * material = new akantu::MaterialPython(*$self, obj, mat_id); */
+    /*     $self->materials.push_back(material); */
+
+    /*     material->parseSection(*it); */
+    /*   } */
+    /* } */
   }
 
   /* ------------------------------------------------------------------------ */
   void applyDirichletBC(PyObject * func_obj, const std::string & group_name) {
     akantu::BC::PythonFunctorDirichlet functor(func_obj);
     $self->applyBC(functor, group_name);
   }
 
   /* ------------------------------------------------------------------------ */
   void applyNeumannBC(PyObject * func_obj, const std::string & group_name) {
     akantu::BC::PythonFunctorNeumann functor(func_obj);
     $self->applyBC(functor, group_name);
   }
 
-  /* ------------------------------------------------------------------------ */
-  void solveDisplCorr(bool need_factorize, bool has_profile_changed) {
-    akantu::Array<akantu::Real> & increment = $self->getIncrement();
-
-    $self->solve<akantu::IntegrationScheme2ndOrder::_displacement_corrector>(
-        increment, 1., need_factorize, has_profile_changed);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  void clearDispl() {
-    akantu::Array<akantu::Real> & displ = $self->getDisplacement();
-    displ.clear();
-  }
-
-  /* ------------------------------------------------------------------------ */
-  void solveStep_TgModifIncr(Real tolerance, UInt max_iteration) {
-    $self->solveStep<akantu::_scm_newton_raphson_tangent_modified,
-                     akantu::_scc_increment>(tolerance, max_iteration);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  void solveStep_TgIncr(Real tolerance, Real & error, UInt max_iteration) {
-    
-    $self->solveStep<akantu::_scm_newton_raphson_tangent,
-      akantu::_scc_increment>(tolerance, error, max_iteration);
-  }
-
-  /* ------------------------------------------------------------------------ */
-  void clearDisplVeloAcc() {
-    akantu::Array<akantu::Real> & displ = $self->getDisplacement();
-    akantu::Array<akantu::Real> & velo = $self->getVelocity();
-    akantu::Array<akantu::Real> & acc = $self->getAcceleration();
-
-    displ.clear();
-    velo.clear();
-    acc.clear();
-  }
-
   /* ------------------------------------------------------------------------ */
   void applyUniformPressure(Real pressure, const std::string surface_name) {
     UInt spatial_dimension = $self->getSpatialDimension();
     akantu::Matrix<akantu::Real> surface_stress(spatial_dimension,
                                                 spatial_dimension, 0.0);
 
     for (UInt i = 0; i < spatial_dimension; ++i) {
       surface_stress(i, i) = -pressure;
     }
     $self->applyBC(akantu::BC::Neumann::FromStress(surface_stress),
                    surface_name);
   }
 
   /* ------------------------------------------------------------------------ */
   void blockDOF(const std::string surface_name, SpacialDirection direction) {
     $self->applyBC(akantu::BC::Dirichlet::FixedValue(0.0, direction),
                    surface_name);
   }
 }
+
diff --git a/python/swig/sparse_matrix.i b/python/swig/sparse_matrix.i
index 50acfc688..f3c2dc6b0 100644
--- a/python/swig/sparse_matrix.i
+++ b/python/swig/sparse_matrix.i
@@ -1,34 +1,34 @@
 
 
 %include "sparse_matrix.hh"
 
 %pythoncode %{
 import scipy.sparse
 import numpy as _np    
 class AkantuSparseMatrix (scipy.sparse.coo_matrix) :
 
     def __init__(self,aka_sparse):
         
         self.aka_sparse = aka_sparse
         matrix_type = self.aka_sparse.getSparseMatrixType()
-        sz = self.aka_sparse.getSize()
+        sz = self.aka_sparse.size()
         row = self.aka_sparse.getIRN()[:,0] -1
         col = self.aka_sparse.getJCN()[:,0] -1
         data = self.aka_sparse.getA()[:,0]
 
         row = row.copy()
         col = col.copy()
         data = data.copy()
 
         if matrix_type == _symmetric:
             non_diags = (row != col)
             row_sup = col[non_diags]
             col_sup = row[non_diags]
             data_sup = data[non_diags]
             col  = _np.concatenate((col,col_sup))
             row  = _np.concatenate((row,row_sup))
             data = _np.concatenate((data,data_sup))
        
         scipy.sparse.coo_matrix.__init__(self,(data, (row,col)),shape=(sz,sz))
 
 %}
diff --git a/src/common/aka_array_tmpl.hh b/src/common/aka_array_tmpl.hh
index 90c468ab8..97fefce38 100644
--- a/src/common/aka_array_tmpl.hh
+++ b/src/common/aka_array_tmpl.hh
@@ -1,1275 +1,1279 @@
 /**
  * @file   aka_array_tmpl.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Thu Jul 15 2010
  * @date last modification: Fri Jan 22 2016
  *
  * @brief  Inline functions of the classes Array<T> and ArrayBase
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 /* Inline Functions Array<T>                                                 */
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 /* -------------------------------------------------------------------------- */
 #include <memory>
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_ARRAY_TMPL_HH__
 #define __AKANTU_AKA_ARRAY_TMPL_HH__
 
 namespace akantu {
 
 namespace debug {
   struct ArrayException : public Exception {};
 } // namespace debug
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 inline T & Array<T, is_scal>::operator()(UInt i, UInt j) {
   AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < size_) && (j < nb_component),
                       "The value at position ["
                           << i << "," << j << "] is out of range in array \""
                           << id << "\"");
   return values[i * nb_component + j];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 inline const T & Array<T, is_scal>::operator()(UInt i, UInt j) const {
   AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < size_) && (j < nb_component),
                       "The value at position ["
                           << i << "," << j << "] is out of range in array \""
                           << id << "\"");
   return values[i * nb_component + j];
 }
 
 template <class T, bool is_scal>
 inline T & Array<T, is_scal>::operator[](UInt i) {
   AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < size_ * nb_component),
                       "The value at position ["
                           << i << "] is out of range in array \"" << id
                           << "\"");
   return values[i];
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 inline const T & Array<T, is_scal>::operator[](UInt i) const {
   AKANTU_DEBUG_ASSERT(size_ > 0, "The array \"" << id << "\" is empty");
   AKANTU_DEBUG_ASSERT((i < size_ * nb_component),
                       "The value at position ["
                           << i << "] is out of range in array \"" << id
                           << "\"");
   return values[i];
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * append a tuple to the array with the value value for all components
  * @param value the new last tuple or the array will contain nb_component copies
  * of value
  */
 template <class T, bool is_scal>
 inline void Array<T, is_scal>::push_back(const T & value) {
   resizeUnitialized(size_ + 1, true, value);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * append a tuple to the array
  * @param new_elem a C-array containing the values to be copied to the end of
  * the array */
 // template <class T, bool is_scal>
 // inline void Array<T, is_scal>::push_back(const T new_elem[]) {
 //   UInt pos = size_;
 
 //   resizeUnitialized(size_ + 1, false);
 
 //   T * tmp = values + nb_component * pos;
 //   std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
 // }
 
 /* -------------------------------------------------------------------------- */
 #ifndef SWIG
 /**
  * append a matrix or a vector to the array
  * @param new_elem a reference to a Matrix<T> or Vector<T> */
 template <class T, bool is_scal>
 template <template <typename> class C, typename>
 inline void Array<T, is_scal>::push_back(const C<T> & new_elem) {
   AKANTU_DEBUG_ASSERT(
       nb_component == new_elem.size(),
       "The vector("
           << new_elem.size()
           << ") as not a size compatible with the Array (nb_component="
           << nb_component << ").");
   UInt pos = size_;
   resizeUnitialized(size_ + 1, false);
 
   T * tmp = values + nb_component * pos;
   std::uninitialized_copy(new_elem.storage(), new_elem.storage() + nb_component,
                           tmp);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * append a tuple to the array
  * @param it an iterator to the tuple to be copied to the end of the array */
 template <class T, bool is_scal>
 template <class Ret>
 inline void
 Array<T, is_scal>::push_back(const Array<T, is_scal>::iterator<Ret> & it) {
   UInt pos = size_;
 
   resizeUnitialized(size_ + 1, false);
 
   T * tmp = values + nb_component * pos;
   T * new_elem = it.data();
   std::uninitialized_copy(new_elem, new_elem + nb_component, tmp);
 }
 #endif
 /* -------------------------------------------------------------------------- */
 /**
  * erase an element. If the erased element is not the last of the array, the
  * last element is moved into the hole in order to maintain contiguity. This
  * may invalidate existing iterators (For instance an iterator obtained by
  * Array::end() is no longer correct) and will change the order of the
  * elements.
  * @param i index of element to erase
  */
 template <class T, bool is_scal> inline void Array<T, is_scal>::erase(UInt i) {
   AKANTU_DEBUG_IN();
   AKANTU_DEBUG_ASSERT((size_ > 0), "The array is empty");
   AKANTU_DEBUG_ASSERT((i < size_),
                       "The element at position [" << i << "] is out of range ("
                                                   << i << ">=" << size_ << ")");
 
   if (i != (size_ - 1)) {
     for (UInt j = 0; j < nb_component; ++j) {
       values[i * nb_component + j] = values[(size_ - 1) * nb_component + j];
     }
   }
 
   resize(size_ - 1);
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Subtract another array entry by entry from this array in place. Both arrays
  * must
  * have the same size and nb_component. If the arrays have different shapes,
  * code compiled in debug mode will throw an expeption and optimised code
  * will behave in an unpredicted manner
  * @param other array to subtract from this
  * @return reference to modified this
  */
 template <class T, bool is_scal>
 Array<T, is_scal> & Array<T, is_scal>::
 operator-=(const Array<T, is_scal> & vect) {
   AKANTU_DEBUG_ASSERT((size_ == vect.size_) &&
                           (nb_component == vect.nb_component),
                       "The too array don't have the same sizes");
 
   T * a = values;
   T * b = vect.storage();
   for (UInt i = 0; i < size_ * nb_component; ++i) {
     *a -= *b;
     ++a;
     ++b;
   }
 
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Add another array entry by entry to this array in place. Both arrays must
  * have the same size and nb_component. If the arrays have different shapes,
  * code compiled in debug mode will throw an expeption and optimised code
  * will behave in an unpredicted manner
  * @param other array to add to this
  * @return reference to modified this
  */
 template <class T, bool is_scal>
 Array<T, is_scal> & Array<T, is_scal>::
 operator+=(const Array<T, is_scal> & vect) {
-  AKANTU_DEBUG_ASSERT((size_ == vect.size) &&
+  AKANTU_DEBUG_ASSERT((size_ == vect.size()) &&
                           (nb_component == vect.nb_component),
                       "The too array don't have the same sizes");
 
   T * a = values;
   T * b = vect.storage();
   for (UInt i = 0; i < size_ * nb_component; ++i) {
     *a++ += *b++;
   }
 
   return *this;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * Multiply all entries of this array by a scalar in place
  * @param alpha scalar multiplicant
  * @return reference to modified this
  */
+
+#ifndef SWIG
 template <class T, bool is_scal>
 Array<T, is_scal> & Array<T, is_scal>::operator*=(const T & alpha) {
   T * a = values;
   for (UInt i = 0; i < size_ * nb_component; ++i) {
     *a++ *= alpha;
   }
 
   return *this;
 }
+#endif
+
 
 /* -------------------------------------------------------------------------- */
 /**
  * Compare this array element by element to another.
  * @param other array to compare to
  * @return true it all element are equal and arrays have the same shape, else
  * false
  */
 template <class T, bool is_scal>
 bool Array<T, is_scal>::operator==(const Array<T, is_scal> & array) const {
   bool equal = nb_component == array.nb_component && size_ == array.size_ &&
                id == array.id;
   if (!equal)
     return false;
 
   if (values == array.storage())
     return true;
   else
     return std::equal(values, values + size_ * nb_component, array.storage());
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 bool Array<T, is_scal>::operator!=(const Array<T, is_scal> & array) const {
   return !operator==(array);
 }
 
 /* -------------------------------------------------------------------------- */
 #ifndef SWIG
 /**
  * set all tuples of the array to a given vector or matrix
  * @param vm Matrix or Vector to fill the array with
  */
 template <class T, bool is_scal>
 template <template <typename> class C, typename>
 inline void Array<T, is_scal>::set(const C<T> & vm) {
   AKANTU_DEBUG_ASSERT(
       nb_component == vm.size(),
       "The size of the object does not match the number of components");
   for (T * it = values; it < values + nb_component * size_;
        it += nb_component) {
     std::copy(vm.storage(), vm.storage() + nb_component, it);
   }
 }
 #endif
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 void Array<T, is_scal>::append(const Array<T> & other) {
   AKANTU_DEBUG_ASSERT(
       nb_component == other.nb_component,
       "Cannot append an array with a different number of component");
   UInt old_size = this->size_;
   this->resizeUnitialized(this->size_ + other.size(), false);
 
   T * tmp = values + nb_component * old_size;
   std::uninitialized_copy(other.storage(),
                           other.storage() + other.size() * nb_component, tmp);
 }
 
 /* -------------------------------------------------------------------------- */
 /* Functions Array<T, is_scal>                                                */
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(UInt size, UInt nb_component, const ID & id)
     : ArrayBase(id), values(nullptr) {
   AKANTU_DEBUG_IN();
   allocate(size, nb_component);
 
   if (!is_scal) {
     T val = T();
     std::uninitialized_fill(values, values + size * nb_component, val);
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(UInt size, UInt nb_component, const T def_values[],
                          const ID & id)
     : ArrayBase(id), values(NULL) {
   AKANTU_DEBUG_IN();
   allocate(size, nb_component);
 
   T * tmp = values;
 
   for (UInt i = 0; i < size; ++i) {
     tmp = values + nb_component * i;
     std::uninitialized_copy(def_values, def_values + nb_component, tmp);
   }
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(UInt size, UInt nb_component, const T & value,
                          const ID & id)
     : ArrayBase(id), values(nullptr) {
   AKANTU_DEBUG_IN();
   allocate(size, nb_component);
 
   std::uninitialized_fill_n(values, size * nb_component, value);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(const Array<T, is_scal> & vect, bool deep,
                          const ID & id)
     : ArrayBase(vect) {
   AKANTU_DEBUG_IN();
   this->id = (id == "") ? vect.id : id;
 
   if (deep) {
     allocate(vect.size_, vect.nb_component);
     T * tmp = values;
     std::uninitialized_copy(vect.storage(),
                             vect.storage() + size_ * nb_component, tmp);
   } else {
     this->values = vect.storage();
     this->size_ = vect.size_;
     this->nb_component = vect.nb_component;
     this->allocated_size = vect.allocated_size;
     this->size_of_type = vect.size_of_type;
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 #ifndef SWIG
 template <class T, bool is_scal>
 Array<T, is_scal>::Array(const std::vector<T> & vect) {
   AKANTU_DEBUG_IN();
   this->id = "";
 
   allocate(vect.size(), 1);
   T * tmp = values;
   std::uninitialized_copy(&(vect[0]), &(vect[size_ - 1]), tmp);
 
   AKANTU_DEBUG_OUT();
 }
 #endif
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal> Array<T, is_scal>::~Array() {
   AKANTU_DEBUG_IN();
   AKANTU_DEBUG(dblAccessory,
                "Freeing " << printMemorySize<T>(allocated_size * nb_component)
                           << " (" << id << ")");
 
   if (values) {
     if (!is_scal)
       for (UInt i = 0; i < size_ * nb_component; ++i) {
         T * obj = values + i;
         obj->~T();
       }
     free(values);
   }
   size_ = allocated_size = 0;
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * perform the allocation for the constructors
  * @param size is the size of the array
  * @param nb_component is the number of component of the array
  */
 template <class T, bool is_scal>
 void Array<T, is_scal>::allocate(UInt size, UInt nb_component) {
   AKANTU_DEBUG_IN();
   if (size == 0) {
     values = nullptr;
   } else {
     values = static_cast<T *>(malloc(nb_component * size * sizeof(T)));
     AKANTU_DEBUG_ASSERT(values != nullptr,
                         "Cannot allocate "
                             << printMemorySize<T>(size * nb_component) << " ("
                             << id << ")");
   }
 
   if (values == nullptr) {
     this->size_ = this->allocated_size = 0;
   } else {
     AKANTU_DEBUG(dblAccessory,
                  "Allocated " << printMemorySize<T>(size * nb_component) << " ("
                               << id << ")");
     this->size_ = this->allocated_size = size;
   }
 
   this->size_of_type = sizeof(T);
   this->nb_component = nb_component;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 void Array<T, is_scal>::reserve(UInt new_size) {
   UInt tmp_size = this->size_;
   resizeUnitialized(new_size, false);
   this->size_ = tmp_size;
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * change the size of the array and allocate or free memory if needed. If the
  * size increases, the new tuples are filled with zeros
  * @param new_size new number of tuples contained in the array */
 template <class T, bool is_scal> void Array<T, is_scal>::resize(UInt new_size) {
   resizeUnitialized(new_size, !is_scal);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * change the size of the array and allocate or free memory if needed. If the
  * size increases, the new tuples are filled with zeros
  * @param new_size new number of tuples contained in the array */
 template <class T, bool is_scal>
 void Array<T, is_scal>::resize(UInt new_size, const T & val) {
   this->resizeUnitialized(new_size, true, val);
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * change the size of the array and allocate or free memory if needed.
  * @param new_size new number of tuples contained in the array */
 template <class T, bool is_scal>
 void Array<T, is_scal>::resizeUnitialized(UInt new_size, bool fill,
                                           const T & val) {
   //  AKANTU_DEBUG_IN();
   // free some memory
   if (new_size <= allocated_size) {
     if (!is_scal) {
       T * old_values = values;
       if (new_size < size_) {
         for (UInt i = new_size * nb_component; i < size_ * nb_component; ++i) {
           T * obj = old_values + i;
           obj->~T();
         }
       }
     }
 
     if (allocated_size - new_size > AKANTU_MIN_ALLOCATION) {
       AKANTU_DEBUG(dblAccessory,
                    "Freeing " << printMemorySize<T>((allocated_size - size_) *
                                                     nb_component)
                               << " (" << id << ")");
 
       // Normally there are no allocation problem when reducing an array
       if (new_size == 0) {
         free(values);
         values = nullptr;
       } else {
         auto * tmp_ptr = static_cast<T *>(
             realloc(values, new_size * nb_component * sizeof(T)));
 
         if (tmp_ptr == nullptr) {
           AKANTU_EXCEPTION("Cannot free data ("
                            << id << ")"
                            << " [current allocated size : " << allocated_size
                            << " | "
                            << "requested size : " << new_size << "]");
         }
         values = tmp_ptr;
       }
       allocated_size = new_size;
     }
   } else {
     // allocate more memory
     UInt size_to_alloc = (new_size - allocated_size < AKANTU_MIN_ALLOCATION)
                              ? allocated_size + AKANTU_MIN_ALLOCATION
                              : new_size;
 
     auto * tmp_ptr = static_cast<T *>(
         realloc(values, size_to_alloc * nb_component * sizeof(T)));
     AKANTU_DEBUG_ASSERT(
         tmp_ptr != nullptr,
         "Cannot allocate " << printMemorySize<T>(size_to_alloc * nb_component));
     if (tmp_ptr == nullptr) {
       AKANTU_DEBUG_ERROR("Cannot allocate more data ("
                          << id << ")"
                          << " [current allocated size : " << allocated_size
                          << " | "
                          << "requested size : " << new_size << "]");
     }
 
     AKANTU_DEBUG(dblAccessory,
                  "Allocating " << printMemorySize<T>(
                      (size_to_alloc - allocated_size) * nb_component));
 
     allocated_size = size_to_alloc;
     values = tmp_ptr;
   }
 
   if (fill && this->size_ < new_size) {
     std::uninitialized_fill(values + size_ * nb_component,
                             values + new_size * nb_component, val);
   }
 
   size_ = new_size;
   //  AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * change the number of components by interlacing data
  * @param multiplicator number of interlaced components add
  * @param block_size blocks of data in the array
  * Examaple for block_size = 2, multiplicator = 2
  * array = oo oo oo -> new array = oo nn nn oo nn nn oo nn nn */
 template <class T, bool is_scal>
 void Array<T, is_scal>::extendComponentsInterlaced(UInt multiplicator,
                                                    UInt block_size) {
   AKANTU_DEBUG_IN();
 
   if (multiplicator == 1)
     return;
 
   AKANTU_DEBUG_ASSERT(multiplicator > 1, "invalid multiplicator");
   AKANTU_DEBUG_ASSERT(nb_component % block_size == 0,
                       "stride must divide actual number of components");
 
   values = static_cast<T *>(
       realloc(values, nb_component * multiplicator * size_ * sizeof(T)));
 
   UInt new_component = nb_component / block_size * multiplicator;
 
   for (UInt i = 0, k = size_ - 1; i < size_; ++i, --k) {
     for (UInt j = 0; j < new_component; ++j) {
       UInt m = new_component - j - 1;
       UInt n = m / multiplicator;
       for (UInt l = 0, p = block_size - 1; l < block_size; ++l, --p) {
         values[k * nb_component * multiplicator + m * block_size + p] =
             values[k * nb_component + n * block_size + p];
       }
     }
   }
 
   nb_component = nb_component * multiplicator;
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * search elem in the array, return  the position of the first occurrence or
  * -1 if not found
  *  @param elem the element to look for
  *  @return index of the first occurrence of elem or -1 if elem is not present
  */
 template <class T, bool is_scal>
 UInt Array<T, is_scal>::find(const T & elem) const {
   AKANTU_DEBUG_IN();
 
   auto begin = this->begin();
   auto end = this->end();
   auto it = std::find(begin, end, elem);
 
   AKANTU_DEBUG_OUT();
   return (it != end) ? it - begin : UInt(-1);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal> UInt Array<T, is_scal>::find(T elem[]) const {
   AKANTU_DEBUG_IN();
   T * it = values;
   UInt i = 0;
   for (; i < size_; ++i) {
     if (*it == elem[0]) {
       T * cit = it;
       UInt c = 0;
       for (; (c < nb_component) && (*cit == elem[c]); ++c, ++cit)
         ;
       if (c == nb_component) {
         AKANTU_DEBUG_OUT();
         return i;
       }
     }
     it += nb_component;
   }
   return UInt(-1);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <template <typename> class C, typename>
 inline UInt Array<T, is_scal>::find(const C<T> & elem) {
   AKANTU_DEBUG_ASSERT(elem.size() == nb_component,
                       "Cannot find an element with a wrong size ("
                           << elem.size() << ") != " << nb_component);
   return this->find(elem.storage());
 }
 
 /* -------------------------------------------------------------------------- */
 /**
  * copy the content of another array. This overwrites the current content.
  * @param other Array to copy into this array. It has to have the same
  * nb_component as this. If compiled in debug mode, an incorrect other will
  * result in an exception being thrown. Optimised code may result in
  * unpredicted behaviour.
  */
 template <class T, bool is_scal>
 void Array<T, is_scal>::copy(const Array<T, is_scal> & vect,
                              bool no_sanity_check) {
   AKANTU_DEBUG_IN();
 
   if (!no_sanity_check)
     if (vect.nb_component != nb_component)
       AKANTU_DEBUG_ERROR(
           "The two arrays do not have the same number of components");
 
   resize((vect.size_ * vect.nb_component) / nb_component);
 
   T * tmp = values;
   std::uninitialized_copy(vect.storage(), vect.storage() + size_ * nb_component,
                           tmp);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template <bool is_scal> class ArrayPrintHelper {
 public:
   template <typename T>
   static void print_content(const Array<T> & vect, std::ostream & stream,
                             int indent) {
     if (AKANTU_DEBUG_TEST(dblDump) || AKANTU_DEBUG_LEVEL_IS_TEST()) {
       std::string space;
       for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
         ;
 
       stream << space << " + values         : {";
       for (UInt i = 0; i < vect.size(); ++i) {
         stream << "{";
         for (UInt j = 0; j < vect.getNbComponent(); ++j) {
           stream << vect(i, j);
           if (j != vect.getNbComponent() - 1)
             stream << ", ";
         }
         stream << "}";
         if (i != vect.size() - 1)
           stream << ", ";
       }
       stream << "}" << std::endl;
     }
   }
 };
 
 template <> class ArrayPrintHelper<false> {
 public:
   template <typename T>
   static void print_content(__attribute__((unused)) const Array<T> & vect,
                             __attribute__((unused)) std::ostream & stream,
                             __attribute__((unused)) int indent) {}
 };
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 void Array<T, is_scal>::printself(std::ostream & stream, int indent) const {
   std::string space;
   for (Int i = 0; i < indent; i++, space += AKANTU_INDENT)
     ;
 
   std::streamsize prec = stream.precision();
   std::ios_base::fmtflags ff = stream.flags();
 
   stream.setf(std::ios_base::showbase);
   stream.precision(2);
 
   stream << space << "Array<" << debug::demangle(typeid(T).name()) << "> ["
          << std::endl;
   stream << space << " + id             : " << this->id << std::endl;
   stream << space << " + size           : " << this->size_ << std::endl;
   stream << space << " + nb_component   : " << this->nb_component << std::endl;
   stream << space << " + allocated size : " << this->allocated_size
          << std::endl;
   stream << space << " + memory size    : "
          << printMemorySize<T>(allocated_size * nb_component) << std::endl;
   if (!AKANTU_DEBUG_LEVEL_IS_TEST())
     stream << space << " + address        : " << std::hex << this->values
            << std::dec << std::endl;
 
   stream.precision(prec);
   stream.flags(ff);
 
   ArrayPrintHelper<is_scal>::print_content(*this, stream, indent);
 
   stream << space << "]" << std::endl;
 }
 
 /* -------------------------------------------------------------------------- */
 /* Inline Functions ArrayBase                                                */
 /* -------------------------------------------------------------------------- */
 
 inline UInt ArrayBase::getMemorySize() const {
   return allocated_size * nb_component * size_of_type;
 }
 
 inline void ArrayBase::empty() { size_ = 0; }
 
 #ifndef SWIG
 /* -------------------------------------------------------------------------- */
 /* Iterators                                                                  */
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <class R, class daughter, class IR, bool is_tensor>
 class Array<T, is_scal>::iterator_internal {
 public:
   using value_type = R;
   using pointer = R *;
   using reference = R &;
   using proxy = typename R::proxy;
   using const_proxy = const typename R::proxy;
   using const_reference = const R &;
   using internal_value_type = IR;
   using internal_pointer = IR *;
   using difference_type = std::ptrdiff_t;
   using iterator_category = std::random_access_iterator_tag;
 
 public:
   iterator_internal() = default;
 
   iterator_internal(pointer_type data, UInt _offset)
       : _offset(_offset), initial(data), ret(nullptr), ret_ptr(data) {
     AKANTU_DEBUG_ERROR(
         "The constructor should never be called it is just an ugly trick...");
   }
 
   iterator_internal(std::unique_ptr<internal_value_type> && wrapped)
       : _offset(wrapped->size()), initial(wrapped->storage()),
         ret(std::move(wrapped)), ret_ptr(ret->storage()) {}
 
   iterator_internal(const iterator_internal & it) {
     if (this != &it) {
       this->_offset = it._offset;
       this->initial = it.initial;
       this->ret_ptr = it.ret_ptr;
       this->ret = std::make_unique<internal_value_type>(*it.ret, false);
     }
   }
 
   iterator_internal(iterator_internal && it) = default;
 
   virtual ~iterator_internal() = default;
 
   inline iterator_internal & operator=(const iterator_internal & it) {
     if (this != &it) {
       this->_offset = it._offset;
       this->initial = it.initial;
       this->ret_ptr = it.ret_ptr;
       if (this->ret)
         this->ret->shallowCopy(*it.ret);
       else
         this->ret = std::make_unique<internal_value_type>(*it.ret, false);
     }
     return *this;
   }
 
   UInt getCurrentIndex() {
     return (this->ret_ptr - this->initial) / this->_offset;
   };
 
   inline reference operator*() {
     ret->values = ret_ptr;
     return *ret;
   };
   inline const_reference operator*() const {
     ret->values = ret_ptr;
     return *ret;
   };
   inline pointer operator->() {
     ret->values = ret_ptr;
     return ret.get();
   };
   inline daughter & operator++() {
     ret_ptr += _offset;
     return static_cast<daughter &>(*this);
   };
   inline daughter & operator--() {
     ret_ptr -= _offset;
     return static_cast<daughter &>(*this);
   };
 
   inline daughter & operator+=(const UInt n) {
     ret_ptr += _offset * n;
     return static_cast<daughter &>(*this);
   }
   inline daughter & operator-=(const UInt n) {
     ret_ptr -= _offset * n;
     return static_cast<daughter &>(*this);
   }
 
   inline proxy operator[](const UInt n) {
     ret->values = ret_ptr + n * _offset;
     return proxy(*ret);
   }
   inline const_proxy operator[](const UInt n) const {
     ret->values = ret_ptr + n * _offset;
     return const_proxy(*ret);
   }
 
   inline bool operator==(const iterator_internal & other) const {
     return this->ret_ptr == other.ret_ptr;
   }
   inline bool operator!=(const iterator_internal & other) const {
     return this->ret_ptr != other.ret_ptr;
   }
   inline bool operator<(const iterator_internal & other) const {
     return this->ret_ptr < other.ret_ptr;
   }
   inline bool operator<=(const iterator_internal & other) const {
     return this->ret_ptr <= other.ret_ptr;
   }
   inline bool operator>(const iterator_internal & other) const {
     return this->ret_ptr > other.ret_ptr;
   }
   inline bool operator>=(const iterator_internal & other) const {
     return this->ret_ptr >= other.ret_ptr;
   }
 
   inline daughter operator+(difference_type n) {
     daughter tmp(static_cast<daughter &>(*this));
     tmp += n;
     return tmp;
   }
   inline daughter operator-(difference_type n) {
     daughter tmp(static_cast<daughter &>(*this));
     tmp -= n;
     return tmp;
   }
 
   inline difference_type operator-(const iterator_internal & b) {
     return (this->ret_ptr - b.ret_ptr) / _offset;
   }
 
   inline pointer_type data() const { return ret_ptr; }
   inline difference_type offset() const { return _offset; }
 
 protected:
   UInt _offset{0};
   pointer_type initial{nullptr};
   std::unique_ptr<internal_value_type> ret{nullptr};
   pointer_type ret_ptr{nullptr};
 };
 
 /* -------------------------------------------------------------------------- */
 /**
  * Specialization for scalar types
  */
 template <class T, bool is_scal>
 template <class R, class daughter, class IR>
 class Array<T, is_scal>::iterator_internal<R, daughter, IR, false> {
 public:
   using value_type = R;
   using pointer = R *;
   using reference = R &;
   using const_reference = const R &;
   using internal_value_type = IR;
   using internal_pointer = IR *;
   using difference_type = std::ptrdiff_t;
   using iterator_category = std::random_access_iterator_tag;
 
 public:
   iterator_internal(pointer data = nullptr) : ret(data), initial(data){};
   iterator_internal(const iterator_internal & it) = default;
   iterator_internal(iterator_internal && it) = default;
 
   virtual ~iterator_internal() = default;
 
   inline iterator_internal & operator=(const iterator_internal & it) = default;
 
   UInt getCurrentIndex() { return (this->ret - this->initial); };
 
   inline reference operator*() { return *ret; };
   inline const_reference operator*() const { return *ret; };
   inline pointer operator->() { return ret; };
   inline daughter & operator++() {
     ++ret;
     return static_cast<daughter &>(*this);
   };
   inline daughter & operator--() {
     --ret;
     return static_cast<daughter &>(*this);
   };
 
   inline daughter & operator+=(const UInt n) {
     ret += n;
     return static_cast<daughter &>(*this);
   }
   inline daughter & operator-=(const UInt n) {
     ret -= n;
     return static_cast<daughter &>(*this);
   }
 
   inline reference operator[](const UInt n) { return ret[n]; }
 
   inline bool operator==(const iterator_internal & other) const {
     return ret == other.ret;
   }
   inline bool operator!=(const iterator_internal & other) const {
     return ret != other.ret;
   }
   inline bool operator<(const iterator_internal & other) const {
     return ret < other.ret;
   }
   inline bool operator<=(const iterator_internal & other) const {
     return ret <= other.ret;
   }
   inline bool operator>(const iterator_internal & other) const {
     return ret > other.ret;
   }
   inline bool operator>=(const iterator_internal & other) const {
     return ret >= other.ret;
   }
 
   inline daughter operator-(difference_type n) { return daughter(ret - n); }
   inline daughter operator+(difference_type n) { return daughter(ret + n); }
 
   inline difference_type operator-(const iterator_internal & b) {
     return ret - b.ret;
   }
 
   inline pointer data() const { return ret; }
 
 protected:
   pointer ret{nullptr};
   pointer initial{nullptr};
 };
 
 /* -------------------------------------------------------------------------- */
 /* Begin/End functions implementation                                         */
 /* -------------------------------------------------------------------------- */
 namespace detail {
   template <class Tuple, size_t... Is>
   constexpr auto take_front_impl(Tuple && t, std::index_sequence<Is...>) {
     return std::make_tuple(std::get<Is>(std::forward<Tuple>(t))...);
   }
 
   template <size_t N, class Tuple> constexpr auto take_front(Tuple && t) {
     return take_front_impl(std::forward<Tuple>(t),
                            std::make_index_sequence<N>{});
   }
 
   template <typename... V> constexpr auto product_all(V &&... v) {
     std::common_type_t<int, V...> result = 1;
     (void)std::initializer_list<int>{(result *= v, 0)...};
     return result;
   }
 
   template <typename... T> std::string to_string_all(T &&... t) {
     if (sizeof...(T) == 0)
       return "";
 
     std::stringstream ss;
     bool noComma = true;
     ss << "(";
     (void)std::initializer_list<bool>{
         (ss << (noComma ? "" : ", ") << t, noComma = false)...};
     ss << ")";
     return ss.str();
   }
 
   template <std::size_t N> struct InstantiationHelper {
     template <typename type, typename T, typename... Ns>
     static auto instantiate(T && data, Ns... ns) {
       return std::make_unique<type>(data, ns...);
     }
   };
 
   template <> struct InstantiationHelper<0> {
     template <typename type, typename T> static auto instantiate(T && data) {
       return data;
     }
   };
 
   template <typename Arr, typename T, typename... Ns>
   decltype(auto) get_iterator(Arr && array, T * data, Ns &&... ns) {
     using type = IteratorHelper_t<sizeof...(Ns) - 1, T>;
     using array_type = std::decay_t<Arr>;
     using iterator =
         std::conditional_t<std::is_const<std::remove_reference_t<Arr>>::value,
                            typename array_type::template const_iterator<type>,
                            typename array_type::template iterator<type>>;
     static_assert(sizeof...(Ns), "You should provide a least one size");
 
     if (array.getNbComponent() * array.size() !=
         product_all(std::forward<Ns>(ns)...)) {
       AKANTU_CUSTOM_EXCEPTION_INFO(
           debug::ArrayException(),
           "The iterator on "
               << debug::demangle(typeid(Arr).name())
               << to_string_all(array.size(), array.getNbComponent())
               << "is not compatible with the type "
               << debug::demangle(typeid(type).name()) << to_string_all(ns...));
     }
 
     auto && wrapped = aka::apply(
         [&](auto... n) {
           return InstantiationHelper<sizeof...(n)>::template instantiate<type>(
               data, n...);
         },
         take_front<sizeof...(Ns) - 1>(std::make_tuple(ns...)));
 
     return iterator(std::move(wrapped));
   }
 } // namespace detail
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::begin(Ns &&... ns) {
   return detail::get_iterator(*this, values, std::forward<Ns>(ns)..., size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::end(Ns &&... ns) {
   return detail::get_iterator(*this, values + nb_component * size_,
                               std::forward<Ns>(ns)..., size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::begin(Ns &&... ns) const {
   return detail::get_iterator(*this, values, std::forward<Ns>(ns)..., size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::end(Ns &&... ns) const {
   return detail::get_iterator(*this, values + nb_component * size_,
                               std::forward<Ns>(ns)..., size_);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::begin_reinterpret(Ns &&... ns) {
   return detail::get_iterator(*this, values, std::forward<Ns>(ns)...);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::end_reinterpret(Ns &&... ns) {
   return detail::get_iterator(
       *this, values + detail::product_all(std::forward<Ns>(ns)...),
       std::forward<Ns>(ns)...);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::begin_reinterpret(Ns &&... ns) const {
   return detail::get_iterator(*this, values, std::forward<Ns>(ns)...);
 }
 
 template <class T, bool is_scal>
 template <typename... Ns>
 inline decltype(auto) Array<T, is_scal>::end_reinterpret(Ns &&... ns) const {
   return detail::get_iterator(
       *this, values + detail::product_all(std::forward<Ns>(ns)...),
       std::forward<Ns>(ns)...);
 }
 
 /* -------------------------------------------------------------------------- */
 /* Views                                                                      */
 /* -------------------------------------------------------------------------- */
 namespace detail {
   template <typename Array, typename... Ns> class ArrayView {
     using tuple = std::tuple<Ns...>;
 
   public:
     ArrayView(Array && array, Ns... ns)
         : array(std::forward<Array>(array)), sizes(std::move(ns)...) {}
 
     ArrayView(ArrayView && array_view) = default;
 
     ArrayView & operator=(const ArrayView & array_view) = default;
     ArrayView & operator=(ArrayView && array_view) = default;
 
     decltype(auto) begin() {
       return aka::apply(
           [&](auto &&... ns) { return array.begin_reinterpret(ns...); }, sizes);
     }
 
     decltype(auto) begin() const {
       return aka::apply(
           [&](auto &&... ns) { return array.begin_reinterpret(ns...); }, sizes);
     }
 
     decltype(auto) end() {
       return aka::apply(
           [&](auto &&... ns) { return array.end_reinterpret(ns...); }, sizes);
     }
 
     decltype(auto) end() const {
       return aka::apply(
           [&](auto &&... ns) { return array.end_reinterpret(ns...); }, sizes);
     }
 
     decltype(auto) size() const {
       return std::get<std::tuple_size<tuple>::value - 1>(sizes);
     }
 
     decltype(auto) dims() const { return std::tuple_size<tuple>::value - 1; }
 
   private:
     Array array;
     tuple sizes;
   };
 } // namespace detail
 
 /* -------------------------------------------------------------------------- */
 template <typename Array, typename... Ns>
 decltype(auto) make_view(Array && array, Ns... ns) {
   auto size = std::forward<decltype(array)>(array).size() *
               std::forward<decltype(array)>(array).getNbComponent() /
               detail::product_all(ns...);
 
   return detail::ArrayView<Array, std::common_type_t<size_t, Ns>...,
                            std::common_type_t<size_t, decltype(size)>>(
       std::forward<Array>(array), std::move(ns)..., size);
 }
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <typename R>
 class Array<T, is_scal>::const_iterator
     : public iterator_internal<const R, Array<T, is_scal>::const_iterator<R>,
                                R> {
 public:
   using parent = iterator_internal<const R, const_iterator, R>;
   using value_type = typename parent::value_type;
   using pointer = typename parent::pointer;
   using reference = typename parent::reference;
   using difference_type = typename parent::difference_type;
   using iterator_category = typename parent::iterator_category;
 
 public:
   const_iterator() : parent(){};
   // const_iterator(pointer_type data, UInt offset) : parent(data, offset) {}
   // const_iterator(pointer warped) : parent(warped) {}
   // const_iterator(const parent & it) : parent(it) {}
 
   const_iterator(const const_iterator & it) = default;
   const_iterator(const_iterator && it) = default;
 
   template <typename P, typename = std::enable_if_t<not is_tensor<P>::value>>
   const_iterator(P * data) : parent(data) {}
 
   template <typename UP_P,
             typename =
                 std::enable_if_t<is_tensor<typename UP_P::element_type>::value>>
   const_iterator(UP_P && tensor) : parent(std::forward<UP_P>(tensor)) {}
 
   const_iterator & operator=(const const_iterator & it) = default;
 };
 
 template <class T, class R, bool is_tensor_ = is_tensor<R>::value>
 struct ConstConverterIteratorHelper {
   using const_iterator = typename Array<T>::template const_iterator<R>;
   using iterator = typename Array<T>::template iterator<R>;
 
   static inline const_iterator convert(const iterator & it) {
     return const_iterator(std::unique_ptr<R>(new R(*it, false)));
   }
 };
 
 template <class T, class R> struct ConstConverterIteratorHelper<T, R, false> {
   using const_iterator = typename Array<T>::template const_iterator<R>;
   using iterator = typename Array<T>::template iterator<R>;
   static inline const_iterator convert(const iterator & it) {
     return const_iterator(it.data());
   }
 };
 
 template <class T, bool is_scal>
 template <typename R>
 class Array<T, is_scal>::iterator
     : public iterator_internal<R, Array<T, is_scal>::iterator<R>> {
 public:
   using parent = iterator_internal<R, iterator>;
   using value_type = typename parent::value_type;
   using pointer = typename parent::pointer;
   using reference = typename parent::reference;
   using difference_type = typename parent::difference_type;
   using iterator_category = typename parent::iterator_category;
 
 public:
   iterator() : parent(){};
   iterator(const iterator & it) = default;
   iterator(iterator && it) = default;
 
   template <typename P, typename = std::enable_if_t<not is_tensor<P>::value>>
   iterator(P * data) : parent(data) {}
 
   template <typename UP_P,
             typename =
                 std::enable_if_t<is_tensor<typename UP_P::element_type>::value>>
   iterator(UP_P && tensor) : parent(std::forward<UP_P>(tensor)) {}
 
   iterator & operator=(const iterator & it) = default;
 
   operator const_iterator<R>() {
     return ConstConverterIteratorHelper<T, R>::convert(*this);
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <class T, bool is_scal>
 template <typename R>
 inline typename Array<T, is_scal>::template iterator<R>
 Array<T, is_scal>::erase(const iterator<R> & it) {
   T * curr = it.data();
   UInt pos = (curr - values) / nb_component;
   erase(pos);
   iterator<R> rit = it;
   return --rit;
 }
 #endif
 
 } // namespace akantu
 
 #endif /* __AKANTU_AKA_ARRAY_TMPL_HH__ */
diff --git a/src/mesh/mesh.hh b/src/mesh/mesh.hh
index fbe7d74ee..649b718d2 100644
--- a/src/mesh/mesh.hh
+++ b/src/mesh/mesh.hh
@@ -1,604 +1,603 @@
 /**
  * @file   mesh.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Dana Christen <dana.christen@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Thu Jan 14 2016
  *
  * @brief  the class representing the meshes
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #ifndef __AKANTU_MESH_HH__
 #define __AKANTU_MESH_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_array.hh"
 #include "aka_event_handler_manager.hh"
 #include "aka_memory.hh"
 #include "dumpable.hh"
 #include "element.hh"
 #include "element_class.hh"
 #include "element_type_map.hh"
 #include "group_manager.hh"
 #include "mesh_data.hh"
 #include "mesh_events.hh"
 /* -------------------------------------------------------------------------- */
 #include <set>
 /* -------------------------------------------------------------------------- */
 
 namespace akantu {
 class Communicator;
 class ElementSynchronizer;
 class NodeSynchronizer;
 } // namespace akantu
 
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 /* Mesh                                                                       */
 /* -------------------------------------------------------------------------- */
 
 /**
  * @class  Mesh this  contain the  coordinates of  the nodes  in  the Mesh.nodes
  * Array,  and the  connectivity. The  connectivity  are stored  in by  element
  * types.
  *
  * In order to loop on all element you have to loop on all types like this :
  * @code{.cpp}
  Mesh::type_iterator it = mesh.firstType(dim, ghost_type);
  Mesh::type_iterator end = mesh.lastType(dim, ghost_type);
  for(; it != end; ++it) {
    UInt nb_element  = mesh.getNbElement(*it);
    const Array<UInt> & conn = mesh.getConnectivity(*it);
    for(UInt e = 0; e < nb_element; ++e) {
      ...
    }
  }
  @endcode
 */
 class Mesh : protected Memory,
              public EventHandlerManager<MeshEventHandler>,
              public GroupManager,
              public Dumpable {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 private:
   /// default constructor used for chaining, the last parameter is just to
   /// differentiate constructors
   Mesh(UInt spatial_dimension, const ID & id, const MemoryID & memory_id,
        Communicator & communicator);
 
 public:
   /// constructor that create nodes coordinates array
   Mesh(UInt spatial_dimension, const ID & id = "mesh",
        const MemoryID & memory_id = 0);
 
   /// mesh not distributed and not using the default communicator
   Mesh(UInt spatial_dimension, Communicator & communicator,
        const ID & id = "mesh", const MemoryID & memory_id = 0);
 
   /// constructor that use an existing nodes coordinates array, by knowing its
   /// ID
   // Mesh(UInt spatial_dimension, const ID & nodes_id, const ID & id,
   //      const MemoryID & memory_id = 0);
 
   /**
    * constructor that use an existing nodes coordinates
    * array, by getting the vector of coordinates
    */
   Mesh(UInt spatial_dimension, const std::shared_ptr<Array<Real>> & nodes,
        const ID & id = "mesh", const MemoryID & memory_id = 0);
 
   ~Mesh() override;
 
   /// @typedef ConnectivityTypeList list of the types present in a Mesh
   using ConnectivityTypeList = std::set<ElementType>;
 
   /// read the mesh from a file
   void read(const std::string & filename,
             const MeshIOType & mesh_io_type = _miot_auto);
   /// write the mesh to a file
   void write(const std::string & filename,
              const MeshIOType & mesh_io_type = _miot_auto);
 
 private:
   /// initialize the connectivity to NULL and other stuff
   void init();
 
   /// function that computes the bounding box (fills xmin, xmax)
   void computeBoundingBox();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// patitionate the mesh among the processors involved in their computation
   virtual void distribute(Communicator & communicator);
   virtual void distribute();
 
   /// function to print the containt of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /// extract coordinates of nodes from an element
   template <typename T>
   inline void extractNodalValuesFromElement(const Array<T> & nodal_values,
                                             T * elemental_values,
                                             UInt * connectivity, UInt n_nodes,
                                             UInt nb_degree_of_freedom) const;
 
   // /// extract coordinates of nodes from a reversed element
   // inline void extractNodalCoordinatesFromPBCElement(Real * local_coords,
   //                                                   UInt * connectivity,
   //                                                   UInt n_nodes);
 
-  /// convert a element to a linearized element
-  inline UInt elementToLinearized(const Element & elem) const;
-
-  /// convert a linearized element to an element
-  inline Element linearizedToElement(UInt linearized_element) const;
-
-  /// update the types offsets array for the conversions
-  // inline void updateTypesOffsets(const GhostType & ghost_type);
-
   /// add a Array of connectivity for the type <type>.
   inline void addConnectivityType(const ElementType & type,
                                   const GhostType & ghost_type = _not_ghost);
 
   /* ------------------------------------------------------------------------ */
   template <class Event> inline void sendEvent(Event & event) {
     //    if(event.getList().size() != 0)
     EventHandlerManager<MeshEventHandler>::sendEvent<Event>(event);
   }
 
   /// prepare the  event to remove the elements listed
   void eraseElements(const Array<Element> & elements);
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   inline void removeNodesFromArray(Array<T> & vect,
                                    const Array<UInt> & new_numbering);
 
   /// initialize normals
   void initNormals();
 
   /// init facets' mesh
   Mesh & initMeshFacets(const ID & id = "mesh_facets");
 
   /// define parent mesh
   void defineMeshParent(const Mesh & mesh);
 
   /// get global connectivity array
   void getGlobalConnectivity(ElementTypeMapArray<UInt> & global_connectivity);
 
 public:
   void getAssociatedElements(const Array<UInt> & node_list,
                              Array<Element> & elements);
 
 private:
   /// fills the nodes_to_elements structure
   void fillNodesToElements();
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the id of the mesh
   AKANTU_GET_MACRO(ID, Memory::id, const ID &);
 
   /// get the id of the mesh
   AKANTU_GET_MACRO(MemoryID, Memory::memory_id, const MemoryID &);
 
   /// get the spatial dimension of the mesh = number of component of the
   /// coordinates
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
 
   /// get the nodes Array aka coordinates
   AKANTU_GET_MACRO(Nodes, *nodes, const Array<Real> &);
   AKANTU_GET_MACRO_NOT_CONST(Nodes, *nodes, Array<Real> &);
 
   /// get the normals for the elements
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Normals, normals, Real);
 
   /// get the number of nodes
   AKANTU_GET_MACRO(NbNodes, nodes->size(), UInt);
 
   /// get the Array of global ids of the nodes (only used in parallel)
   AKANTU_GET_MACRO(GlobalNodesIds, *nodes_global_ids, const Array<UInt> &);
   AKANTU_GET_MACRO_NOT_CONST(GlobalNodesIds, *nodes_global_ids, Array<UInt> &);
 
   /// get the global id of a node
   inline UInt getNodeGlobalId(UInt local_id) const;
 
   /// get the global id of a node
   inline UInt getNodeLocalId(UInt global_id) const;
 
   /// get the global number of nodes
   inline UInt getNbGlobalNodes() const;
 
   /// get the nodes type Array
   AKANTU_GET_MACRO(NodesType, nodes_type, const Array<NodeType> &);
 
 protected:
   AKANTU_GET_MACRO_NOT_CONST(NodesType, nodes_type, Array<NodeType> &);
 
 public:
   inline NodeType getNodeType(UInt local_id) const;
 
   /// say if a node is a pure ghost node
   inline bool isPureGhostNode(UInt n) const;
 
   /// say if a node is pur local or master node
   inline bool isLocalOrMasterNode(UInt n) const;
 
   inline bool isLocalNode(UInt n) const;
   inline bool isMasterNode(UInt n) const;
   inline bool isSlaveNode(UInt n) const;
 
   AKANTU_GET_MACRO(LowerBounds, lower_bounds, const Vector<Real> &);
   AKANTU_GET_MACRO(UpperBounds, upper_bounds, const Vector<Real> &);
   AKANTU_GET_MACRO(LocalLowerBounds, local_lower_bounds, const Vector<Real> &);
   AKANTU_GET_MACRO(LocalUpperBounds, local_upper_bounds, const Vector<Real> &);
 
   /// get the connectivity Array for a given type
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Connectivity, connectivities, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(Connectivity, connectivities, UInt);
   AKANTU_GET_MACRO(Connectivities, connectivities,
                    const ElementTypeMapArray<UInt> &);
 
   /// get the number of element of a type in the mesh
   inline UInt getNbElement(const ElementType & type,
                            const GhostType & ghost_type = _not_ghost) const;
 
   /// get the number of element for a given ghost_type and a given dimension
   inline UInt getNbElement(const UInt spatial_dimension = _all_dimensions,
                            const GhostType & ghost_type = _not_ghost,
                            const ElementKind & kind = _ek_not_defined) const;
 
   // /// get the connectivity list either for the elements or the ghost elements
   // inline const ConnectivityTypeList &
   // getConnectivityTypeList(const GhostType & ghost_type = _not_ghost) const;
 
   /// compute the barycenter of a given element
 private:
   inline void getBarycenter(UInt element, const ElementType & type,
                             Real * barycenter,
                             GhostType ghost_type = _not_ghost) const;
 
 public:
   inline void getBarycenter(const Element & element,
                             Vector<Real> & barycenter) const;
 
   /// get the element connected to a subelement
   const auto & getElementToSubelement() const;
 
   /// get the element connected to a subelement
   const auto &
   getElementToSubelement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost) const;
 
   /// get the element connected to a subelement
   auto & getElementToSubelement(const ElementType & el_type,
                                 const GhostType & ghost_type = _not_ghost);
 
   /// get the subelement connected to an element
   const auto &
   getSubelementToElement(const ElementType & el_type,
                          const GhostType & ghost_type = _not_ghost) const;
   /// get the subelement connected to an element
   auto & getSubelementToElement(const ElementType & el_type,
                                 const GhostType & ghost_type = _not_ghost);
 
   /// register a new ElementalTypeMap in the MeshData
   template <typename T>
   inline ElementTypeMapArray<T> & registerData(const std::string & data_name);
 
   template <typename T>
   inline bool hasData(const ID & data_name, const ElementType & el_type,
                       const GhostType & ghost_type = _not_ghost) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline const Array<T> &
   getData(const ID & data_name, const ElementType & el_type,
           const GhostType & ghost_type = _not_ghost) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline Array<T> & getData(const ID & data_name, const ElementType & el_type,
                             const GhostType & ghost_type = _not_ghost);
 
   /// tells if the data data_name is contained in the mesh or not
   inline bool hasData(const ID & data_name) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline const ElementTypeMapArray<T> & getData(const ID & data_name) const;
 
   /// get a name field associated to the mesh
   template <typename T>
   inline ElementTypeMapArray<T> & getData(const ID & data_name);
 
   template <typename T>
   ElementTypeMap<UInt> getNbDataPerElem(ElementTypeMapArray<T> & array,
                                         const ElementKind & element_kind);
 
   template <typename T>
   dumper::Field * createFieldFromAttachedData(const std::string & field_id,
                                               const std::string & group_name,
                                               const ElementKind & element_kind);
 
   /// templated getter returning the pointer to data in MeshData (modifiable)
   template <typename T>
   inline Array<T> &
   getDataPointer(const std::string & data_name, const ElementType & el_type,
                  const GhostType & ghost_type = _not_ghost,
                  UInt nb_component = 1, bool size_to_nb_element = true,
                  bool resize_with_parent = false);
 
   /// Facets mesh accessor
   inline const Mesh & getMeshFacets() const;
   inline Mesh & getMeshFacets();
 
   /// Parent mesh accessor
   inline const Mesh & getMeshParent() const;
 
   inline bool isMeshFacets() const { return this->is_mesh_facets; }
 
   /// defines is the mesh is distributed or not
   inline bool isDistributed() const { return this->is_distributed; }
 
 #ifndef SWIG
   /// return the dumper from a group and and a dumper name
   DumperIOHelper & getGroupDumper(const std::string & dumper_name,
                                   const std::string & group_name);
 #endif
   /* ------------------------------------------------------------------------ */
   /* Wrappers on ElementClass functions                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /// get the number of nodes per element for a given element type
   static inline UInt getNbNodesPerElement(const ElementType & type);
 
   /// get the number of nodes per element for a given element type considered as
   /// a first order element
   static inline ElementType getP1ElementType(const ElementType & type);
 
   /// get the kind of the element type
   static inline ElementKind getKind(const ElementType & type);
 
   /// get spatial dimension of a type of element
   static inline UInt getSpatialDimension(const ElementType & type);
 
   /// get number of facets of a given element type
   static inline UInt getNbFacetsPerElement(const ElementType & type);
 
   /// get number of facets of a given element type
   static inline UInt getNbFacetsPerElement(const ElementType & type, UInt t);
 
+#ifndef SWIG
+
   /// get local connectivity of a facet for a given facet type
   static inline auto getFacetLocalConnectivity(const ElementType & type,
                                                UInt t = 0);
 
   /// get connectivity of facets for a given element
   inline auto getFacetConnectivity(const Element & element, UInt t = 0) const;
 
+#endif
+
   /// get the number of type of the surface element associated to a given
   /// element type
   static inline UInt getNbFacetTypes(const ElementType & type, UInt t = 0);
 
+#ifndef SWIG
+
   /// get the type of the surface element associated to a given element
   static inline constexpr auto getFacetType(const ElementType & type,
                                             UInt t = 0);
 
   /// get all the type of the surface element associated to a given element
   static inline constexpr auto getAllFacetTypes(const ElementType & type);
 
+#endif
+
   /// get the number of nodes in the given element list
   static inline UInt getNbNodesPerElementList(const Array<Element> & elements);
 
   /* ------------------------------------------------------------------------ */
   /* Element type Iterator                                                    */
   /* ------------------------------------------------------------------------ */
   using type_iterator = ElementTypeMapArray<UInt, ElementType>::type_iterator;
   using ElementTypesIteratorHelper =
       ElementTypeMapArray<UInt, ElementType>::ElementTypesIteratorHelper;
 
   template <typename... pack>
   ElementTypesIteratorHelper elementTypes(pack &&... _pack) const;
 
   inline type_iterator firstType(UInt dim = _all_dimensions,
                                  GhostType ghost_type = _not_ghost,
                                  ElementKind kind = _ek_regular) const {
     return connectivities.firstType(dim, ghost_type, kind);
   }
 
   inline type_iterator lastType(UInt dim = _all_dimensions,
                                 GhostType ghost_type = _not_ghost,
                                 ElementKind kind = _ek_regular) const {
     return connectivities.lastType(dim, ghost_type, kind);
   }
 
   AKANTU_GET_MACRO(ElementSynchronizer, *element_synchronizer,
                    const ElementSynchronizer &);
   AKANTU_GET_MACRO_NOT_CONST(ElementSynchronizer, *element_synchronizer,
                              ElementSynchronizer &);
   AKANTU_GET_MACRO(NodeSynchronizer, *node_synchronizer,
                    const NodeSynchronizer &);
   AKANTU_GET_MACRO_NOT_CONST(NodeSynchronizer, *node_synchronizer,
                              NodeSynchronizer &);
 
 // AKANTU_GET_MACRO_NOT_CONST(Communicator, *communicator, StaticCommunicator
 // &);
 #ifndef SWIG
   AKANTU_GET_MACRO(Communicator, *communicator, const auto &);
   AKANTU_GET_MACRO_NOT_CONST(Communicator, *communicator, auto &);
 #endif
   /* ------------------------------------------------------------------------ */
   /* Private methods for friends                                              */
   /* ------------------------------------------------------------------------ */
 private:
   friend class MeshAccessor;
 
   AKANTU_GET_MACRO(NodesPointer, *nodes, Array<Real> &);
 
   /// get a pointer to the nodes_global_ids Array<UInt> and create it if
   /// necessary
   inline Array<UInt> & getNodesGlobalIdsPointer();
 
   /// get a pointer to the nodes_type Array<Int> and create it if necessary
   inline Array<NodeType> & getNodesTypePointer();
 
   /// get a pointer to the connectivity Array for the given type and create it
   /// if necessary
   inline Array<UInt> &
   getConnectivityPointer(const ElementType & type,
                          const GhostType & ghost_type = _not_ghost);
 
   /// get the ghost element counter
   inline Array<UInt> &
   getGhostsCounters(const ElementType & type,
                     const GhostType & ghost_type = _ghost) {
     AKANTU_DEBUG_ASSERT(ghost_type != _not_ghost,
                         "No ghost counter for _not_ghost elements");
     return ghosts_counters(type, ghost_type);
   }
 
   /// get a pointer to the element_to_subelement Array for the given type and
   /// create it if necessary
   inline Array<std::vector<Element>> &
   getElementToSubelementPointer(const ElementType & type,
                                 const GhostType & ghost_type = _not_ghost);
 
   /// get a pointer to the subelement_to_element Array for the given type and
   /// create it if necessary
   inline Array<Element> &
   getSubelementToElementPointer(const ElementType & type,
                                 const GhostType & ghost_type = _not_ghost);
 
   AKANTU_GET_MACRO_NOT_CONST(MeshData, mesh_data, MeshData &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// array of the nodes coordinates
   std::shared_ptr<Array<Real>> nodes;
 
   /// global node ids
   std::unique_ptr<Array<UInt>> nodes_global_ids;
 
   /// node type,  -3 pure ghost, -2  master for the  node, -1 normal node,  i in
   /// [0-N] slave node and master is proc i
   Array<NodeType> nodes_type;
 
   /// global number of nodes;
   UInt nb_global_nodes{0};
 
   /// all class of elements present in this mesh (for heterogenous meshes)
   ElementTypeMapArray<UInt> connectivities;
 
   /// count the references on ghost elements
   ElementTypeMapArray<UInt> ghosts_counters;
 
   /// map to normals for all class of elements present in this mesh
   ElementTypeMapArray<Real> normals;
 
   /// list of all existing types in the mesh
   // ConnectivityTypeList type_set;
 
   /// the spatial dimension of this mesh
   UInt spatial_dimension{0};
 
   /// types offsets
   // Array<UInt> types_offsets;
 
   // /// list of all existing types in the mesh
   // ConnectivityTypeList ghost_type_set;
   // /// ghost types offsets
   // Array<UInt> ghost_types_offsets;
 
   /// min of coordinates
   Vector<Real> lower_bounds;
   /// max of coordinates
   Vector<Real> upper_bounds;
   /// size covered by the mesh on each direction
   Vector<Real> size;
 
   /// local min of coordinates
   Vector<Real> local_lower_bounds;
   /// local max of coordinates
   Vector<Real> local_upper_bounds;
 
   /// Extra data loaded from the mesh file
   MeshData mesh_data;
 
   /// facets' mesh
   std::unique_ptr<Mesh> mesh_facets;
 
   /// parent mesh (this is set for mesh_facets meshes)
   const Mesh * mesh_parent{nullptr};
 
   /// defines if current mesh is mesh_facets or not
   bool is_mesh_facets{false};
 
   /// defines if the mesh is centralized or distributed
   bool is_distributed{false};
 
   /// Communicator on which mesh is distributed
   Communicator * communicator;
 
   /// Element synchronizer
   std::unique_ptr<ElementSynchronizer> element_synchronizer;
 
   /// Node synchronizer
   std::unique_ptr<NodeSynchronizer> node_synchronizer;
 
   using NodesToElements = std::vector<std::unique_ptr<std::set<Element>>>;
 
   /// This info is stored to simplify the dynamic changes
   NodesToElements nodes_to_elements;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream, const Mesh & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* Inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "element_type_map_tmpl.hh"
 #include "mesh_inline_impl.cc"
 
 #endif /* __AKANTU_MESH_HH__ */
diff --git a/src/model/solid_mechanics/material.hh b/src/model/solid_mechanics/material.hh
index adb3385c7..19d09abde 100644
--- a/src/model/solid_mechanics/material.hh
+++ b/src/model/solid_mechanics/material.hh
@@ -1,682 +1,682 @@
 
 /**
  * @file   material.hh
  *
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  * @author Marco Vocialta <marco.vocialta@epfl.ch>
  *
  * @date creation: Fri Jun 18 2010
  * @date last modification: Wed Nov 25 2015
  *
  * @brief  Mother class for all materials
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_factory.hh"
 #include "aka_voigthelper.hh"
 #include "data_accessor.hh"
 #include "integration_point.hh"
 #include "parsable.hh"
 #include "parser.hh"
 /* -------------------------------------------------------------------------- */
 #include "internal_field.hh"
 #include "random_internal_field.hh"
 /* -------------------------------------------------------------------------- */
 #include "mesh_events.hh"
 #include "solid_mechanics_model_event_handler.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_HH__
 #define __AKANTU_MATERIAL_HH__
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 class Model;
 class SolidMechanicsModel;
 } // namespace akantu
 
 namespace akantu {
 
 /**
  * Interface of all materials
  * Prerequisites for a new material
  * - inherit from this class
  * - implement the following methods:
  * \code
  *  virtual Real getStableTimeStep(Real h, const Element & element =
  * ElementNull);
  *
  *  virtual void computeStress(ElementType el_type,
  *                             GhostType ghost_type = _not_ghost);
  *
  *  virtual void computeTangentStiffness(const ElementType & el_type,
  *                                       Array<Real> & tangent_matrix,
  *                                       GhostType ghost_type = _not_ghost);
  * \endcode
  *
  */
 
 class Material : public Memory,
-                 public DataAccessor<Element>,
+                 public TemporarySwigDataAccessor<Element>,
                  public Parsable,
                  public MeshEventHandler,
                  protected SolidMechanicsModelEventHandler {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
 #if __cplusplus > 199711L
   Material(const Material & mat) = delete;
   Material & operator=(const Material & mat) = delete;
 #endif
 
   /// Initialize material with defaults
   Material(SolidMechanicsModel & model, const ID & id = "");
 
   /// Initialize material with custom mesh & fe_engine
   Material(SolidMechanicsModel & model, UInt dim, const Mesh & mesh,
            FEEngine & fe_engine, const ID & id = "");
 
   /// Destructor
   ~Material() override;
 
 protected:
   void initialize();
 
   /* ------------------------------------------------------------------------ */
   /* Function that materials can/should reimplement                           */
   /* ------------------------------------------------------------------------ */
 protected:
   /// constitutive law
   virtual void computeStress(__attribute__((unused)) ElementType el_type,
                              __attribute__((unused))
                              GhostType ghost_type = _not_ghost) {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   /// compute the tangent stiffness matrix
   virtual void computeTangentModuli(__attribute__((unused))
                                     const ElementType & el_type,
                                     __attribute__((unused))
                                     Array<Real> & tangent_matrix,
                                     __attribute__((unused))
                                     GhostType ghost_type = _not_ghost) {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   /// compute the potential energy
   virtual void computePotentialEnergy(ElementType el_type,
                                       GhostType ghost_type = _not_ghost);
 
   /// compute the potential energy for an element
   virtual void
   computePotentialEnergyByElement(__attribute__((unused)) ElementType type,
                                   __attribute__((unused)) UInt index,
                                   __attribute__((unused))
                                   Vector<Real> & epot_on_quad_points) {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   virtual void updateEnergies(__attribute__((unused)) ElementType el_type,
                               __attribute__((unused))
                               GhostType ghost_type = _not_ghost) {}
 
   virtual void updateEnergiesAfterDamage(__attribute__((unused))
                                          ElementType el_type,
                                          __attribute__((unused))
                                          GhostType ghost_type = _not_ghost) {}
 
   /// set the material to steady state (to be implemented for materials that
   /// need it)
   virtual void setToSteadyState(__attribute__((unused)) ElementType el_type,
                                 __attribute__((unused))
                                 GhostType ghost_type = _not_ghost) {}
 
   /// function called to update the internal parameters when the modifiable
   /// parameters are modified
   virtual void updateInternalParameters() {}
 
 public:
   /// extrapolate internal values
   virtual void extrapolateInternal(const ID & id, const Element & element,
                                    const Matrix<Real> & points,
                                    Matrix<Real> & extrapolated);
 
   /// compute the p-wave speed in the material
   virtual Real getPushWaveSpeed(__attribute__((unused))
                                 const Element & element) const {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   /// compute the s-wave speed in the material
   virtual Real getShearWaveSpeed(__attribute__((unused))
                                  const Element & element) const {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   /// get a material celerity to compute the stable time step (default: is the
   /// push wave speed)
   virtual Real getCelerity(const Element & element) const {
     return getPushWaveSpeed(element);
   }
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T>
   void registerInternal(__attribute__((unused)) InternalField<T> & vect) {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   template <typename T>
   void unregisterInternal(__attribute__((unused)) InternalField<T> & vect) {
     AKANTU_DEBUG_TO_IMPLEMENT();
   }
 
   /// initialize the material computed parameter
   virtual void initMaterial();
 
   /// compute the residual for this material
   //  virtual void updateResidual(GhostType ghost_type = _not_ghost);
 
   /// assemble the residual for this material
   virtual void assembleInternalForces(GhostType ghost_type);
 
   /// save the stress in the previous_stress if needed
   virtual void savePreviousState();
 
   /// compute the stresses for this material
   virtual void computeAllStresses(GhostType ghost_type = _not_ghost);
   // virtual void
   // computeAllStressesFromTangentModuli(GhostType ghost_type = _not_ghost);
   virtual void computeAllCauchyStresses(GhostType ghost_type = _not_ghost);
 
   /// set material to steady state
   void setToSteadyState(GhostType ghost_type = _not_ghost);
 
   /// compute the stiffness matrix
   virtual void assembleStiffnessMatrix(GhostType ghost_type);
 
   /// add an element to the local mesh filter
   inline UInt addElement(const ElementType & type, UInt element,
                          const GhostType & ghost_type);
   inline UInt addElement(const Element & element);
 
   /// add many elements at once
   void addElements(const Array<Element> & elements_to_add);
 
   /// remove many element at once
   void removeElements(const Array<Element> & elements_to_remove);
 
   /// function to print the contain of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /**
    * interpolate stress on given positions for each element by means
    * of a geometrical interpolation on quadrature points
    */
   void interpolateStress(ElementTypeMapArray<Real> & result,
                          const GhostType ghost_type = _not_ghost);
 
   /**
    * interpolate stress on given positions for each element by means
    * of a geometrical interpolation on quadrature points and store the
    * results per facet
    */
   void interpolateStressOnFacets(ElementTypeMapArray<Real> & result,
                                  ElementTypeMapArray<Real> & by_elem_result,
                                  const GhostType ghost_type = _not_ghost);
 
   /**
    * function to initialize the elemental field interpolation
    * function by inverting the quadrature points' coordinates
    */
   void initElementalFieldInterpolation(
       const ElementTypeMapArray<Real> & interpolation_points_coordinates);
 
   /* ------------------------------------------------------------------------ */
   /* Common part                                                              */
   /* ------------------------------------------------------------------------ */
 protected:
   /* ------------------------------------------------------------------------ */
   inline UInt getTangentStiffnessVoigtSize(UInt spatial_dimension) const;
 
   /// compute the potential energy by element
   void computePotentialEnergyByElements();
 
   /// resize the intenals arrays
   virtual void resizeInternals();
 
   /* ------------------------------------------------------------------------ */
   /* Finite deformation functions                                             */
   /* This functions area implementing what is described in the paper of Bathe */
   /* et al, in IJNME, Finite Element Formulations For Large Deformation       */
   /* Dynamic Analysis, Vol 9, 353-386, 1975                                   */
   /* ------------------------------------------------------------------------ */
 protected:
   /// assemble the residual
   template <UInt dim> void assembleInternalForces(GhostType ghost_type);
 
   /// Computation of Cauchy stress tensor in the case of finite deformation from
   /// the 2nd Piola-Kirchhoff for a given element type
   template <UInt dim>
   void computeCauchyStress(ElementType el_type,
                            GhostType ghost_type = _not_ghost);
 
   /// Computation the Cauchy stress the 2nd Piola-Kirchhoff and the deformation
   /// gradient
   template <UInt dim>
   inline void computeCauchyStressOnQuad(const Matrix<Real> & F,
                                         const Matrix<Real> & S,
                                         Matrix<Real> & cauchy,
                                         const Real & C33 = 1.0) const;
 
   template <UInt dim>
   void computeAllStressesFromTangentModuli(const ElementType & type,
                                            GhostType ghost_type);
 
   template <UInt dim>
   void assembleStiffnessMatrix(const ElementType & type, GhostType ghost_type);
 
   /// assembling in finite deformation
   template <UInt dim>
   void assembleStiffnessMatrixNL(const ElementType & type,
                                  GhostType ghost_type);
 
   template <UInt dim>
   void assembleStiffnessMatrixL2(const ElementType & type,
                                  GhostType ghost_type);
 
   /// Size of the Stress matrix for the case of finite deformation see: Bathe et
   /// al, IJNME, Vol 9, 353-386, 1975
   inline UInt getCauchyStressMatrixSize(UInt spatial_dimension) const;
 
   /// Sets the stress matrix according to Bathe et al, IJNME, Vol 9, 353-386,
   /// 1975
   template <UInt dim>
   inline void setCauchyStressMatrix(const Matrix<Real> & S_t,
                                     Matrix<Real> & sigma);
 
   /// write the stress tensor in the Voigt notation.
   template <UInt dim>
   inline void setCauchyStressArray(const Matrix<Real> & S_t,
                                    Matrix<Real> & sigma_voight);
 
   /* ------------------------------------------------------------------------ */
   /* Conversion functions                                                     */
   /* ------------------------------------------------------------------------ */
 public:
   template <UInt dim>
   static inline void gradUToF(const Matrix<Real> & grad_u, Matrix<Real> & F);
   static inline void rightCauchy(const Matrix<Real> & F, Matrix<Real> & C);
   static inline void leftCauchy(const Matrix<Real> & F, Matrix<Real> & B);
 
   template <UInt dim>
   static inline void gradUToEpsilon(const Matrix<Real> & grad_u,
                                     Matrix<Real> & epsilon);
   template <UInt dim>
   static inline void gradUToGreenStrain(const Matrix<Real> & grad_u,
                                         Matrix<Real> & epsilon);
 
   static inline Real stressToVonMises(const Matrix<Real> & stress);
 
 protected:
   /// converts global element to local element
   inline Element convertToLocalElement(const Element & global_element) const;
   /// converts local element to global element
   inline Element convertToGlobalElement(const Element & local_element) const;
 
   /// converts global quadrature point to local quadrature point
   inline IntegrationPoint
   convertToLocalPoint(const IntegrationPoint & global_point) const;
   /// converts local quadrature point to global quadrature point
   inline IntegrationPoint
   convertToGlobalPoint(const IntegrationPoint & local_point) const;
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
 public:
   inline UInt getNbData(const Array<Element> & elements,
                         const SynchronizationTag & tag) const override;
 
   inline void packData(CommunicationBuffer & buffer,
                        const Array<Element> & elements,
                        const SynchronizationTag & tag) const override;
 
   inline void unpackData(CommunicationBuffer & buffer,
                          const Array<Element> & elements,
                          const SynchronizationTag & tag) override;
 
   template <typename T>
   inline void packElementDataHelper(const ElementTypeMapArray<T> & data_to_pack,
                                     CommunicationBuffer & buffer,
                                     const Array<Element> & elements,
                                     const ID & fem_id = ID()) const;
 
   template <typename T>
   inline void unpackElementDataHelper(ElementTypeMapArray<T> & data_to_unpack,
                                       CommunicationBuffer & buffer,
                                       const Array<Element> & elements,
                                       const ID & fem_id = ID());
 
   /* ------------------------------------------------------------------------ */
   /* MeshEventHandler inherited members                                       */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   void onNodesAdded(const Array<UInt> &, const NewNodesEvent &) override{};
   void onNodesRemoved(const Array<UInt> &, const Array<UInt> &,
                       const RemovedNodesEvent &) override{};
 
   void onElementsAdded(const Array<Element> & element_list,
                        const NewElementsEvent & event) override;
 
   void onElementsRemoved(const Array<Element> & element_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const RemovedElementsEvent & event) override;
 
   void onElementsChanged(const Array<Element> &, const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const ChangedElementsEvent &) override{};
 
   /* ------------------------------------------------------------------------ */
   /* SolidMechanicsModelEventHandler inherited members                        */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void beforeSolveStep();
   virtual void afterSolveStep();
 
   void onDamageIteration() override;
   void onDamageUpdate() override;
   void onDump() override;
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Name, name, const std::string &);
 
   AKANTU_GET_MACRO(Model, model, const SolidMechanicsModel &)
 
   AKANTU_GET_MACRO(ID, Memory::getID(), const ID &);
   AKANTU_GET_MACRO(Rho, rho, Real);
   AKANTU_SET_MACRO(Rho, rho, Real);
 
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
 
   /// return the potential energy for the subset of elements contained by the
   /// material
   Real getPotentialEnergy();
   /// return the potential energy for the provided element
   Real getPotentialEnergy(ElementType & type, UInt index);
 
   /// return the energy (identified by id) for the subset of elements contained
   /// by the material
   virtual Real getEnergy(const std::string & energy_id);
   /// return the energy (identified by id) for the provided element
   virtual Real getEnergy(const std::string & energy_id, ElementType type,
                          UInt index);
 
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementFilter, element_filter, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(GradU, gradu, Real);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Stress, stress, Real);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(PotentialEnergy, potential_energy,
                                          Real);
   AKANTU_GET_MACRO(GradU, gradu, const ElementTypeMapArray<Real> &);
   AKANTU_GET_MACRO(Stress, stress, const ElementTypeMapArray<Real> &);
   AKANTU_GET_MACRO(ElementFilter, element_filter,
                    const ElementTypeMapArray<UInt> &);
   AKANTU_GET_MACRO(FEEngine, fem, FEEngine &);
 
   bool isNonLocal() const { return is_non_local; }
 
   template <typename T>
   const Array<T> & getArray(const ID & id, const ElementType & type,
                             const GhostType & ghost_type = _not_ghost) const;
   template <typename T>
   Array<T> & getArray(const ID & id, const ElementType & type,
                       const GhostType & ghost_type = _not_ghost);
 
   template <typename T>
   const InternalField<T> & getInternal(const ID & id) const;
   template <typename T> InternalField<T> & getInternal(const ID & id);
 
   template <typename T>
   inline bool isInternal(const ID & id, const ElementKind & element_kind) const;
 
   template <typename T>
   ElementTypeMap<UInt>
   getInternalDataPerElem(const ID & id, const ElementKind & element_kind) const;
 
   bool isFiniteDeformation() const { return finite_deformation; }
   bool isInelasticDeformation() const { return inelastic_deformation; }
 
   template <typename T> inline void setParam(const ID & param, T value);
   inline const Parameter & getParam(const ID & param) const;
 
   template <typename T>
   void flattenInternal(const std::string & field_id,
                        ElementTypeMapArray<T> & internal_flat,
                        const GhostType ghost_type = _not_ghost,
                        ElementKind element_kind = _ek_not_defined) const;
 
   /// apply a constant eigengrad_u everywhere in the material
   virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
                                const GhostType = _not_ghost);
 
   /// specify if the matrix need to be recomputed for this material
   virtual bool hasStiffnessMatrixChanged() { return true; }
 
 protected:
   bool isInit() const { return is_init; }
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// boolean to know if the material has been initialized
   bool is_init;
 
   std::map<ID, InternalField<Real> *> internal_vectors_real;
   std::map<ID, InternalField<UInt> *> internal_vectors_uint;
   std::map<ID, InternalField<bool> *> internal_vectors_bool;
 
 protected:
   /// Link to the fem object in the model
   FEEngine & fem;
 
   /// Finite deformation
   bool finite_deformation;
 
   /// Finite deformation
   bool inelastic_deformation;
 
   /// material name
   std::string name;
 
   /// The model to witch the material belong
   SolidMechanicsModel & model;
 
   /// density : rho
   Real rho;
 
   /// spatial dimension
   UInt spatial_dimension;
 
   /// list of element handled by the material
   ElementTypeMapArray<UInt> element_filter;
 
   /// stresses arrays ordered by element types
   InternalField<Real> stress;
 
   /// eigengrad_u arrays ordered by element types
   InternalField<Real> eigengradu;
 
   /// grad_u arrays ordered by element types
   InternalField<Real> gradu;
 
   /// Green Lagrange strain (Finite deformation)
   InternalField<Real> green_strain;
 
   /// Second Piola-Kirchhoff stress tensor arrays ordered by element types
   /// (Finite deformation)
   InternalField<Real> piola_kirchhoff_2;
 
   /// potential energy by element
   InternalField<Real> potential_energy;
 
   /// tell if using in non local mode or not
   bool is_non_local;
 
   /// tell if the material need the previous stress state
   bool use_previous_stress;
 
   /// tell if the material need the previous strain state
   bool use_previous_gradu;
 
   /// elemental field interpolation coordinates
   InternalField<Real> interpolation_inverse_coordinates;
 
   /// elemental field interpolation points
   InternalField<Real> interpolation_points_matrices;
 
   /// vector that contains the names of all the internals that need to
   /// be transferred when material interfaces move
   std::vector<ID> internals_to_transfer;
 };
 
 /// standard output stream operator
 inline std::ostream & operator<<(std::ostream & stream,
                                  const Material & _this) {
   _this.printself(stream);
   return stream;
 }
 
 } // namespace akantu
 
 #include "material_inline_impl.cc"
 
 #include "internal_field_tmpl.hh"
 #include "random_internal_field_tmpl.hh"
 
 /* -------------------------------------------------------------------------- */
 /* Auto loop                                                                  */
 /* -------------------------------------------------------------------------- */
 /// This can be used to automatically write the loop on quadrature points in
 /// functions such as computeStress. This macro in addition to write the loop
 /// provides two tensors (matrices) sigma and grad_u
 #define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type)       \
   Array<Real>::matrix_iterator gradu_it =                                      \
       this->gradu(el_type, ghost_type)                                         \
           .begin(this->spatial_dimension, this->spatial_dimension);            \
   Array<Real>::matrix_iterator gradu_end =                                     \
       this->gradu(el_type, ghost_type)                                         \
           .end(this->spatial_dimension, this->spatial_dimension);              \
                                                                                \
   this->stress(el_type, ghost_type)                                            \
       .resize(this->gradu(el_type, ghost_type).size());                        \
                                                                                \
   Array<Real>::iterator<Matrix<Real>> stress_it =                              \
       this->stress(el_type, ghost_type)                                        \
           .begin(this->spatial_dimension, this->spatial_dimension);            \
                                                                                \
   if (this->isFiniteDeformation()) {                                           \
     this->piola_kirchhoff_2(el_type, ghost_type)                               \
         .resize(this->gradu(el_type, ghost_type).size());                      \
     stress_it = this->piola_kirchhoff_2(el_type, ghost_type)                   \
                     .begin(this->spatial_dimension, this->spatial_dimension);  \
   }                                                                            \
                                                                                \
   for (; gradu_it != gradu_end; ++gradu_it, ++stress_it) {                     \
     Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it;                 \
     Matrix<Real> & __attribute__((unused)) sigma = *stress_it
 
 #define MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END }
 
 /// This can be used to automatically write the loop on quadrature points in
 /// functions such as computeTangentModuli. This macro in addition to write the
 /// loop provides two tensors (matrices) sigma_tensor, grad_u, and a matrix
 /// where the elemental tangent moduli should be stored in Voigt Notation
 #define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_BEGIN(tangent_mat)              \
   Array<Real>::matrix_iterator gradu_it =                                      \
       this->gradu(el_type, ghost_type)                                         \
           .begin(this->spatial_dimension, this->spatial_dimension);            \
   Array<Real>::matrix_iterator gradu_end =                                     \
       this->gradu(el_type, ghost_type)                                         \
           .end(this->spatial_dimension, this->spatial_dimension);              \
   Array<Real>::matrix_iterator sigma_it =                                      \
       this->stress(el_type, ghost_type)                                        \
           .begin(this->spatial_dimension, this->spatial_dimension);            \
                                                                                \
   tangent_mat.resize(this->gradu(el_type, ghost_type).size());                 \
                                                                                \
   UInt tangent_size =                                                          \
       this->getTangentStiffnessVoigtSize(this->spatial_dimension);             \
   Array<Real>::matrix_iterator tangent_it =                                    \
       tangent_mat.begin(tangent_size, tangent_size);                           \
                                                                                \
   for (; gradu_it != gradu_end; ++gradu_it, ++sigma_it, ++tangent_it) {        \
     Matrix<Real> & __attribute__((unused)) grad_u = *gradu_it;                 \
     Matrix<Real> & __attribute__((unused)) sigma_tensor = *sigma_it;           \
     Matrix<Real> & tangent = *tangent_it
 
 #define MATERIAL_TANGENT_QUADRATURE_POINT_LOOP_END }
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 using MaterialFactory =
     Factory<Material, ID, UInt, const ID &, SolidMechanicsModel &, const ID &>;
 } // namespace akantu
 
 #define INSTANTIATE_MATERIAL_ONLY(mat_name)                                    \
   template class mat_name<1>;                                                  \
   template class mat_name<2>;                                                  \
   template class mat_name<3>
 
 #define MATERIAL_DEFAULT_PER_DIM_ALLOCATOR(id, mat_name)                       \
   [](UInt dim, const ID &, SolidMechanicsModel & model,                        \
      const ID & id) -> std::unique_ptr<Material> {                             \
     switch (dim) {                                                             \
     case 1:                                                                    \
       return std::make_unique<mat_name<1>>(model, id);                         \
     case 2:                                                                    \
       return std::make_unique<mat_name<2>>(model, id);                         \
     case 3:                                                                    \
       return std::make_unique<mat_name<3>>(model, id);                         \
     default:                                                                   \
       AKANTU_EXCEPTION("The dimension "                                        \
                        << dim << "is not a valid dimension for the material "  \
                        << #id);                                                \
     }                                                                          \
   }
 
 #define INSTANTIATE_MATERIAL(id, mat_name)                                     \
   INSTANTIATE_MATERIAL_ONLY(mat_name);                                         \
   static bool material_is_alocated_##id [[gnu::unused]] =                      \
       MaterialFactory::getInstance().registerAllocator(                        \
           #id, MATERIAL_DEFAULT_PER_DIM_ALLOCATOR(id, mat_name))
 
 #endif /* __AKANTU_MATERIAL_HH__ */
diff --git a/src/model/solid_mechanics/materials/material_python/material_python.hh b/src/model/solid_mechanics/materials/material_python/material_python.hh
index badec2b76..9237401dd 100644
--- a/src/model/solid_mechanics/materials/material_python/material_python.hh
+++ b/src/model/solid_mechanics/materials/material_python/material_python.hh
@@ -1,120 +1,119 @@
 /**
  * @file   material_python.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date creation: Fri Nov 13 2015
  * @date last modification: Fri Nov 13 2015
  *
  * @brief  Python material
  *
  * @section LICENSE
  *
  * Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory
  * (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /**
  * @file   material_python.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "python_functor.hh"
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_PYTHON_HH__
 #define __AKANTU_MATERIAL_PYTHON_HH__
 
 /* -------------------------------------------------------------------------- */
 
 
 
 namespace akantu {
 
 class MaterialPython : public Material, PythonFunctor {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   MaterialPython(SolidMechanicsModel & model, PyObject * obj,
                  const ID & id = "");
 
   ~MaterialPython() override = default;
-  ;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   void registerInternals();
 
   void initMaterial() override;
 
   /// constitutive law for all element of a type
   void computeStress(ElementType el_type,
                      GhostType ghost_type = _not_ghost) override;
 
   /// constitutive law for a given quad point
   template <typename it_type>
   void computeStress(Matrix<Real> & grad_u, Matrix<Real> & sigma,
                      std::vector<it_type> & internal_iterators);
 
   /// compute the tangent stiffness matrix for an element type
   void computeTangentModuli(const ElementType & el_type,
                             Array<Real> & tangent_matrix,
                             GhostType ghost_type = _not_ghost) override;
 
   /// compute the push wave speed of the material
   Real getPushWaveSpeed(const Element & element) const override;
 
 protected:
   /// update the dissipated energy, must be called after the stress have been
   /// computed
   // virtual void updateEnergies(ElementType el_type, GhostType ghost_type){};
 
   /// compute the tangent stiffness matrix for a given quadrature point
   // inline void computeTangentModuliOnQuad(Matrix<Real> & tangent, Real &
   // dam){};
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   // virtual Real getEnergy(std::string type){};
   // virtual Real getEnergy(std::string energy_id, ElementType type, UInt
   // index){};
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   std::map<std::string, Real> local_params;
   std::map<std::string, InternalField<Real> *> internals;
 };
 
 } // akantu
 
 #endif /* __AKANTU_MATERIAL_PYTHON_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model.hh b/src/model/solid_mechanics/solid_mechanics_model.hh
index f015fb6d5..19bdd2dd2 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,562 +1,556 @@
 /**
  * @file   solid_mechanics_model.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Daniel Pino Muñoz <daniel.pinomunoz@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Tue Jul 27 2010
  * @date last modification: Tue Jan 19 2016
  *
  * @brief  Model of Solid Mechanics
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 /* -------------------------------------------------------------------------- */
 #include "boundary_condition.hh"
 #include "data_accessor.hh"
 #include "fe_engine.hh"
 #include "model.hh"
 #include "non_local_manager.hh"
 #include "solid_mechanics_model_event_handler.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLID_MECHANICS_MODEL_HH__
 #define __AKANTU_SOLID_MECHANICS_MODEL_HH__
 
 namespace akantu {
 class Material;
 class MaterialSelector;
 class DumperIOHelper;
 class NonLocalManager;
 template <ElementKind kind, class IntegrationOrderFunctor>
 class IntegratorGauss;
 template <ElementKind kind> class ShapeLagrange;
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
 
 /* -------------------------------------------------------------------------- */
 class SolidMechanicsModel
     : public Model,
-      public DataAccessor<Element>,
+      public TemporarySwigDataAccessor<Element>,
       public DataAccessor<UInt>,
       public BoundaryCondition<SolidMechanicsModel>,
       public NonLocalManagerCallback,
       public EventHandlerManager<SolidMechanicsModelEventHandler> {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   class NewMaterialElementsEvent : public NewElementsEvent {
   public:
     AKANTU_GET_MACRO_NOT_CONST(MaterialList, material, Array<UInt> &);
     AKANTU_GET_MACRO(MaterialList, material, const Array<UInt> &);
 
   protected:
     Array<UInt> material;
   };
 
   using MyFEEngineType = FEEngineTemplate<IntegratorGauss, ShapeLagrange>;
 
 protected:
   using EventManager = EventHandlerManager<SolidMechanicsModelEventHandler>;
 
 public:
   SolidMechanicsModel(
       Mesh & mesh, UInt spatial_dimension = _all_dimensions,
       const ID & id = "solid_mechanics_model", const MemoryID & memory_id = 0,
       const ModelType model_type = ModelType::_solid_mechanics_model);
 
   ~SolidMechanicsModel() override;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 protected:
   /// initialize completely the model
   void initFullImpl(
       const ModelOptions & options = SolidMechanicsModelOptions()) override;
 
   /// initialize all internal arrays for materials
   virtual void initMaterials();
 
   /// initialize the model
   void initModel() override;
 
   /// function to print the containt of the class
   void printself(std::ostream & stream, int indent = 0) const override;
 
   /// get some default values for derived classes
   std::tuple<ID, TimeStepSolverType>
   getDefaultSolverID(const AnalysisMethod & method) override;
 
   /* ------------------------------------------------------------------------ */
   /* Solver interface                                                         */
   /* ------------------------------------------------------------------------ */
 public:
   /// assembles the stiffness matrix,
   virtual void assembleStiffnessMatrix();
   /// assembles the internal forces in the array internal_forces
   virtual void assembleInternalForces();
 
 protected:
   /// callback for the solver, this adds f_{ext} - f_{int} to the residual
   void assembleResidual() override;
 
   /// get the type of matrix needed
   MatrixType getMatrixType(const ID & matrix_id) override;
 
   /// callback for the solver, this assembles different matrices
   void assembleMatrix(const ID & matrix_id) override;
 
   /// callback for the solver, this assembles the stiffness matrix
   void assembleLumpedMatrix(const ID & matrix_id) override;
 
   /// callback for the solver, this is called at beginning of solve
   void predictor() override;
   /// callback for the solver, this is called at end of solve
   void corrector() override;
 
   /// callback for the solver, this is called at beginning of solve
   void beforeSolveStep() override;
   /// callback for the solver, this is called at end of solve
   void afterSolveStep() override;
 
   /// Callback for the model to instantiate the matricees when needed
   void initSolver(TimeStepSolverType time_step_solver_type,
                   NonLinearSolverType non_linear_solver_type) override;
 
 protected:
   /* ------------------------------------------------------------------------ */
   TimeStepSolverType getDefaultSolverType() const override;
   /* ------------------------------------------------------------------------ */
   ModelSolverOptions
   getDefaultSolverOptions(const TimeStepSolverType & type) const override;
 
 public:
   bool isDefaultSolverExplicit() {
     return method == _explicit_lumped_mass ||
            method == _explicit_consistent_mass;
   }
 
 protected:
   /// update the current position vector
   void updateCurrentPosition();
 
   /* ------------------------------------------------------------------------ */
   /* Materials (solid_mechanics_model_material.cc)                            */
   /* ------------------------------------------------------------------------ */
 public:
   /// register an empty material of a given type
   Material & registerNewMaterial(const ID & mat_name, const ID & mat_type,
                                  const ID & opt_param);
 
   /// reassigns materials depending on the material selector
   virtual void reassignMaterial();
 
   /// apply a constant eigen_grad_u on all quadrature points of a given material
   virtual void applyEigenGradU(const Matrix<Real> & prescribed_eigen_grad_u,
                                const ID & material_name,
                                const GhostType ghost_type = _not_ghost);
 
 protected:
   /// register a material in the dynamic database
   Material & registerNewMaterial(const ParserSection & mat_section);
 
   /// read the material files to instantiate all the materials
   void instantiateMaterials();
 
   /// set the element_id_by_material and add the elements to the good materials
   virtual void
   assignMaterialToElements(const ElementTypeMapArray<UInt> * filter = nullptr);
 
   /* ------------------------------------------------------------------------ */
   /* Mass (solid_mechanics_model_mass.cc)                                     */
   /* ------------------------------------------------------------------------ */
 public:
   /// assemble the lumped mass matrix
   void assembleMassLumped();
 
   /// assemble the mass matrix for consistent mass resolutions
   void assembleMass();
 
 protected:
   /// assemble the lumped mass matrix for local and ghost elements
   void assembleMassLumped(GhostType ghost_type);
 
   /// assemble the mass matrix for either _ghost or _not_ghost elements
   void assembleMass(GhostType ghost_type);
 
   /// fill a vector of rho
   void computeRho(Array<Real> & rho, ElementType type, GhostType ghost_type);
 
   /// compute the kinetic energy
   Real getKineticEnergy();
   Real getKineticEnergy(const ElementType & type, UInt index);
 
   /// compute the external work (for impose displacement, the velocity should be
   /// given too)
   Real getExternalWork();
 
   /* ------------------------------------------------------------------------ */
   /* NonLocalManager inherited members                                        */
   /* ------------------------------------------------------------------------ */
 protected:
   void initializeNonLocal() override;
 
   void updateDataForNonLocalCriterion(ElementTypeMapReal & criterion) override;
 
   void computeNonLocalStresses(const GhostType & ghost_type) override;
 
   void
   insertIntegrationPointsInNeighborhoods(const GhostType & ghost_type) override;
 
   /// update the values of the non local internal
   void updateLocalInternal(ElementTypeMapReal & internal_flat,
                            const GhostType & ghost_type,
                            const ElementKind & kind) override;
 
   /// copy the results of the averaging in the materials
   void updateNonLocalInternal(ElementTypeMapReal & internal_flat,
                               const GhostType & ghost_type,
                               const ElementKind & kind) override;
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
   UInt getNbData(const Array<Element> & elements,
                  const SynchronizationTag & tag) const override;
 
   void packData(CommunicationBuffer & buffer, const Array<Element> & elements,
                 const SynchronizationTag & tag) const override;
 
   void unpackData(CommunicationBuffer & buffer, const Array<Element> & elements,
                   const SynchronizationTag & tag) override;
 
   UInt getNbData(const Array<UInt> & dofs,
                  const SynchronizationTag & tag) const override;
 
   void packData(CommunicationBuffer & buffer, const Array<UInt> & dofs,
                 const SynchronizationTag & tag) const override;
 
   void unpackData(CommunicationBuffer & buffer, const Array<UInt> & dofs,
                   const SynchronizationTag & tag) override;
 
 protected:
   void
   splitElementByMaterial(const Array<Element> & elements,
                          std::vector<Array<Element>> & elements_per_mat) const;
 
   template <typename Operation>
   void splitByMaterial(const Array<Element> & elements, Operation && op) const;
 
   /* ------------------------------------------------------------------------ */
   /* Mesh Event Handler inherited members                                     */
   /* ------------------------------------------------------------------------ */
 protected:
   void onNodesAdded(const Array<UInt> & nodes_list,
                     const NewNodesEvent & event) override;
   void onNodesRemoved(const Array<UInt> & element_list,
                       const Array<UInt> & new_numbering,
                       const RemovedNodesEvent & event) override;
   void onElementsAdded(const Array<Element> & nodes_list,
                        const NewElementsEvent & event) override;
   void onElementsRemoved(const Array<Element> & element_list,
                          const ElementTypeMapArray<UInt> & new_numbering,
                          const RemovedElementsEvent & event) override;
   void onElementsChanged(const Array<Element> &, const Array<Element> &,
                          const ElementTypeMapArray<UInt> &,
                          const ChangedElementsEvent &) override{};
 
   /* ------------------------------------------------------------------------ */
   /* Dumpable interface (kept for convenience) and dumper relative functions  */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void onDump();
 
   //! decide wether a field is a material internal or not
   bool isInternal(const std::string & field_name,
                   const ElementKind & element_kind);
 #ifndef SWIG
   //! give the amount of data per element
   virtual ElementTypeMap<UInt>
   getInternalDataPerElem(const std::string & field_name,
                          const ElementKind & kind);
 
   //! flatten a given material internal field
   ElementTypeMapArray<Real> &
   flattenInternal(const std::string & field_name, const ElementKind & kind,
                   const GhostType ghost_type = _not_ghost);
   //! flatten all the registered material internals
   void flattenAllRegisteredInternals(const ElementKind & kind);
 #endif
 
   dumper::Field * createNodalFieldReal(const std::string & field_name,
                                        const std::string & group_name,
                                        bool padding_flag) override;
 
   dumper::Field * createNodalFieldBool(const std::string & field_name,
                                        const std::string & group_name,
                                        bool padding_flag) override;
 
   dumper::Field * createElementalField(const std::string & field_name,
                                        const std::string & group_name,
                                        bool padding_flag,
                                        const UInt & spatial_dimension,
                                        const ElementKind & kind) override;
 
   virtual void dump(const std::string & dumper_name);
 
   virtual void dump(const std::string & dumper_name, UInt step);
 
   virtual void dump(const std::string & dumper_name, Real time, UInt step);
 
   void dump() override;
 
   virtual void dump(UInt step);
 
   virtual void dump(Real time, UInt step);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// return the dimension of the system space
   AKANTU_GET_MACRO(SpatialDimension, Model::spatial_dimension, UInt);
 
   /// set the value of the time step
   void setTimeStep(Real time_step, const ID & solver_id = "") override;
 
   /// get the value of the conversion from forces/ mass to acceleration
   AKANTU_GET_MACRO(F_M2A, f_m2a, Real);
 
   /// set the value of the conversion from forces/ mass to acceleration
   AKANTU_SET_MACRO(F_M2A, f_m2a, Real);
 
   /// get the SolidMechanicsModel::displacement vector
   AKANTU_GET_MACRO(Displacement, *displacement, Array<Real> &);
 
   /// get the SolidMechanicsModel::previous_displacement vector
   AKANTU_GET_MACRO(PreviousDisplacement, *previous_displacement, Array<Real> &);
 
   /// get the SolidMechanicsModel::current_position vector \warn only consistent
   /// after a call to SolidMechanicsModel::updateCurrentPosition
   const Array<Real> & getCurrentPosition();
 
   /// get  the SolidMechanicsModel::increment  vector \warn  only  consistent if
   /// SolidMechanicsModel::setIncrementFlagOn has been called before
   AKANTU_GET_MACRO(Increment, *displacement_increment, Array<Real> &);
 
   /// get the lumped SolidMechanicsModel::mass vector
   AKANTU_GET_MACRO(Mass, *mass, Array<Real> &);
 
   /// get the SolidMechanicsModel::velocity vector
   AKANTU_GET_MACRO(Velocity, *velocity, Array<Real> &);
 
   /// get    the    SolidMechanicsModel::acceleration    vector,   updated    by
   /// SolidMechanicsModel::updateAcceleration
   AKANTU_GET_MACRO(Acceleration, *acceleration, Array<Real> &);
 
   /// get the SolidMechanicsModel::force vector (external forces)
   AKANTU_GET_MACRO(Force, *external_force, Array<Real> &);
 
   /// get the SolidMechanicsModel::internal_force vector (internal forces)
   AKANTU_GET_MACRO(InternalForce, *internal_force, Array<Real> &);
 
   /// get the SolidMechanicsModel::blocked_dofs vector
   AKANTU_GET_MACRO(BlockedDOFs, *blocked_dofs, Array<bool> &);
 
   /// get the value of the SolidMechanicsModel::increment_flag
   AKANTU_GET_MACRO(IncrementFlag, increment_flag, bool);
 
   /// get a particular material (by material index)
   inline Material & getMaterial(UInt mat_index);
 
   /// get a particular material (by material index)
   inline const Material & getMaterial(UInt mat_index) const;
 
   /// get a particular material (by material name)
   inline Material & getMaterial(const std::string & name);
 
   /// get a particular material (by material name)
   inline const Material & getMaterial(const std::string & name) const;
 
   /// get a particular material id from is name
   inline UInt getMaterialIndex(const std::string & name) const;
 
   /// give the number of materials
   inline UInt getNbMaterials() const { return materials.size(); }
 
   /// give the material internal index from its id
   Int getInternalIndexFromID(const ID & id) const;
 
   /// compute the stable time step
   Real getStableTimeStep();
 
   /// get the energies
   Real getEnergy(const std::string & energy_id);
 
   /// compute the energy for energy
   Real getEnergy(const std::string & energy_id, const ElementType & type,
                  UInt index);
 
   AKANTU_GET_MACRO(MaterialByElement, material_index,
                    const ElementTypeMapArray<UInt> &);
 
   /// vectors containing local material element index for each global element
   /// index
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialByElement, material_index,
                                          UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialByElement, material_index, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(MaterialLocalNumbering,
                                          material_local_numbering, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(MaterialLocalNumbering,
                                    material_local_numbering, UInt);
 
   AKANTU_GET_MACRO_NOT_CONST(MaterialSelector, *material_selector,
                              MaterialSelector &);
   AKANTU_SET_MACRO(MaterialSelector, material_selector,
                    std::shared_ptr<MaterialSelector>);
 
   /// Access the non_local_manager interface
   AKANTU_GET_MACRO(NonLocalManager, *non_local_manager, NonLocalManager &);
 
   /// get the FEEngine object to integrate or interpolate on the boundary
   FEEngine & getFEEngineBoundary(const ID & name = "") override;
 
 protected:
   friend class Material;
 
 protected:
 
   /// compute the stable time step
   Real getStableTimeStep(const GhostType & ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   /// conversion coefficient form force/mass to acceleration
   Real f_m2a;
 
   /// displacements array
   Array<Real> * displacement;
   UInt displacement_release{0};
 
   /// displacements array at the previous time step (used in finite deformation)
   Array<Real> * previous_displacement{nullptr};
 
   /// increment of displacement
   Array<Real> * displacement_increment{nullptr};
 
   /// lumped mass array
   Array<Real> * mass{nullptr};
 
   /// Check if materials need to recompute the mass array
   bool need_to_reassemble_lumped_mass{true};
   /// Check if materials need to recompute the mass matrix
   bool need_to_reassemble_mass{true};
 
   /// velocities array
   Array<Real> * velocity{nullptr};
 
   /// accelerations array
   Array<Real> * acceleration{nullptr};
 
   /// accelerations array
   // Array<Real> * increment_acceleration;
 
   /// external forces array
   Array<Real> * external_force{nullptr};
 
   /// internal forces array
   Array<Real> * internal_force{nullptr};
 
   /// array specifing if a degree of freedom is blocked or not
   Array<bool> * blocked_dofs{nullptr};
 
   /// array of current position used during update residual
   Array<Real> * current_position{nullptr};
   UInt current_position_release{0};
 
   /// Arrays containing the material index for each element
   ElementTypeMapArray<UInt> material_index;
 
   /// Arrays containing the position in the element filter of the material
   /// (material's local numbering)
   ElementTypeMapArray<UInt> material_local_numbering;
 
-#ifdef SWIGPYTHON
-public:
-#endif
   /// list of used materials
   std::vector<std::unique_ptr<Material>> materials;
 
   /// mapping between material name and material internal id
   std::map<std::string, UInt> materials_names_to_id;
-#ifdef SWIGPYTHON
-protected:
-#endif
 
   /// class defining of to choose a material
   std::shared_ptr<MaterialSelector> material_selector;
 
   /// flag defining if the increment must be computed or not
   bool increment_flag;
 
   /// tells if the material are instantiated
   bool are_materials_instantiated;
 
   using flatten_internal_map = std::map<std::pair<std::string, ElementKind>,
                                         ElementTypeMapArray<Real> *>;
 
   /// map a registered internals to be flattened for dump purposes
   flatten_internal_map registered_internals;
 
   /// non local manager
   std::unique_ptr<NonLocalManager> non_local_manager;
 };
 
 /* -------------------------------------------------------------------------- */
 namespace BC {
   namespace Neumann {
     using FromStress = FromHigherDim;
     using FromTraction = FromSameDim;
   } // namespace Neumann
 } // namespace BC
 
 } // namespace akantu
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "material.hh"
 #include "parser.hh"
 
 #include "solid_mechanics_model_inline_impl.cc"
 #include "solid_mechanics_model_tmpl.hh"
 /* -------------------------------------------------------------------------- */
 
 #endif /* __AKANTU_SOLID_MECHANICS_MODEL_HH__ */
diff --git a/src/synchronizer/data_accessor.hh b/src/synchronizer/data_accessor.hh
index cebcb66b3..577e3e551 100644
--- a/src/synchronizer/data_accessor.hh
+++ b/src/synchronizer/data_accessor.hh
@@ -1,279 +1,283 @@
 /**
  * @file   data_accessor.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Wed Sep 01 2010
  * @date last modification: Tue Dec 08 2015
  *
  * @brief  Interface of accessors for pack_unpack system
  *
  * @section LICENSE
  *
  * Copyright (©)  2010-2012, 2014,  2015 EPFL  (Ecole Polytechnique  Fédérale de
  * Lausanne)  Laboratory (LSMS  -  Laboratoire de  Simulation  en Mécanique  des
  * Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "communication_buffer.hh"
 #include "element.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_DATA_ACCESSOR_HH__
 #define __AKANTU_DATA_ACCESSOR_HH__
 
 namespace akantu {
 class FEEngine;
 } // akantu
 
 namespace akantu {
 
 class DataAccessorBase {
 public:
   DataAccessorBase() = default;
   virtual ~DataAccessorBase() = default;
 };
 
 template <class T> class DataAccessor : public virtual DataAccessorBase {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   DataAccessor() = default;
   ~DataAccessor() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /**
    * @brief get  the number of  data to exchange  for a given array of T
    * (elements or dofs) and a given akantu::SynchronizationTag
    */
   virtual UInt getNbData(const Array<T> & elements,
                          const SynchronizationTag & tag) const = 0;
 
   /**
    * @brief pack the data for a given array of T (elements or dofs) and a given
    * akantu::SynchronizationTag
    */
   virtual void packData(CommunicationBuffer & buffer, const Array<T> & element,
                         const SynchronizationTag & tag) const = 0;
 
   /**
    * @brief unpack the data for a given array of T (elements or dofs) and a
    * given akantu::SynchronizationTag
    */
   virtual void unpackData(CommunicationBuffer & buffer,
                           const Array<T> & element,
                           const SynchronizationTag & tag) = 0;
 };
 
 /* -------------------------------------------------------------------------- */
 /* Specialization                                                             */
 /* -------------------------------------------------------------------------- */
 template <> class DataAccessor<Element> : public virtual DataAccessorBase {
 public:
   DataAccessor() = default;
   ~DataAccessor() override = default;
 
   virtual UInt getNbData(const Array<Element> & elements,
                          const SynchronizationTag & tag) const = 0;
   virtual void packData(CommunicationBuffer & buffer,
                         const Array<Element> & element,
                         const SynchronizationTag & tag) const = 0;
   virtual void unpackData(CommunicationBuffer & buffer,
                           const Array<Element> & element,
                           const SynchronizationTag & tag) = 0;
 
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T, bool pack_helper>
   static void
   packUnpackNodalDataHelper(Array<T> & data, CommunicationBuffer & buffer,
                             const Array<Element> & elements, const Mesh & mesh);
 
   /* ------------------------------------------------------------------------ */
   template <typename T, bool pack_helper>
   static void packUnpackElementalDataHelper(
       ElementTypeMapArray<T> & data_to_pack, CommunicationBuffer & buffer,
       const Array<Element> & element, bool per_quadrature_point_data,
       const FEEngine & fem);
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   static void
   packNodalDataHelper(const Array<T> & data, CommunicationBuffer & buffer,
                       const Array<Element> & elements, const Mesh & mesh) {
     packUnpackNodalDataHelper<T, true>(const_cast<Array<T> &>(data), buffer,
                                        elements, mesh);
   }
 
   template <typename T>
   static inline void
   unpackNodalDataHelper(Array<T> & data, CommunicationBuffer & buffer,
                         const Array<Element> & elements, const Mesh & mesh) {
     packUnpackNodalDataHelper<T, false>(data, buffer, elements, mesh);
   }
 
   /* ------------------------------------------------------------------------ */
   template <typename T>
   static inline void
   packElementalDataHelper(const ElementTypeMapArray<T> & data_to_pack,
                           CommunicationBuffer & buffer,
                           const Array<Element> & elements,
                           bool per_quadrature_point, const FEEngine & fem) {
     packUnpackElementalDataHelper<T, true>(
         const_cast<ElementTypeMapArray<T> &>(data_to_pack), buffer, elements,
         per_quadrature_point, fem);
   }
 
   template <typename T>
   static inline void
   unpackElementalDataHelper(ElementTypeMapArray<T> & data_to_unpack,
                             CommunicationBuffer & buffer,
                             const Array<Element> & elements,
                             bool per_quadrature_point, const FEEngine & fem) {
     packUnpackElementalDataHelper<T, false>(data_to_unpack, buffer, elements,
                                             per_quadrature_point, fem);
   }
 };
 
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 template <> class DataAccessor<UInt> : public virtual DataAccessorBase {
 public:
   DataAccessor() = default;
   ~DataAccessor() override = default;
 
   virtual UInt getNbData(const Array<UInt> & elements,
                          const SynchronizationTag & tag) const = 0;
   virtual void packData(CommunicationBuffer & buffer,
                         const Array<UInt> & element,
                         const SynchronizationTag & tag) const = 0;
   virtual void unpackData(CommunicationBuffer & buffer,
                           const Array<UInt> & element,
                           const SynchronizationTag & tag) = 0;
   /* ------------------------------------------------------------------------ */
 public:
   template <typename T, bool pack_helper>
   static void packUnpackDOFDataHelper(Array<T> & data,
                                       CommunicationBuffer & buffer,
                                       const Array<UInt> & dofs);
 
   template <typename T>
   static inline void packDOFDataHelper(const Array<T> & data_to_pack,
                                        CommunicationBuffer & buffer,
                                        const Array<UInt> & dofs) {
     packUnpackDOFDataHelper<T, true>(const_cast<Array<T> &>(data_to_pack),
                                      buffer, dofs);
   }
 
   template <typename T>
   static inline void unpackDOFDataHelper(Array<T> & data_to_unpack,
                                          CommunicationBuffer & buffer,
                                          const Array<UInt> & dofs) {
     packUnpackDOFDataHelper<T, false>(data_to_unpack, buffer, dofs);
   }
 };
 
 /* -------------------------------------------------------------------------- */
 template <typename T> class AddOperation {
 public:
   inline T operator()(T & a, T & b) { return a + b; };
 };
 
 template <typename T> class IdentityOperation {
 public:
   inline T & operator()(T &, T & b) { return b; };
 };
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 template <template <class> class Op, class T>
 class ReduceUIntDataAccessor : public virtual DataAccessor<UInt> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   ReduceUIntDataAccessor(Array<T> & data, const SynchronizationTag & tag)
       : data(data), tag(tag) {}
 
   ~ReduceUIntDataAccessor() override = default;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /* ------------------------------------------------------------------------ */
   UInt getNbData(const Array<UInt> & elements,
                  const SynchronizationTag & tag) const override {
     if (tag != this->tag)
       return 0;
 
     Vector<T> tmp(data.getNbComponent());
     return elements.size() * CommunicationBuffer::sizeInBuffer(tmp);
   }
 
   /* ------------------------------------------------------------------------ */
   void packData(CommunicationBuffer & buffer, const Array<UInt> & elements,
                 const SynchronizationTag & tag) const override {
     if (tag != this->tag)
       return;
 
     auto data_it = data.begin(data.getNbComponent());
     for (auto el : elements) {
       buffer << Vector<T>(data_it[el]);
     }
   }
 
   /* ------------------------------------------------------------------------ */
   void unpackData(CommunicationBuffer & buffer, const Array<UInt> & elements,
                   const SynchronizationTag & tag) override {
     if (tag != this->tag)
       return;
 
     auto data_it = data.begin(data.getNbComponent());
     for (auto el : elements) {
       Vector<T> unpacked(data.getNbComponent());
       Vector<T> vect(data_it[el]);
       buffer >> unpacked;
 
       vect = oper(vect, unpacked);
     }
   }
 
 protected:
   /// data to (un)pack
   Array<T> & data;
 
   /// Tag to consider
   SynchronizationTag tag;
 
   /// reduction operator
   Op<Vector<T>> oper;
 };
 
 /* -------------------------------------------------------------------------- */
 template <class T>
 using SimpleUIntDataAccessor = ReduceUIntDataAccessor<IdentityOperation, T>;
 
+template <class T>
+using TemporarySwigDataAccessor = DataAccessor<T>;
+
+
 } // akantu
 
 #endif /* __AKANTU_DATA_ACCESSOR_HH__ */