diff --git a/cmake/AkantuBuildTreeSettings.cmake.in b/cmake/AkantuBuildTreeSettings.cmake.in
index 207b86b22..fe20feff6 100644
--- a/cmake/AkantuBuildTreeSettings.cmake.in
+++ b/cmake/AkantuBuildTreeSettings.cmake.in
@@ -1,34 +1,35 @@
 #===============================================================================
 # @file   AkantuBuildTreeSettings.cmake.in
 #
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date   Thu Dec 01 18:00:05 2011
 #
 # @brief  Configuration for link with build tree
 #
 # @section LICENSE
 #
 # Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
 # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
 #
 # Akantu is free  software: you can redistribute it and/or  modify it under the
 # terms  of the  GNU Lesser  General Public  License as  published by  the Free
 # Software Foundation, either version 3 of the License, or (at your option) any
 # later version.
 #
 # Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
 # details.
 #
 # You should  have received  a copy  of the GNU  Lesser General  Public License
 # along with Akantu. If not, see <http://www.gnu.org/licenses/>.
 #
 #===============================================================================
 
 set(AKANTU_INCLUDE_DIR
   "@AKANTU_INCLUDE_DIRS@"
   )
 
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "@CMAKE_SOURCE_DIR@/cmake")
\ No newline at end of file
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "@CMAKE_SOURCE_DIR@/cmake")
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "@CMAKE_SOURCE_DIR@/cmake/Modules")
\ No newline at end of file
diff --git a/cmake/AkantuInstall.cmake b/cmake/AkantuInstall.cmake
index ef646cd30..206de39d5 100644
--- a/cmake/AkantuInstall.cmake
+++ b/cmake/AkantuInstall.cmake
@@ -1,123 +1,123 @@
 #===============================================================================
 # @file   AkantuInstall.cmake
 #
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date   Wed Oct 17 15:19:18 2012
 #
 # @brief  Create the files that allows users to link with Akantu in an other
 # cmake project
 #
 # @section LICENSE
 #
 # Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
 # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
 #
 # Akantu is free  software: you can redistribute it and/or  modify it under the
 # terms  of the  GNU Lesser  General Public  License as  published by  the Free
 # Software Foundation, either version 3 of the License, or (at your option) any
 # later version.
 #
 # Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
 # details.
 #
 # You should  have received  a copy  of the GNU  Lesser General  Public License
 # along with Akantu. If not, see <http://www.gnu.org/licenses/>.
 #
 #===============================================================================
 
 #===============================================================================
 # Config gen for external packages
 #===============================================================================
 configure_file(cmake/AkantuBuildTreeSettings.cmake.in  "${PROJECT_BINARY_DIR}/AkantuBuildTreeSettings.cmake" @ONLY)
 
 file(WRITE "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
 #===============================================================================
 # @file   AkantuConfigInclude.cmake
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 # @date   Fri Jun 11 09:46:59 2010
 #
 # @section LICENSE
 #
 # Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
 # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
 #
 # Akantu is free  software: you can redistribute it and/or  modify it under the
 # terms  of the  GNU Lesser  General Public  License as  published by  the Free
 # Software Foundation, either version 3 of the License, or (at your option) any
 # later version.
 #
 # Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
 # details.
 #
 # You should  have received  a copy  of the GNU  Lesser General  Public License
 # along with Akantu. If not, see <http://www.gnu.org/licenses/>.
 #
 # @section DESCRIPTION
 #
 #===============================================================================
 
 ")
 
-foreach(_option ${PACKAGE_SYSTEM_PACKAGES_NAMES_LIST_ALL})
+foreach(_option ${AKANTU_PACKAGE_SYSTEM_PACKAGES_NAMES_LIST_ALL})
   list(FIND AKANTU_OPTION_LIST ${_option_name} _index)
   if (_index EQUAL -1)
     if(NOT "${_option}" STREQUAL "CORE")
       if(NOT AKANTU_${_option})
         set(AKANTU_${_option} OFF)
       endif()
       file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
 set(AKANTU_HAS_${_option} ${AKANTU_${_option}})")
     endif()
   endif()
 endforeach()
 
 file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake"
 "
 
 set(AKANTU_HAS_PARTITIONER  ${AKANTU_PARTITIONER})
 set(AKANTU_HAS_SOLVER       ${AKANTU_SOLVER})
 ")
 
 foreach(_option ${AKANTU_OPTION_LIST})
   package_pkg_name(${_option} _pkg_name)
   file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
 list(APPEND AKANTU_OPTION_LIST ${_option})
 set(AKANTU_USE_${_option} ${AKANTU_${_option}})")
   if(${_pkg_name}_LIBRARIES)
     file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
 set(${_pkg_name}_LIBRARIES ${${_pkg_name}_LIBRARIES})")
   endif()
   if(${_pkg_name}_INCLUDE_DIR)
     file(APPEND "${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake" "
 set(${_pkg_name}_INCLUDE_DIR ${${_pkg_name}_INCLUDE_DIR})
 ")
   endif()
 endforeach()
 
 # Create the AkantuConfig.cmake and AkantuConfigVersion files
 get_filename_component(CONF_REL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}" ABSOLUTE)
 configure_file(cmake/AkantuConfig.cmake.in "${PROJECT_BINARY_DIR}/AkantuConfig.cmake" @ONLY)
 configure_file(cmake/AkantuConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/AkantuConfigVersion.cmake" @ONLY)
 configure_file(cmake/AkantuUse.cmake "${PROJECT_BINARY_DIR}/AkantuUse.cmake" COPYONLY)
 
 # Install the export set for use with the install-tree
 install(FILES ${PROJECT_BINARY_DIR}/AkantuConfig.cmake
   ${PROJECT_BINARY_DIR}/AkantuConfigInclude.cmake
   ${PROJECT_BINARY_DIR}/AkantuConfigVersion.cmake
   ${PROJECT_SOURCE_DIR}/cmake/AkantuUse.cmake
   DESTINATION  lib/akantu
   COMPONENT dev)
 
 install(FILES
   ${PROJECT_SOURCE_DIR}/cmake/Modules/FindIOHelper.cmake
   ${PROJECT_SOURCE_DIR}/cmake/Modules/FindQVIEW.cmake
   ${PROJECT_SOURCE_DIR}/cmake/Modules/FindMumps.cmake
   ${PROJECT_SOURCE_DIR}/cmake/Modules/FindScotch.cmake
   ${PROJECT_SOURCE_DIR}/cmake/Modules/FindGMSH.cmake
   DESTINATION  lib/akantu/cmake
   COMPONENT dev)
diff --git a/src/common/aka_point.hh b/src/common/aka_point.hh
index 48d0b88bb..59317ba46 100644
--- a/src/common/aka_point.hh
+++ b/src/common/aka_point.hh
@@ -1,226 +1,227 @@
 /**
  * @file   aka_point.hh
  * @author David Kammer <david.kammer@epfl.ch>
  * @author Alejandro Aragon <alejandro.aragon@epfl.ch>
  * @date   Thu Jan 12 15:43:51 2012
  *
  * @brief  class of a geometrical point
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_AKA_POINT_HH__
 #define __AKANTU_AKA_POINT_HH__
 
 #include "aka_common.hh"
+#include <cmath>
 
 #include <cassert>
 
 __BEGIN_AKANTU__
 
 
 const Real inf = std::numeric_limits<Real>::infinity();
 
 
 template <int d, typename T = Real>
 class Point {
   
 public:
   
   typedef T value_type;
   
   static int dim()
   { return d; }
   
   Point() {
     for (UInt i=0; i<d; ++i)
       coord_[i] = value_type();
   }
   
   
   explicit Point(value_type const* coordinates) {
     for (UInt i=0; i<d; ++i)
       coord_[i] = coordinates[i];
   }
   
   // parameter constructor
   template <typename... Args>
   explicit Point(const Args&... args) {
     
     static_assert(sizeof...(Args) <= d , "*** ERROR *** Number of arguments exceeded point dension");
     
     std::fill_n(coord_, d, value_type());
     
     value_type coord[] = { args... };
     
     if (sizeof...(Args) != 0)
       for (size_t i=0; i<d; ++i)
         coord_[i] = i < sizeof...(Args) ? coord[i] : coord[sizeof...(Args) - 1];
   }
   
   /// less operator
   bool operator<(const Point & p) const {
     for (int i=0; i<d; ++i)
       if (coord_[i] < p[i])
         return true;
     return false;
   }
   
   /// bool equal operator
   bool operator==(const Point & p) const {
     for (int i=0; i<d; ++i)
       if (coord_[i] != p[i])
         return false;
     return true;
   }
   
   /// standard output stream operator
   friend std::ostream& operator <<(std::ostream &os, const Point &p) {
     os<<"{"<<p.coord_[0];
     for (int i=1; i<d; ++i)
       os<<","<<p.coord_[i];
     os<<"}";
     return os;
   }
   
 public:
   
   //! Get copy of coordinate
   value_type operator[] (UInt index) const {
     assert(index < d);
     return coord_[index];
   }
   
   //! Get write access to coordinate
   value_type& operator[] (UInt index) {
     assert(index < d);
     return coord_[index];
   }
   
   Point& operator+=(const Point& p) {
     for (int i=0; i<d; ++i)
       coord_[i] += p.coord_[i];
     return *this;
   }
   
   Point& operator-=(const Point& p) {
     for (int i=0; i<d; ++i)
       coord_[i] -= p.coord_[i];
     return *this;
   }
   
   template <typename S>
   Point& operator*=(S s) {
     for (int i=0; i<d; ++i)
       coord_[i] *= s;
     return *this;
   }
   
   Point& normalize()
-  { return (*this)*=(1/sqrt(sq_norm())); }
+  { return (*this)*=(1/std::sqrt(sq_norm())); }
   
   value_type sq_norm() {
     value_type r = value_type();
     for (int i=0; i<d; ++i)
-      r += pow(coord_[i],2);
+      r += std::pow(coord_[i],2);
     return r;
   }
   
 private:
   
   Real coord_[d];
 };
 
 
 template <int d, typename T>
 Point<d,T> operator+(const Point<d,T>& p, const Point<d,T>& q) {
   Point<d,T> r(p);
   return r += q;
 }
 
 
 template <int d, typename T>
 Point<d,T> operator-(const Point<d,T>& p, const Point<d,T>& q) {
   Point<d,T> r(p);
   return r -= q;
 }
 
 // used operator* for dot product
 template <int d, typename T>
 typename Point<d,T>::value_type operator*(const Point<d,T>& p, const Point<d,T>& q) {
   
   typename Point<d,T>::value_type r = 0;
   for (int i=0; i<d; ++i)
     r += p[i] * q[i];
   return r;
 }
 
 
 
 template <int d, typename T>
 Point<d,T> operator*(const Point<d,T>& p, typename Point<d,T>::value_type s) {
   Point<d,T> r(p);
   return r *= s;
 }
 
 template <int d, typename T>
 Point<d,T> operator*(typename Point<d,T>::value_type s, const Point<d,T>& p) {
   Point<d,T> r(p);
   return r *= s;
 }
 
 
 // cross product
 template <typename T>
 Point<3,T> cross(const Point<3,T>& o, const Point<3,T>& p) {
   
   Point<3,T> r;
   for (int i=0; i<3; ++i)
     r[i] = o[(i+1)%3]*p[(i+2)%3] - o[(i+2)%3]*p[(i+1)%3];
   return r;
 }
 
 
 template <int d>
 struct Bounding_volume {
 
   typedef Point<d> point_type;
   typedef typename point_type::value_type value_type;
 
   virtual value_type measure() const = 0; // {assert(false);}
   virtual Bounding_volume* combine(const Bounding_volume&) const = 0; // {assert(false);}
   virtual std::ostream& print(std::ostream& os) const = 0; //{ assert(false); }
   
   Real last_time_;
   point_type velocity_;
   point_type acceleration_;
   
   friend std::ostream& operator<<(std::ostream& os, const Bounding_volume& gv)
   { return gv.print(os); }
 };
 
 
 
 
 __END_AKANTU__
 
 #endif /* __AKANTU_AKA_POINT_HH__ */
diff --git a/src/model/heat_transfer/heat_transfer_model.hh b/src/model/heat_transfer/heat_transfer_model.hh
index 3fa17ed12..05e8f18da 100644
--- a/src/model/heat_transfer/heat_transfer_model.hh
+++ b/src/model/heat_transfer/heat_transfer_model.hh
@@ -1,309 +1,306 @@
 /**
  * @file   heat_transfer_model.hh
  *
  * @author Rui Wang <rui.wang@epfl.ch>
  * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date   Sun May 01 19:14:43 2011
  *
  * @brief  Model of Heat Transfer
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_HEAT_TRANSFER_MODEL_HH__
 #define __AKANTU_HEAT_TRANSFER_MODEL_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_memory.hh"
 #include "model.hh"
 #include "integrator_gauss.hh"
 #include "shape_lagrange.hh"
 
 namespace akantu {
   class IntegrationScheme1stOrder;
 //    class Solver;
 //    class SparseMatrix;
 }
 
 __BEGIN_AKANTU__
 
 class HeatTransferModel : public Model, public DataAccessor {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   typedef FEMTemplate<IntegratorGauss,ShapeLagrange> MyFEMType;
 
   HeatTransferModel(UInt spatial_dimension,
 		    const ID & id = "heat_transfer_model",
   		    const MemoryID & memory_id = 0) ;
 
   HeatTransferModel(Mesh & mesh,
 		    UInt spatial_dimension = 0,
 		    const ID & id = "heat_transfer_model",
 		    const MemoryID & memory_id = 0);
 
   virtual ~HeatTransferModel() ;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 
 public:
 
   /// generic function to initialize everything ready for explicit dynamics
   void initFull(const std::string & material_file);
 
   /// initialize the fem object of the boundary
   void initFEMBoundary(bool create_surface = true);
 
   /// set the parameters
   bool setParam(const std::string & key, const std::string & value);
 
   /// read one material file to instantiate all the materials
   void readMaterials(const std::string & filename);
 
   /// allocate all vectors
   void initVectors();
 
   /// register the tags associated with the parallel synchronizer
   void initParallel(MeshPartition * partition, DataAccessor * data_accessor=NULL);
 
   /// initialize the model
   void initModel();
 
   /// init PBC synchronizer
   void initPBC();
 
   /// function to print the contain of the class
   virtual void printself(__attribute__ ((unused)) std::ostream & stream,
 			 __attribute__ ((unused)) int indent = 0) const {};
 
   /* ------------------------------------------------------------------------ */
   /* Methods for explicit                                                     */
   /* ------------------------------------------------------------------------ */
 public:
 
   /// compute and get the stable time step
   Real getStableTimeStep();
 
   /// compute the heat flux
   void updateResidual();
 
   /// calculate the lumped capacity vector for heat transfer problem
   void assembleCapacityLumped();
 
   /// update the temperature from the temperature rate
   void explicitPred();
 
   /// update the temperature rate from the increment
   void explicitCorr();
 
 
   // /// initialize the heat flux
   // void initializeResidual(Vector<Real> &temp);
   // /// initialize temperature
   // void initializeTemperature(Vector<Real> &temp);
 
 private:
 
   /// solve the system in temperature rate  @f$C\delta \dot T = q_{n+1} - C \dot T_{n}@f$
   void solveExplicitLumped();
 
   /// compute the heat flux on ghost types
   void updateResidual(const GhostType & ghost_type);
 
   /// calculate the lumped capacity vector for heat transfer problem (w ghosttype)
   void assembleCapacityLumped(const GhostType & ghost_type);
   
   /// compute the conductivity tensor for each quadrature point in an array
   void computeConductivityOnQuadPoints(const GhostType & ghost_type);
 
   /// compute vector k \grad T for each quadrature point 
   void computeKgradT(const GhostType & ghost_type);
 
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
-
-  inline UInt getNbDataToPack(const Element & element,
-			      SynchronizationTag tag) const;
-  inline UInt getNbDataToUnpack(const Element & element,
-				SynchronizationTag tag) const;
+  inline UInt getNbDataForElements(const Vector<Element> & elements,
+                                   SynchronizationTag tag) const;
   inline void packData(CommunicationBuffer & buffer,
-		       const Element & element,
+		       const Vector<Element> & elements,
 		       SynchronizationTag tag) const;
   inline void unpackData(CommunicationBuffer & buffer,
-			 const Element & element,
+			 const Vector<Element> & elements,
 			 SynchronizationTag tag);
 
   inline UInt getNbDataToPack(SynchronizationTag tag) const;
   inline UInt getNbDataToUnpack(SynchronizationTag tag) const;
   inline void packData(CommunicationBuffer & buffer,
 		       const UInt index,
 		       SynchronizationTag tag) const;
   inline void unpackData(CommunicationBuffer & buffer,
 			 const UInt index,
 			 SynchronizationTag tag);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
 
   inline FEM & getFEMBoundary(std::string name = "");
 
   /// get the dimension of the system space
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
   /// get the current value of the time step
   AKANTU_GET_MACRO(TimeStep, time_step, Real);
   /// set the value of the time step
   AKANTU_SET_MACRO(TimeStep, time_step, Real);
   /// get the assembled heat flux
   AKANTU_GET_MACRO(Residual, *residual, Vector<Real>&);
   /// get the lumped capacity
   AKANTU_GET_MACRO(CapacityLumped, * capacity_lumped, Vector<Real>&);
   /// get the boundary vector
   AKANTU_GET_MACRO(Boundary, * boundary, Vector<bool>&);
   /// get the external flux vector
   AKANTU_GET_MACRO(ExternalFlux, * external_flux, Vector<Real>&);
   /// get the temperature gradient
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(TemperatureGradient, temperature_gradient, Real);
   /// get the conductivity on q points
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ConductivityOnQpoints, conductivity_on_qpoints, Real);
   /// get the conductivity on q points
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(TemperatureOnQpoints, temperature_on_qpoints, Real);
   /// internal variables
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(KGradtOnQpoints,  k_gradt_on_qpoints, Real);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(IntBtKgT, int_bt_k_gT, Real);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(BtKgT, bt_k_gT, Real);
   /// get the temperature
   AKANTU_GET_MACRO(Temperature, *temperature, Vector<Real> &);
   /// get the temperature derivative
   AKANTU_GET_MACRO(TemperatureRate, *temperature_rate, Vector<Real> &);
   /// get the equation number Vector<Int>
   AKANTU_GET_MACRO(EquationNumber, *equation_number, const Vector<Int> &);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   IntegrationScheme1stOrder * integrator;
 
   /// time step
   Real time_step;
 
   /// temperatures array
   Vector<Real> * temperature;
 
   /// temperatures derivatives array
   Vector<Real> * temperature_rate;
 
   /// increment array (@f$\delta \dot T@f$ or @f$\delta T@f$)
   Vector<Real> * increment;
 
   /// the spatial dimension
   UInt spatial_dimension;
 
   /// the density
   Real density;
 
   /// the speed of the changing temperature
   ByElementTypeReal temperature_gradient;
 
   /// temperature field on quadrature points
   ByElementTypeReal temperature_on_qpoints;
 
   /// conductivity tensor on quadrature points
   ByElementTypeReal conductivity_on_qpoints;
 
   /// vector k \grad T on quad points
   ByElementTypeReal k_gradt_on_qpoints;
 
   /// vector \int \grad N k \grad T
   ByElementTypeReal int_bt_k_gT;
 
   /// vector \grad N k \grad T
   ByElementTypeReal bt_k_gT;
 
   //external flux vector
   Vector<Real> * external_flux;
 
   /// residuals array
   Vector<Real> * residual;
 
   /// position of a dof in the K matrix
   Vector<Int> * equation_number;
 
   //lumped vector
   Vector<Real> * capacity_lumped;
 
   /// boundary vector
   Vector<bool> * boundary;
 
   //realtime
   Real time;
 
   ///capacity
   Real capacity;
 
   //conductivity matrix
   Real* conductivity;
 
   //linear variation of the conductivity (for temperature dependent conductivity)
   Real conductivity_variation;
 
   // reference temperature for the interpretation of temperature variation
   Real t_ref;
 
   //the biggest parameter of conductivity matrix
   Real conductivitymax;
 
 };
 
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #if defined (AKANTU_INCLUDE_INLINE_IMPL)
 #  include "heat_transfer_model_inline_impl.cc"
 #endif
 
 /// standard output stream operator
 inline std::ostream & operator <<(std::ostream & stream, const HeatTransferModel & _this)
 {
   _this.printself(stream);
   return stream;
 }
 
 
 __END_AKANTU__
 
 
 
 #endif /* __AKANTU_HEAT_TRANSFER_MODEL_HH__ */
diff --git a/src/model/heat_transfer/heat_transfer_model_inline_impl.cc b/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
index 609779a11..004e337b7 100644
--- a/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
+++ b/src/model/heat_transfer/heat_transfer_model_inline_impl.cc
@@ -1,374 +1,299 @@
 /**
  * @file   heat_transfer_model_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch>
  *
  * @date   Sun May 01 19:14:43 2011
  *
  * @brief  Implementation of the inline functions of the HeatTransferModel class
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 inline FEM & HeatTransferModel::getFEMBoundary(std::string name) {
   return dynamic_cast<FEM &>(getFEMClassBoundary<MyFEMType>(name));
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt HeatTransferModel::getNbDataToPack(SynchronizationTag tag) const{
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   UInt nb_nodes = getFEM().getMesh().getNbNodes();
 
   switch(tag) {
   case _gst_htm_temperature:
   case _gst_htm_capacity: {
     size += nb_nodes * sizeof(Real);
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt HeatTransferModel::getNbDataToUnpack(SynchronizationTag tag) const{
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   UInt nb_nodes = getFEM().getMesh().getNbNodes();
 
   switch(tag) {
   case _gst_htm_capacity:
   case _gst_htm_temperature: {
     size += nb_nodes * sizeof(Real);
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void HeatTransferModel::packData(CommunicationBuffer & buffer,
 					const UInt index,
 					SynchronizationTag tag) const{
   AKANTU_DEBUG_IN();
 
   switch(tag) {
   case _gst_htm_capacity:
     buffer << (*capacity_lumped)(index);
     break;
   case _gst_htm_temperature: {
     buffer << (*temperature)(index);
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void HeatTransferModel::unpackData(CommunicationBuffer & buffer,
 					  const UInt index,
 					  SynchronizationTag tag) {
   AKANTU_DEBUG_IN();
 
   switch(tag) {
   case _gst_htm_capacity: {
     buffer >> (*capacity_lumped)(index);
     break;
   }
   case _gst_htm_temperature: {
     buffer >> (*temperature)(index);
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-inline UInt HeatTransferModel::getNbDataToPack(const Element & element,
-					       SynchronizationTag tag) const {
+inline UInt HeatTransferModel::getNbDataForElements(const Vector<Element> & elements,
+                                                    SynchronizationTag tag) const {
   AKANTU_DEBUG_IN();
 
-  UInt size = 0;
-  UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(element.type);
-
-#ifndef AKANTU_NDEBUG
-  size += spatial_dimension * sizeof(Real); /// position of the barycenter of the element (only for check)
-  size += spatial_dimension * nb_nodes_per_element * sizeof(Real); /// position of the nodes of the element
-#endif
-
-  switch(tag) {
-  case _gst_htm_capacity: {
-    size += nb_nodes_per_element * sizeof(Real); // capacity vector
-    break;
-  }
-  case _gst_htm_temperature: {
-    size += nb_nodes_per_element * sizeof(Real); // temperature
-    break;
-  }
-  case _gst_htm_gradient_temperature: {
-    size += spatial_dimension * sizeof(Real); // temperature gradient
-    size += nb_nodes_per_element * sizeof(Real); // nodal temperatures
-    size += spatial_dimension * nb_nodes_per_element * sizeof(Real); // shape derivatives
-    break;
-  }
-  default: {
-    AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
-  }
-  }
-
-  AKANTU_DEBUG_OUT();
-  return size;
-}
-
-/* -------------------------------------------------------------------------- */
-inline UInt HeatTransferModel::getNbDataToUnpack(const Element & element,
-						 SynchronizationTag tag) const {
-  AKANTU_DEBUG_IN();
 
   UInt size = 0;
-  UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(element.type);
+  UInt nb_nodes_per_element = 0;
+  Vector<Element>::const_iterator<Element> it  = elements.begin();
+  Vector<Element>::const_iterator<Element> end = elements.end();
+  for (; it != end; ++it) {
+    const Element & el = *it;
+    nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
+  }
 
 #ifndef AKANTU_NDEBUG
-  size += spatial_dimension * sizeof(Real); /// position of the barycenter of the element (only for check)
+  size += elements.getSize() * spatial_dimension * sizeof(Real); /// position of the barycenter of the element (only for check)
   size += spatial_dimension * nb_nodes_per_element * sizeof(Real); /// position of the nodes of the element
 #endif
 
   switch(tag) {
   case _gst_htm_capacity: {
     size += nb_nodes_per_element * sizeof(Real); // capacity vector
     break;
   }
   case _gst_htm_temperature: {
     size += nb_nodes_per_element * sizeof(Real); // temperature
     break;
   }
   case _gst_htm_gradient_temperature: {
     size += spatial_dimension * sizeof(Real); // temperature gradient
     size += nb_nodes_per_element * sizeof(Real); // nodal temperatures
     size += spatial_dimension * nb_nodes_per_element * sizeof(Real); // shape derivatives
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void HeatTransferModel::packData(CommunicationBuffer & buffer,
-					const Element & element,
+					const Vector<Element> & elements,
 					SynchronizationTag tag) const {
-  GhostType ghost_type = _not_ghost;
-  UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(element.type);
-  UInt el_offset  = element.element * nb_nodes_per_element;
-  UInt * conn  = getFEM().getMesh().getConnectivity(element.type, ghost_type).values;
-
 #ifndef AKANTU_NDEBUG
-  types::RVector barycenter(spatial_dimension);
-  getFEM().getMesh().getBarycenter(element.element, element.type, barycenter.storage(), ghost_type);
-  buffer << barycenter;
-  Real * nodes = getFEM().getMesh().getNodes().values;
-  for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-    UInt offset_conn = conn[el_offset + n];
-    for (UInt s = 0; s < spatial_dimension; ++s) {
-    buffer << nodes[spatial_dimension*offset_conn+s];
-    }
-  }
+  Vector<Element>::const_iterator<Element> bit  = elements.begin();
+  Vector<Element>::const_iterator<Element> bend = elements.end();
+  for (; bit != bend; ++bit) {
+    const Element & element = *bit;
+    types::RVector barycenter(spatial_dimension);
+    mesh.getBarycenter(element.element, element.type, barycenter.storage(), element.ghost_type);
+    buffer << barycenter;
+  }
+  // packNodalDataHelper(mesh.getNodes(), buffer, elements);
 #endif
 
   switch (tag){
   case _gst_htm_capacity: {
-    for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-      UInt offset_conn = conn[el_offset + n];
-      buffer << (*capacity_lumped)(offset_conn);
-    }
+    packNodalDataHelper(*capacity_lumped, buffer, elements);
     break;
   }
   case _gst_htm_temperature: {
-    for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-      UInt offset_conn = conn[el_offset + n];
-      buffer << (*temperature)(offset_conn);
-    }
+    packNodalDataHelper(*temperature, buffer, elements);
     break;
   }
   case _gst_htm_gradient_temperature: {
-    Vector<Real>::const_iterator<types::RVector> it_gtemp =
-      temperature_gradient(element.type, ghost_type).begin(spatial_dimension);
-
-    buffer << it_gtemp[element.element];
-
-    for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-      UInt offset_conn = conn[el_offset + n];
-      buffer << (*temperature)(offset_conn);
-    }
-
-    Vector<Real>::const_iterator<types::RMatrix> it_shaped =
-      getFEM().getShapesDerivatives(element.type, ghost_type).begin(nb_nodes_per_element,spatial_dimension);
-    buffer << it_shaped[element.element];
+    packElementalDataHelper(temperature_gradient, buffer, elements);
+    packNodalDataHelper(*temperature, buffer, elements);
+    // Vector<Real>::const_iterator<types::RMatrix> it_shaped =
+    //   getFEM().getShapesDerivatives(element.type, ghost_type).begin(nb_nodes_per_element,spatial_dimension);
+    // buffer << it_shaped[element.element];
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 }
 
 /* -------------------------------------------------------------------------- */
 inline void HeatTransferModel::unpackData(CommunicationBuffer & buffer,
-		       const Element & element,
-		       SynchronizationTag tag) {
-  GhostType ghost_type = _ghost;
-  UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(element.type);
-  UInt el_offset  = element.element * nb_nodes_per_element;
-  UInt * conn  = getFEM().getMesh().getConnectivity(element.type, ghost_type).values;
-
+                                          const Vector<Element> & elements,
+                                          SynchronizationTag tag) {
 #ifndef AKANTU_NDEBUG
-  types::RVector barycenter_loc(spatial_dimension);
-  getFEM().getMesh().getBarycenter(element.element, element.type, barycenter_loc.storage(), ghost_type);
-
-  types::RVector barycenter(spatial_dimension);
-  buffer >> barycenter;
-  Real tolerance = 1e-15;
-  for (UInt i = 0; i < spatial_dimension; ++i) {
-    if(!(std::abs(barycenter(i) - barycenter_loc(i)) <= tolerance))
-      AKANTU_EXCEPTION("Unpacking an unknown value for the element : "
-			     << element
-			     << "(barycenter[" << i << "] = " << barycenter_loc(i)
-			     << " and buffer[" << i << "] = " << barycenter(i) << ")");
-  }
+  Vector<Element>::const_iterator<Element> bit  = elements.begin();
+  Vector<Element>::const_iterator<Element> bend = elements.end();
+  for (; bit != bend; ++bit) {
+    const Element & element = *bit;
+
+    types::RVector barycenter_loc(spatial_dimension);
+    mesh.getBarycenter(element.element, element.type, barycenter_loc.storage(), element.ghost_type);
 
-  types::RVector coords(spatial_dimension);
-  Real * nodes = getFEM().getMesh().getNodes().values;
-  for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-    buffer >> coords;
-    UInt offset_conn = conn[el_offset + n];
-    Real * coords_local = nodes+spatial_dimension*offset_conn;
+    types::RVector barycenter(spatial_dimension);
+    buffer >> barycenter;
+    Real tolerance = 1e-15;
     for (UInt i = 0; i < spatial_dimension; ++i) {
-      if(!(std::abs(coords(i) - coords_local[i]) <= tolerance))
-	AKANTU_EXCEPTION("Unpacking to wrong node for the element : "
-			 << element
-			 << "(coords[" << i << "] = " << coords_local[i]
-			 << " and buffer[" << i << "] = " << coords(i) << ")");
+      if(!(std::abs(barycenter(i) - barycenter_loc(i)) <= tolerance))
+	AKANTU_DEBUG_ERROR("Unpacking an unknown value for the element: "
+			   << element
+			   << "(barycenter[" << i << "] = " << barycenter_loc(i)
+			   << " and buffer[" << i << "] = " << barycenter(i) << ") - tag: " << tag);
     }
   }
+
+  // types::RVector coords(spatial_dimension);
+  // Real * nodes = getFEM().getMesh().getNodes().values;
+  // for (UInt n = 0; n < nb_nodes_per_element; ++n) {
+  //   buffer >> coords;
+  //   UInt offset_conn = conn[el_offset + n];
+  //   Real * coords_local = nodes+spatial_dimension*offset_conn;
+  //   for (UInt i = 0; i < spatial_dimension; ++i) {
+  //     if(!(std::abs(coords(i) - coords_local[i]) <= tolerance))
+  //       AKANTU_EXCEPTION("Unpacking to wrong node for the element : "
+  //       		 << element
+  //       		 << "(coords[" << i << "] = " << coords_local[i]
+  //       		 << " and buffer[" << i << "] = " << coords(i) << ")");
+  //   }
+  // }
 #endif
 
   switch (tag){
   case _gst_htm_capacity: {
-    for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-      UInt offset_conn = conn[el_offset + n];
-      buffer >> (*capacity_lumped)(offset_conn);
-    }
+    unpackNodalDataHelper(*capacity_lumped, buffer, elements);
     break;
   }
   case _gst_htm_temperature: {
-    for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-      UInt offset_conn = conn[el_offset + n];
-      Real tbuffer;
-      buffer >> tbuffer;
-#ifndef AKANTU_NDEBUG
-      // if (!getFEM().getMesh().isPureGhostNode(offset_conn)){
-      // 	if (std::abs(tbuffer - (*temperature)(offset_conn)) > 1e-15){
-      // 	  AKANTU_EXCEPTION(std::scientific << std::setprecision(20)
-      // 			   << "local node is impacted with a different value computed from a distant proc"
-      // 			   << " => divergence of trajectory detected " << std::endl
-      // 			   << tbuffer << " != " << (*temperature)(offset_conn)
-      // 			   << " diff is " << tbuffer - (*temperature)(offset_conn));
-      // 	}
-      // }
-#endif
-    (*temperature)(offset_conn) = tbuffer;
-    }
+    unpackNodalDataHelper(*temperature, buffer, elements);
     break;
   }
   case _gst_htm_gradient_temperature: {
-    Vector<Real>::iterator<types::RVector> it_gtemp =
-      temperature_gradient(element.type, ghost_type).begin(spatial_dimension);
-    types::RVector gtemp(spatial_dimension);
-    types::RVector temp_nodes(nb_nodes_per_element);
-    types::RMatrix shaped(nb_nodes_per_element,spatial_dimension);
-
-    buffer >> gtemp;
-    buffer >> temp_nodes;
-    buffer >> shaped;
-
-    //    Real tolerance = 1e-15;
-    if (!Math::are_vector_equal(spatial_dimension,gtemp.storage(),it_gtemp[element.element].storage())){
-      Real dist = Math::distance_3d(gtemp.storage(), it_gtemp[element.element].storage());
-      debug::debugger.getOutputStream().precision(20);
-      std::stringstream temperatures_str;
-      temperatures_str.precision(20);
-      temperatures_str << std::scientific << "temperatures are ";
-      for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-	UInt offset_conn = conn[el_offset + n];
-	temperatures_str << (*temperature)(offset_conn) << " ";
-      }
-      Vector<Real>::iterator<types::RMatrix> it_shaped =
-	const_cast<Vector<Real> &>(getFEM().getShapesDerivatives(element.type, ghost_type))
-	.begin(nb_nodes_per_element,spatial_dimension);
-
-
-      AKANTU_EXCEPTION("packed gradient do not match for element " << element.element << std::endl
-		       << "buffer is " << gtemp << " local is " << it_gtemp[element.element]
-		       << " dist is " << dist << std::endl
-		       << temperatures_str.str() << std::endl
-		       << std::scientific << std::setprecision(20)
-		       << " distant temperatures " << temp_nodes
-		       << "temperature gradient size " << temperature_gradient(element.type, ghost_type).getSize()
-		       << " number of ghost elements " << getFEM().getMesh().getNbElement(element.type,_ghost)
-		       << std::scientific << std::setprecision(20)
-		       << " shaped " << shaped
-		       << std::scientific << std::setprecision(20)
-		       << " local shaped " << it_shaped[element.element]);
-    }
+    unpackElementalDataHelper(temperature_gradient, buffer, elements);
+    unpackNodalDataHelper(*temperature, buffer, elements);
+
+    // //    Real tolerance = 1e-15;
+    // if (!Math::are_vector_equal(spatial_dimension,gtemp.storage(),it_gtemp[element.element].storage())){
+    //   Real dist = Math::distance_3d(gtemp.storage(), it_gtemp[element.element].storage());
+    //   debug::debugger.getOutputStream().precision(20);
+    //   std::stringstream temperatures_str;
+    //   temperatures_str.precision(20);
+    //   temperatures_str << std::scientific << "temperatures are ";
+    //   for (UInt n = 0; n < nb_nodes_per_element; ++n) {
+    //     UInt offset_conn = conn[el_offset + n];
+    //     temperatures_str << (*temperature)(offset_conn) << " ";
+    //   }
+    //   Vector<Real>::iterator<types::RMatrix> it_shaped =
+    //     const_cast<Vector<Real> &>(getFEM().getShapesDerivatives(element.type, ghost_type))
+    //     .begin(nb_nodes_per_element,spatial_dimension);
+
+
+    //   AKANTU_EXCEPTION("packed gradient do not match for element " << element.element << std::endl
+    //     	       << "buffer is " << gtemp << " local is " << it_gtemp[element.element]
+    //     	       << " dist is " << dist << std::endl
+    //     	       << temperatures_str.str() << std::endl
+    //     	       << std::scientific << std::setprecision(20)
+    //     	       << " distant temperatures " << temp_nodes
+    //     	       << "temperature gradient size " << temperature_gradient(element.type, ghost_type).getSize()
+    //     	       << " number of ghost elements " << getFEM().getMesh().getNbElement(element.type,_ghost)
+    //     	       << std::scientific << std::setprecision(20)
+    //     	       << " shaped " << shaped
+    //     	       << std::scientific << std::setprecision(20)
+    //     	       << " local shaped " << it_shaped[element.element]);
+    // }
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 }
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/model/integration_scheme/generalized_trapezoidal.hh b/src/model/integration_scheme/generalized_trapezoidal.hh
index 60c18b7f1..25248798f 100644
--- a/src/model/integration_scheme/generalized_trapezoidal.hh
+++ b/src/model/integration_scheme/generalized_trapezoidal.hh
@@ -1,168 +1,168 @@
 /**
  * @file   generalized_trapezoidal.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Mon Jul 04 15:07:57 2011
  *
  * @brief  Generalized Trapezoidal  Method.  This implementation  is taken  from
  * Méthodes  numériques en mécanique  des solides  by Alain  Curnier \note{ISBN:
  * 2-88074-247-1}
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__
 #define __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__
 
 #include "integration_scheme_1st_order.hh"
 
 __BEGIN_AKANTU__
 
 /**
- * The two differentiate equation (thermal and cinematic) are :
+ * The two differentiate equation (thermal and kinematic) are :
  * @f{eqnarray*}{
  *  C\dot{u}_{n+1} + Ku_{n+1} = q_{n+1}\\
  *  u_{n+1} = u_{n} + (1-\alpha) \Delta t \dot{u}_{n} + \alpha \Delta t \dot{u}_{n+1}
  * @f}
  *
  * To solve it :
  * Predictor :
  * @f{eqnarray*}{
  * u^0_{n+1} &=& u_{n} + \Delta t v_{n} \\
  * \dot{u}^0_{n+1} &=& \dot{u}_{n}
  * @f}
  *
  * Solve :
  * @f[ (a C + b K^i_{n+1}) w = q_{n+1} - f^i_{n+1} - C \dot{u}^i_{n+1} @f]
  *
  * Corrector :
  * @f{eqnarray*}{
  * \dot{u}^{i+1}_{n+1} &=& \dot{u}^{i}_{n+1} + a w \\
  * u^{i+1}_{n+1} &=& u^{i}_{n+1} + b w
  * @f}
  *
  * a and b depends on the resolution method : temperature (u) or temperature rate (@f$\dot{u}@f$)
  *
  * For temperature : @f$ w = \delta u, a = 1 / (\alpha \Delta t) , b = 1 @f$ @n
  * For temperature rate : @f$ w = \delta \dot{u}, a = 1, b = \alpha \Delta t @f$
  */
 class GeneralizedTrapezoidal : public IntegrationScheme1stOrder {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   GeneralizedTrapezoidal(Real alpha) : alpha(alpha) {};
   virtual ~GeneralizedTrapezoidal() {};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
 
   virtual void integrationSchemePred(Real delta_t,
 				     Vector<Real> & u,
 				     Vector<Real> & u_dot,
 				     Vector<bool> & boundary);
 
   virtual void integrationSchemeCorrTemp(Real delta_t,
 					 Vector<Real> & u,
 					 Vector<Real> & u_dot,
 					 Vector<bool> & boundary,
 					 Vector<Real> & delta);
 
   virtual void integrationSchemeCorrTempRate(Real delta_t,
 					     Vector<Real> & u,
 					     Vector<Real> & u_dot,
 					     Vector<bool> & boundary,
 					     Vector<Real> & delta);
 
 public:
   /// the coeffichent @f{b@f} in the description
   template<IntegrationSchemeCorrectorType type>
   Real getTemperatureCoefficient(Real delta_t);
 
   /// the coeffichent @f{a@f} in the description
   template<IntegrationSchemeCorrectorType type>
   Real getTemperatureRateCoefficient(Real delta_t);
 
 private:
   template<IntegrationSchemeCorrectorType type>
   void integrationSchemeCorr(Real delta_t,
 			     Vector<Real> & u,
 			     Vector<Real> & u_dot,
 			     Vector<bool> & boundary,
 			     Vector<Real> & delta);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   AKANTU_GET_MACRO(Alpha, alpha, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 private:
   /// the @f$\alpha@f$ parameter
   const Real alpha;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #if defined (AKANTU_INCLUDE_INLINE_IMPL)
 #  include "generalized_trapezoidal_inline_impl.cc"
 #endif
 
 
 /**
  * Forward Euler (explicit) -> condition on delta_t
  */
 class ForwardEuler : public GeneralizedTrapezoidal {
 public:
   ForwardEuler() : GeneralizedTrapezoidal(0.) {};
 };
 
 
 /**
  * Trapezoidal rule (implicit), midpoint rule or Crank-Nicolson
  */
 class TrapezoidalRule1 : public GeneralizedTrapezoidal {
 public:
   TrapezoidalRule1() : GeneralizedTrapezoidal(.5) {};
 };
 
 /**
  * Backward Euler (implicit)
  */
 class BackwardEuler : public GeneralizedTrapezoidal {
 public:
   BackwardEuler() : GeneralizedTrapezoidal(1.) {};
 };
 
 
 __END_AKANTU__
 
 #endif /* __AKANTU_GENERALIZED_TRAPEZOIDAL_HH__ */
diff --git a/src/model/model.hh b/src/model/model.hh
index 84ec1c4dd..66e93b96f 100644
--- a/src/model/model.hh
+++ b/src/model/model.hh
@@ -1,198 +1,224 @@
 /**
  * @file   model.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author David Simon Kammer <david.kammer@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Tue Jul 27 18:15:37 2010
  *
  * @brief  Interface of a model
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MODEL_HH__
 #define __AKANTU_MODEL_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_memory.hh"
 #include "mesh.hh"
 #include "fem.hh"
 #include "mesh_utils.hh"
 #include "synchronizer_registry.hh"
 #include "distributed_synchronizer.hh"
 #include "static_communicator.hh"
 #include "mesh_partition.hh"
 #include "dof_synchronizer.hh"
 #include "pbc_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 
 __BEGIN_AKANTU__
 
 class Model : public Memory {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   
   typedef Mesh mesh_type;
 
   
   Model(Mesh& mesh, const ID & id = "model",
         const MemoryID & memory_id = 0);
   
   virtual ~Model();
   
   typedef std::map<std::string, FEM *> FEMMap;
   
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   virtual void initModel() = 0;
   
   /// create the synchronizer registry object
   void createSynchronizerRegistry(DataAccessor * data_accessor);
   
   /// create a parallel synchronizer and distribute the mesh
   Synchronizer & createParallelSynch(MeshPartition * partition,
                                      DataAccessor * data_accessor);
   
   /// change local equation number so that PBC is assembled properly
   void changeLocalEquationNumberforPBC(std::map<UInt,UInt> & pbc_pair,UInt dimension);
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const = 0;
   
   /// initialize the model for PBC
   void setPBC(UInt x, UInt y, UInt z);
   void setPBC(SurfacePairList & surface_pairs,
               ElementType surface_e_type);
   
   virtual void initPBC();
   
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   /// get id of model
   AKANTU_GET_MACRO(ID, id, const ID)
   
   /// get the number of surfaces
   AKANTU_GET_MACRO(Mesh, mesh, Mesh&);
   
   /// return the object hadling equation numbers
   AKANTU_GET_MACRO(DOFSynchronizer, *dof_synchronizer, const DOFSynchronizer &)
   
   /// synchronize the boundary in case of parallel run
   virtual void synchronizeBoundaries() {};
   
   /// return the fem object associated with a provided name
   inline FEM & getFEM(std::string name = "") const;
   
   /// return the fem boundary object associated with a provided name
   virtual FEM & getFEMBoundary(std::string name = "");
   
   /// register a fem object associated with name
   template <typename FEMClass> inline void registerFEMObject(const std::string & name,
                                                              Mesh & mesh,
                                                              UInt spatial_dimension);
   /// unregister a fem object associated with name
   inline void unRegisterFEMObject(const std::string & name);
   
   /// return the synchronizer registry
   SynchronizerRegistry & getSynchronizerRegistry();
   
 public:
   /// return the fem object associated with a provided name
   template <typename FEMClass>
   inline FEMClass & getFEMClass(std::string name = "") const;
   
   /// return the fem boundary object associated with a provided name
   template <typename FEMClass>
   inline FEMClass & getFEMClassBoundary(std::string name = "");
   
   /// get the pbc pairs
   std::map<UInt,UInt> & getPBCPairs(){return pbc_pair;};
   
 protected:
   /// returns if node is slave in pbc
   inline bool getIsPBCSlaveNode(const UInt node);
   
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
+  template<typename T>
+  inline void packElementalDataHelper(const ByElementTypeVector<T> & data_to_pack,
+                                      CommunicationBuffer & buffer,
+                                      const Vector<Element> & elements) const;
+  template<typename T>
+  inline void unpackElementalDataHelper(ByElementTypeVector<T> & data_to_unpack,
+                                        CommunicationBuffer & buffer,
+                                        const Vector<Element> & elements) const;
+  template<typename T, bool pack_helper>
+  inline void packUnpackElementalDataHelper(ByElementTypeVector<T> & data_to_pack,
+                                            CommunicationBuffer & buffer,
+                                            const Vector<Element> & element) const;
+
+  /* -------------------------------------------------------------------------- */
+  template<typename T>
+  inline void packNodalDataHelper(Vector<T> & data_to_pack,
+                                  CommunicationBuffer & buffer,
+                                  const Vector<Element> & element) const;
+  template<typename T>
+  inline void unpackNodalDataHelper(Vector<T> & data_to_unpack,
+                                    CommunicationBuffer & buffer,
+                                    const Vector<Element> & element) const;
+  template<typename T, bool pack_helper>
+  inline void packUnpackNodalDataHelper(Vector<T> & data,
+                                        CommunicationBuffer & buffer,
+                                        const Vector<Element> & elements) const;
   
   
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
   
   /// Mesh
   Mesh & mesh;
   
   /// id
   ID id;
   
   /// the main fem object present in all  models
   FEMMap fems;
   
   /// the fem object present in all  models for boundaries
   FEMMap fems_boundary;
   
   /// default fem object
   std::string default_fem;
   
   /// synchronizer registry
   SynchronizerRegistry * synch_registry;
   
   /// handle the equation number things
   DOFSynchronizer * dof_synchronizer;
   
   /// pbc pairs
   std::map<UInt,UInt> pbc_pair;
   
   /// flag per node to know is pbc slave
   Vector<bool> is_pbc_slave_node;
 };
 
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #if defined (AKANTU_INCLUDE_INLINE_IMPL)
 #  include "model_inline_impl.cc"
 #endif
 
 /// standard output stream operator
 inline std::ostream & operator <<(std::ostream & stream, const Model & _this)
 {
   _this.printself(stream);
   return stream;
 }
 
 __END_AKANTU__
 
 #endif /* __AKANTU_MODEL_HH__ */
diff --git a/src/model/model_inline_impl.cc b/src/model/model_inline_impl.cc
index 5ec38b3ff..31b389be0 100644
--- a/src/model/model_inline_impl.cc
+++ b/src/model/model_inline_impl.cc
@@ -1,174 +1,279 @@
 /**
  * @file   model_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  *
  * @date   Wed Aug 25 08:50:54 2010
  *
  * @brief  inline implementation of the model class
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 inline SynchronizerRegistry & Model::getSynchronizerRegistry(){
   AKANTU_DEBUG_ASSERT(synch_registry,"synchronizer registry not initialized:"
 		      << " did you call createSynchronizerRegistry ?");
   return  *synch_registry;
 }
 
 /* -------------------------------------------------------------------------- */
 template <typename FEMClass>
 inline FEMClass & Model::getFEMClassBoundary(std::string name) {
   AKANTU_DEBUG_IN();
 
   if (name == "") name = default_fem;
 
   FEMMap::const_iterator it_boun = fems_boundary.find(name);
 
   FEMClass * tmp_fem_boundary;
 
   if (it_boun == fems_boundary.end()){
     AKANTU_DEBUG_INFO("Creating FEM boundary " << name);
 
     FEMMap::const_iterator it = fems.find(name);
     AKANTU_DEBUG_ASSERT(it != fems.end(), "The FEM " << name << " is not registered");
 
     UInt spatial_dimension = it->second->getElementDimension();
     std::stringstream sstr; sstr << id << ":fem_boundary:" << name;
 
     tmp_fem_boundary = new FEMClass(it->second->getMesh(),
 				    spatial_dimension-1,
 				    sstr.str(),
 				    memory_id);
     fems_boundary[name] = tmp_fem_boundary;
   } else {
     tmp_fem_boundary = dynamic_cast<FEMClass *>(it_boun->second);
   }
 
   AKANTU_DEBUG_OUT();
   return *tmp_fem_boundary;
 }
 
 
 /* -------------------------------------------------------------------------- */
 template <typename FEMClass>
 inline FEMClass & Model::getFEMClass(std::string name) const{
   AKANTU_DEBUG_IN();
 
   if (name == "") name = default_fem;
 
   FEMMap::const_iterator it = fems.find(name);
   AKANTU_DEBUG_ASSERT(it != fems.end(), "The FEM " << name << " is not registered");
 
   AKANTU_DEBUG_OUT();
   return dynamic_cast<FEMClass &>(*(it->second));
 }
 
 /* -------------------------------------------------------------------------- */
 
 inline void Model::unRegisterFEMObject(const std::string & name){
 
   FEMMap::iterator it = fems.find(name);
   AKANTU_DEBUG_ASSERT(it != fems.end(), "FEM object with name "
 		      << name << " was not found");
 
   delete((*it).second);
   fems.erase(it);
   if (!fems.empty())
     default_fem = (*fems.begin()).first;
 }
 
 /* -------------------------------------------------------------------------- */
 
 template <typename FEMClass>
 inline void Model::registerFEMObject(const std::string & name,
 				     Mesh & mesh,
 				     UInt spatial_dimension){
   if (fems.size() == 0) default_fem = name;
 
 #ifndef AKANTU_NDEBUG
   FEMMap::iterator it = fems.find(name);
   AKANTU_DEBUG_ASSERT(it == fems.end(), "FEM object with name "
 		      << name << " was already created");
 #endif
 
   std::stringstream sstr; sstr << id << ":fem:" << name;
   fems[name] = new FEMClass(mesh, spatial_dimension, sstr.str(), memory_id);
 
   // MeshUtils::buildFacets(fems[name]->getMesh());
 
   // std::stringstream sstr2; sstr2 << id << ":fem_boundary:" << name;
   // fems_boundary[name] = new FEMClass(mesh, spatial_dimension-1, sstr2.str(), memory_id);
 }
 
 /* -------------------------------------------------------------------------- */
 inline FEM & Model::getFEM(std::string name) const{
   AKANTU_DEBUG_IN();
 
   if (name == "") name = default_fem;
 
   FEMMap::const_iterator it = fems.find(name);
   AKANTU_DEBUG_ASSERT(it != fems.end(),"The FEM " << name << " is not registered");
 
   AKANTU_DEBUG_OUT();
   return *(it->second);
 }
 
 
 /* -------------------------------------------------------------------------- */
 inline FEM & Model::getFEMBoundary(std::string name){
   AKANTU_DEBUG_IN();
 
   if (name == "") name = default_fem;
 
   FEMMap::const_iterator it = fems_boundary.find(name);
   AKANTU_DEBUG_ASSERT(it != fems_boundary.end(),
 		      "The FEM boundary  " << name << " is not registered");
   AKANTU_DEBUG_ASSERT(it->second != NULL,
 		      "The FEM boundary " << name << " was not created");
 
   AKANTU_DEBUG_OUT();
   return *(it->second);
 }
 /* -------------------------------------------------------------------------- */
 /// @todo : should merge with a single function which handles local and global
 inline void Model::changeLocalEquationNumberforPBC(std::map<UInt,UInt> & pbc_pair,
 					    UInt dimension){
   for (std::map<UInt,UInt>::iterator it = pbc_pair.begin();
        it != pbc_pair.end();++it) {
     Int node_master = (*it).second;
     Int node_slave = (*it).first;
     for (UInt i = 0; i < dimension; ++i) {
       (*dof_synchronizer->getLocalDOFEquationNumbersPointer())
 	(node_slave*dimension+i) = dimension*node_master+i;
       (*dof_synchronizer->getGlobalDOFEquationNumbersPointer())
 	(node_slave*dimension+i) = dimension*node_master+i;
     }
   }
 }
 /* -------------------------------------------------------------------------- */
 inline bool Model::getIsPBCSlaveNode(const UInt node) {
   // if no pbc is defined, is_pbc_slave_node is of size zero
   if (is_pbc_slave_node.getSize() == 0)
     return false;
   else
     return is_pbc_slave_node(node);
 }
+
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+inline void Model::packElementalDataHelper(const ByElementTypeVector<T> & data_to_pack,
+                                           CommunicationBuffer & buffer,
+                                           const Vector<Element> & elements) const {
+  packUnpackElementalDataHelper<T, true>(const_cast<ByElementTypeVector<T> &>(data_to_pack),
+                                         buffer,
+                                         elements);
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+inline void Model::unpackElementalDataHelper(ByElementTypeVector<T> & data_to_unpack,
+                                             CommunicationBuffer & buffer,
+                                             const Vector<Element> & elements) const {
+  packUnpackElementalDataHelper<T, false>(data_to_unpack, buffer, elements);
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T, bool pack_helper>
+inline void Model::packUnpackElementalDataHelper(ByElementTypeVector<T> & data_to_pack,
+                                                 CommunicationBuffer & buffer,
+                                                 const Vector<Element> & element) const {
+  ElementType current_element_type = _not_defined;
+  GhostType current_ghost_type = _casper;
+  UInt nb_quad_per_elem = 0;
+  UInt nb_component = 0;
+
+  Vector<T> * vect = NULL;
+
+  Vector<Element>::const_iterator<Element> it  = element.begin();
+  Vector<Element>::const_iterator<Element> end = element.end();
+  for (; it != end; ++it) {
+    const Element & el = *it;
+    if(el.type != current_element_type || el.ghost_type != current_ghost_type) {
+      current_element_type = el.type;
+      current_ghost_type   = el.ghost_type;
+      vect = &data_to_pack(el.type, el.ghost_type);
+      nb_quad_per_elem = this->getFEM().getNbQuadraturePoints(el.type, el.ghost_type);
+      nb_component = vect->getNbComponent();
+    }
+
+    types::Vector<T> data(vect->storage() + el.element * nb_component * nb_quad_per_elem,
+			  nb_component * nb_quad_per_elem);
+    if(pack_helper)
+      buffer << data;
+    else
+      buffer >> data;
+  }
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+inline void Model::packNodalDataHelper(Vector<T> & data_to_pack,
+                                       CommunicationBuffer & buffer,
+                                       const Vector<Element> & element) const {
+  packUnpackNodalDataHelper<T, true>(data_to_pack, buffer, element);
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T>
+inline void Model::unpackNodalDataHelper(Vector<T> & data_to_unpack,
+                                         CommunicationBuffer & buffer,
+                                         const Vector<Element> & element) const {
+  packUnpackNodalDataHelper<T, false>(data_to_unpack, buffer, element);
+}
+
+/* -------------------------------------------------------------------------- */
+template<typename T, bool pack_helper>
+inline void Model::packUnpackNodalDataHelper(Vector<T> & data,
+                                             CommunicationBuffer & buffer,
+                                             const Vector<Element> & elements) const {
+  UInt nb_component = data.getNbComponent();
+  UInt nb_nodes_per_element = 0;
+
+  ElementType current_element_type = _not_defined;
+  GhostType current_ghost_type = _casper;
+  UInt * conn = NULL;
+
+  Vector<Element>::const_iterator<Element> it  = elements.begin();
+  Vector<Element>::const_iterator<Element> end = elements.end();
+  for (; it != end; ++it) {
+    const Element & el = *it;
+    if(el.type != current_element_type || el.ghost_type != current_ghost_type) {
+      current_element_type = el.type;
+      current_ghost_type   = el.ghost_type;
+      conn = mesh.getConnectivity(el.type, el.ghost_type).storage();
+      nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
+    }
+
+    UInt el_offset  = el.element * nb_nodes_per_element;
+    for (UInt n = 0; n < nb_nodes_per_element; ++n) {
+      UInt offset_conn = conn[el_offset + n];
+      types::Vector<T> data_vect(data.storage() + offset_conn * nb_component,
+				 nb_component);
+
+      if(pack_helper)
+	buffer << data_vect;
+      else
+	buffer >> data_vect;
+    }
+  }
+}
diff --git a/src/model/solid_mechanics/solid_mechanics_model.hh b/src/model/solid_mechanics/solid_mechanics_model.hh
index 7fee3f99e..7ca82d645 100644
--- a/src/model/solid_mechanics/solid_mechanics_model.hh
+++ b/src/model/solid_mechanics/solid_mechanics_model.hh
@@ -1,593 +1,575 @@
 /**
  * @file   solid_mechanics_model.hh
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Tue Jul 27 18:15:37 2010
  *
  * @brief  Model of Solid Mechanics
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_SOLID_MECHANICS_MODEL_HH__
 #define __AKANTU_SOLID_MECHANICS_MODEL_HH__
 
 
 /* -------------------------------------------------------------------------- */
 #include <fstream>
 /* -------------------------------------------------------------------------- */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "model.hh"
 #include "data_accessor.hh"
 #include "integrator_gauss.hh"
 #include "shape_lagrange.hh"
 #include "aka_types.hh"
 #include "integration_scheme_2nd_order.hh"
 #include "solver.hh"
 #include "dumpable.hh"
 
 /* -------------------------------------------------------------------------- */
 namespace akantu {
   class Material;
   class IntegrationScheme2ndOrder;
   class Contact;
   class SparseMatrix;
 }
 
 __BEGIN_AKANTU__
 
 class SolidMechanicsModel : public Model, public DataAccessor, public MeshEventHandler, public Dumpable<DumperParaview> {
 
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
 
   typedef FEMTemplate<IntegratorGauss,ShapeLagrange> MyFEMType;
 
   SolidMechanicsModel(Mesh & mesh,
 		      UInt spatial_dimension = 0,
 		      const ID & id = "solid_mechanics_model",
 		      const MemoryID & memory_id = 0);
 
   virtual ~SolidMechanicsModel();
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
 
   /// initialize completely the model
   virtual void initFull(std::string material_file,
 			AnalysisMethod method = _explicit_dynamic);
 
   /// initialize the fem object needed for boundary conditions
   void initFEMBoundary(bool create_surface = true);
 
   /// register the tags associated with the parallel synchronizer
   void initParallel(MeshPartition * partition, DataAccessor * data_accessor=NULL);
 
   /// allocate all vectors
   void initVectors();
 
   /// initialize all internal arrays for materials
   void initMaterials();
 
   /// initialize the model
   virtual void initModel();
 
   /// init PBC synchronizer
   void initPBC();
 
   /// function to print the containt of the class
   virtual void printself(std::ostream & stream, int indent = 0) const;
 
   /* ------------------------------------------------------------------------ */
   /* PBC                                                                      */
   /* ------------------------------------------------------------------------ */
 public:
 
   /// change the equation number for proper assembly when using PBC
   void changeEquationNumberforPBC(std::map<UInt,UInt> & pbc_pair);
 
   /// synchronize Residual for output
   void synchronizeResidual();
 
 protected:
 
   /// register PBC synchronizer
   void registerPBCSynchronizer();
 
   /* ------------------------------------------------------------------------ */
   /* Explicit                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   /// initialize the stuff for the explicit scheme
   void initExplicit();
 
   /// initialize the array needed by updateResidual (residual, current_position)
   void initializeUpdateResidualData();
 
   /// update the current position vector
   void updateCurrentPosition();
 
   /// assemble the residual for the explicit scheme
   void updateResidual(bool need_initialize = true);
 
   /**
    * \brief compute the acceleration from the residual
    * this function is the explicit equivalent to solveDynamic in implicit
    * In the case of lumped mass just divide the residual by the mass
    * In the case of not lumped mass call solveDynamic<_acceleration_corrector>
    */
   void updateAcceleration();
 
   /// Solve the system @f[ A x = \alpha b @f] with A a lumped matrix
   void solveLumped(Vector<Real> & x, 
 		   const Vector<Real> & A,
 		   const Vector<Real> & b,
 		   const Vector<bool> & boundary,
 		   Real alpha);
 
   /// explicit integration predictor
   void explicitPred();
 
   /// explicit integration corrector
   void explicitCorr();
 
   /* ------------------------------------------------------------------------ */
   /* Implicit                                                                 */
   /* ------------------------------------------------------------------------ */
 public:
 
   /// initialize the solver and the jacobian_matrix (called by initImplicit)
   void initSolver(SolverOptions & options = _solver_no_options);
 
   /// initialize the stuff for the implicit solver
   void initImplicit(bool dynamic = false,
                     SolverOptions & solver_options = _solver_no_options);
 
   /// solve Ma = f to get the initial acceleration
   void initialAcceleration();
 
   /// assemble the stiffness matrix
   void assembleStiffnessMatrix();
 
   /// solve @f[ A\delta u = f_ext - f_int @f] in displacement
   void solveDynamic();
 
   /// solve Ku = f
   void solveStatic();
 
   /// test the convergence (norm of increment)
   bool testConvergenceIncrement(Real tolerance);
   bool testConvergenceIncrement(Real tolerance, Real & error);
 
   /// test the convergence (norm of residual)
   bool testConvergenceResidual(Real tolerance);
   bool testConvergenceResidual(Real tolerance, Real & error);
 
   /// implicit time integration predictor
   void implicitPred();
 
   /// implicit time integration corrector
   void implicitCorr();
 
 protected:
   /// finish the computation of residual to solve in increment
   void updateResidualInternal();
 
   /// compute the support reaction and store it in force
   void updateSupportReaction();
 
   /// compute A and solve @f[ A\delta u = f_ext - f_int @f]
   template<NewmarkBeta::IntegrationSchemeCorrectorType type>
   void solveDynamic(Vector<Real> & increment);
 
   /* ------------------------------------------------------------------------ */
   /* Explicit/Implicit                                                        */
   /* ------------------------------------------------------------------------ */
 public:
   /// compute the stresses
   void computeStresses();
 
   /* ------------------------------------------------------------------------ */
   /* Boundaries (solid_mechanics_model_boundary.cc)                           */
   /* ------------------------------------------------------------------------ */
 public:
   class SurfaceLoadFunctor {
   public:
     virtual void traction(__attribute__ ((unused)) const types::Vector<Real> & position,
 			  __attribute__ ((unused)) types::Vector<Real> & traction,
 			  __attribute__ ((unused)) const types::Vector<Real> & normal,
 			  __attribute__ ((unused)) Surface surface_id) {
       AKANTU_DEBUG_TO_IMPLEMENT();
     }
 
     virtual void stress(__attribute__ ((unused)) const types::Vector<Real> & position,
 			__attribute__ ((unused)) types::RMatrix & stress,
 			__attribute__ ((unused)) const types::Vector<Real> & normal,
 			__attribute__ ((unused)) Surface surface_id) {
       AKANTU_DEBUG_TO_IMPLEMENT();
     }
   };
 
   /// compute force vector from a function(x,y,z) that describe stresses
   void computeForcesFromFunction(BoundaryFunction in_function,
 				 BoundaryFunctionType function_type) __attribute__((deprecated));
 
   template<class Functor>
   void computeForcesFromFunction(Functor & functor, BoundaryFunctionType function_type);
 
   /// integrate a force on the boundary by providing a stress tensor
   void computeForcesByStressTensor(const Vector<Real> & stresses,
 				   const ElementType & type,
 				   const GhostType & ghost_type);
 
   /// integrate a force on the boundary by providing a traction vector
   void computeForcesByTractionVector(const Vector<Real> & tractions,
 				     const ElementType & type,
 				     const GhostType & ghost_type);
 
   /// synchronize the ghost element boundaries values
   void synchronizeBoundaries();
 
   /* ------------------------------------------------------------------------ */
   /* Materials (solid_mechanics_model_material.cc)                            */
   /* ------------------------------------------------------------------------ */
 public:
   /// register a material in the dynamic database
   Material & registerNewMaterial(const ID & mat_type,
 				 const std::string & opt_param = "");
 
   template <typename M>
   Material & registerNewCustomMaterial(const ID & mat_type,
 				       const std::string & opt_param = "");
   /// read the material files to instantiate all the materials
   void readMaterials(const std::string & filename);
 
   /// read a custom material with a keyword and class as template
   template <typename M>
   UInt readCustomMaterial(const std::string & filename,
 				const std::string & keyword);
 
   /// Use a UIntData in the mesh to specify the material to use per element
   void setMaterialIDsFromIntData(const std::string & data_name);
 
   /* ------------------------------------------------------------------------ */
   /* Mass (solid_mechanics_model_mass.cc)                                     */
   /* ------------------------------------------------------------------------ */
 public:
 
   /// assemble the lumped mass matrix
   void assembleMassLumped();
 
   /// assemble the mass matrix
   void assembleMass();
 
 
 protected:
   /// assemble the lumped mass matrix for local and ghost elements
   void assembleMassLumped(GhostType ghost_type);
 
   void assembleMass(GhostType ghost_type);
 
   /// fill a vector of rho
   void computeRho(Vector<Real> & rho,
 		  ElementType type,
 		  GhostType ghost_type);
 
 
   /* ------------------------------------------------------------------------ */
   /* Data Accessor inherited members                                          */
   /* ------------------------------------------------------------------------ */
 public:
 
   inline virtual UInt getNbDataForElements(const Vector<Element> & elements,
 					   SynchronizationTag tag) const;
 
   inline virtual void packElementData(CommunicationBuffer & buffer,
 				      const Vector<Element> & elements,
 				      SynchronizationTag tag) const;
 
   inline virtual void unpackElementData(CommunicationBuffer & buffer,
 					const Vector<Element> & elements,
 					SynchronizationTag tag);
 
   inline virtual UInt getNbDataToPack(SynchronizationTag tag) const;
   inline virtual UInt getNbDataToUnpack(SynchronizationTag tag) const;
 
   inline virtual void packData(CommunicationBuffer & buffer,
 			       const UInt index,
 			       SynchronizationTag tag) const;
 
   inline virtual void unpackData(CommunicationBuffer & buffer,
 				 const UInt index,
 				 SynchronizationTag tag);
 
 protected:
   inline void splitElementByMaterial(const Vector<Element> & elements,
 				     Vector<Element> * elements_per_mat) const;
 
-
-  template<typename T>
-  inline void packElementDataHelper(Vector<T> & data_to_pack,
-				    CommunicationBuffer & buffer,
-				    const Vector<Element> & element) const;
-
-  /* -------------------------------------------------------------------------- */
-  template<typename T>
-  inline void unpackElementDataHelper(Vector<T> & data_to_unpack,
-				      CommunicationBuffer & buffer,
-				      const Vector<Element> & element) const;
-
-  /* -------------------------------------------------------------------------- */
-  template<typename T, bool pack_helper>
-  inline void packUnpackElementDataHelper(Vector<T> & data,
-					  CommunicationBuffer & buffer,
-					  const Vector<Element> & element) const;
-
   /* ------------------------------------------------------------------------ */
   /* Mesh Event Handler inherited members                                     */
   /* ------------------------------------------------------------------------ */
 protected:
   virtual void onNodesAdded  (const Vector<UInt> & nodes_list);
   virtual void onNodesRemoved(const Vector<UInt> & element_list,
 			      const Vector<UInt> & new_numbering);
 
   virtual void onElementsAdded  (const Vector<Element> & nodes_list);
   virtual void onElementsRemoved(const Vector<Element> & element_list,
 				 const ByElementTypeUInt & new_numbering);
 
 public:
   virtual void addDumpField(const std::string & field_id);
   virtual void addDumpFieldVector(const std::string & field_id);
   virtual void addDumpFieldTensor(const std::string & field_id);
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
 
   /// return the dimension of the system space
   AKANTU_GET_MACRO(SpatialDimension, spatial_dimension, UInt);
 
   /// get the current value of the time step
   AKANTU_GET_MACRO(TimeStep, time_step, Real);
   /// set the value of the time step
   AKANTU_SET_MACRO(TimeStep, time_step, Real);
 
   /// 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,           Vector<Real> &);
   /// get the SolidMechanicsModel::current_position vector \warn only consistent
   /// after a call to SolidMechanicsModel::updateCurrentPosition
   AKANTU_GET_MACRO(CurrentPosition, *current_position, const Vector<Real> &);
   /// get  the SolidMechanicsModel::increment  vector \warn  only  consistent if
   /// SolidMechanicsModel::setIncrementFlagOn has been called before
   AKANTU_GET_MACRO(Increment,       *increment,              Vector<Real> &);
   /// get the lumped SolidMechanicsModel::mass vector
   AKANTU_GET_MACRO(Mass,            *mass,                   Vector<Real> &);
   /// get the SolidMechanicsModel::velocity vector
   AKANTU_GET_MACRO(Velocity,        *velocity,               Vector<Real> &);
   /// get    the    SolidMechanicsModel::acceleration    vector,   updated    by
   /// SolidMechanicsModel::updateAcceleration
   AKANTU_GET_MACRO(Acceleration,    *acceleration,           Vector<Real> &);
   /// get the SolidMechanicsModel::force vector (boundary forces)
   AKANTU_GET_MACRO(Force,           *force,                  Vector<Real> &);
   /// get     the    SolidMechanicsModel::residual    vector,     computed    by
   /// SolidMechanicsModel::updateResidual
   AKANTU_GET_MACRO(Residual,        *residual,               Vector<Real> &);
   /// get the SolidMechanicsModel::boundary vector
   AKANTU_GET_MACRO(Boundary,        *boundary,               Vector<bool> &);
   /// get the SolidMechnicsModel::incrementAcceleration vector
   AKANTU_GET_MACRO(IncrementAcceleration, *increment_acceleration, Vector<Real> &);
 
   /// get the value of the SolidMechanicsModel::increment_flag
   AKANTU_GET_MACRO(IncrementFlag, increment_flag, bool);
 
   /// get  the SolidMechanicsModel::element_material  vector corresponding  to a
   /// given akantu::ElementType
   //  AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementMaterial, element_material, UInt);
   //  AKANTU_GET_MACRO_BY_ELEMENT_TYPE(ElementMaterial, element_material, UInt);
   //AKANTU_GET_MACRO(ElementMaterial, element_material, const ByElementTypeVector<UInt> &);
 
   /// vectors containing local material element index for each global element index
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(ElementIndexByMaterial, element_index_by_material, UInt);
   AKANTU_GET_MACRO_BY_ELEMENT_TYPE(ElementIndexByMaterial, element_index_by_material, UInt);
   AKANTU_GET_MACRO(ElementIndexByMaterial, element_index_by_material, const ByElementTypeVector<UInt> &);
 
   /// get a particular material
   inline Material & getMaterial(UInt mat_index);
   inline const Material & getMaterial(UInt mat_index) 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();
 
   /// compute the potential energy
   Real getPotentialEnergy();
 
   /// compute the kinetic energy
   Real getKineticEnergy();
 
   /// compute the external work (for impose displacement, the velocity should be given too)
   Real getExternalWork();
 
   /// get the energies
   Real getEnergy(const std::string & energy_id);
 
   /// compute the energy for energy
   Real getEnergy(const std::string & energy_id, ElementType & type, UInt index);
 
   /// set the Contact object
   AKANTU_SET_MACRO(Contact, contact, Contact *);
 
   /**
    * @brief set the SolidMechanicsModel::increment_flag  to on, the activate the
    * update of the SolidMechanicsModel::increment vector
    */
   void setIncrementFlagOn();
 
   /// get the stiffness matrix
   AKANTU_GET_MACRO(StiffnessMatrix, *stiffness_matrix, SparseMatrix &);
 
   /// get the mass matrix
   AKANTU_GET_MACRO(MassMatrix, *mass_matrix, SparseMatrix &);
 
   inline FEM & getFEMBoundary(std::string name = "");
 
   /// get integrator
   AKANTU_GET_MACRO(Integrator, *integrator, const IntegrationScheme2ndOrder &);
 
   /// get access to the internal solver
   AKANTU_GET_MACRO(Solver, *solver, Solver &);
 
 protected:
   /// compute the stable time step
   Real getStableTimeStep(const GhostType & ghost_type);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
 
   /// time step
   Real time_step;
 
   /// conversion coefficient form force/mass to acceleration
   Real f_m2a;
 
   /// displacements array
   Vector<Real> * displacement;
 
   /// lumped mass array
   Vector<Real> * mass;
 
   /// velocities array
   Vector<Real> * velocity;
 
   /// accelerations array
   Vector<Real> * acceleration;
 
   /// accelerations array
   Vector<Real> * increment_acceleration;
 
   /// forces array
   Vector<Real> * force;
 
   /// residuals array
   Vector<Real> * residual;
 
   /// boundaries array
   Vector<bool> * boundary;
 
   /// array of current position used during update residual
   Vector<Real> * current_position;
 
   /// mass matrix
   SparseMatrix * mass_matrix;
 
   /// velocity damping matrix
   SparseMatrix * velocity_damping_matrix;
 
   /// stiffness matrix
   SparseMatrix * stiffness_matrix;
 
   /// jacobian matrix @f[A = cM + dD + K@f] with @f[c = \frac{1}{\beta \Delta t^2}, d = \frac{\gamma}{\beta \Delta t} @f]
   SparseMatrix * jacobian_matrix;
 
   // /// materials of all elements
   // ByElementTypeUInt element_material;
 
   /// vectors containing local material element index for each global element index
   ByElementTypeUInt element_index_by_material;
 
   /// list of used materials
   std::vector<Material *> materials;
 
   /// integration scheme of second order used
   IntegrationScheme2ndOrder * integrator;
 
   /// increment of displacement
   Vector<Real> * increment;
 
   /// flag defining if the increment must be computed or not
   bool increment_flag;
 
   /// solver for implicit
   Solver * solver;
 
   /// object to resolve the contact
   Contact * contact;
 
   /// the spatial dimension
   UInt spatial_dimension;
 
   AnalysisMethod method;
 };
 
 __END_AKANTU__
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 #include "parser.hh"
 #include "material.hh"
 
 __BEGIN_AKANTU__
 
 
 #ifdef AKANTU_USE_IOHELPER
 #  include "dumper_iohelper_tmpl_homogenizing_field.hh"
 #  include "dumper_iohelper_tmpl_material_internal_field.hh"
 #endif
 
 #include "solid_mechanics_model_tmpl.hh"
 
 #if defined (AKANTU_INCLUDE_INLINE_IMPL)
 #  include "solid_mechanics_model_inline_impl.cc"
 #endif
 
 /// standard output stream operator
 inline std::ostream & operator <<(std::ostream & stream, const SolidMechanicsModel & _this)
 {
   _this.printself(stream);
   return stream;
 }
 
 __END_AKANTU__
 
 #endif /* __AKANTU_SOLID_MECHANICS_MODEL_HH__ */
diff --git a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
index 0a49c6f18..4dec2fd56 100644
--- a/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
+++ b/src/model/solid_mechanics/solid_mechanics_model_inline_impl.cc
@@ -1,452 +1,399 @@
 /**
  * @file   solid_mechanics_model_inline_impl.cc
  *
  * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Wed Aug 04 10:58:42 2010
  *
  * @brief  Implementation of the inline functions of the SolidMechanicsModel class
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 inline Material & SolidMechanicsModel::getMaterial(UInt mat_index) {
   AKANTU_DEBUG_IN();
   AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
 		      "The model " << id << " has no material no "<< mat_index);
   AKANTU_DEBUG_OUT();
   return *materials[mat_index];
 }
 
 /* -------------------------------------------------------------------------- */
 inline const Material & SolidMechanicsModel::getMaterial(UInt mat_index) const {
   AKANTU_DEBUG_IN();
   AKANTU_DEBUG_ASSERT(mat_index < materials.size(),
 		      "The model " << id << " has no material no "<< mat_index);
   AKANTU_DEBUG_OUT();
   return *materials[mat_index];
 }
 
 
 /* -------------------------------------------------------------------------- */
 inline FEM & SolidMechanicsModel::getFEMBoundary(std::string name) {
   return dynamic_cast<FEM &>(getFEMClassBoundary<MyFEMType>(name));
 }
 
 /* -------------------------------------------------------------------------- */
 inline void SolidMechanicsModel::splitElementByMaterial(const Vector<Element> & elements,
 						 Vector<Element> * elements_per_mat) const {
   ElementType current_element_type = _not_defined;
   GhostType current_ghost_type = _casper;
   UInt * elem_mat = NULL;
 
   Vector<Element>::const_iterator<Element> it  = elements.begin();
   Vector<Element>::const_iterator<Element> end = elements.end();
   for (; it != end; ++it) {
     const Element & el = *it;
     if(el.type != current_element_type || el.ghost_type != current_ghost_type) {
       current_element_type = el.type;
       current_ghost_type   = el.ghost_type;
       elem_mat = element_index_by_material(el.type, el.ghost_type).storage();
     }
     elements_per_mat[elem_mat[2*el.element+1]].push_back(el);
   }
 }
 
-/* -------------------------------------------------------------------------- */
-template<typename T>
-inline void SolidMechanicsModel::packElementDataHelper(Vector<T> & data_to_pack,
-						       CommunicationBuffer & buffer,
-						       const Vector<Element> & element) const {
-  packUnpackElementDataHelper<T, true>(data_to_pack, buffer, element);
-}
-
-/* -------------------------------------------------------------------------- */
-template<typename T>
-inline void SolidMechanicsModel::unpackElementDataHelper(Vector<T> & data_to_unpack,
-							 CommunicationBuffer & buffer,
-							 const Vector<Element> & element) const {
-  packUnpackElementDataHelper<T, false>(data_to_unpack, buffer, element);
-}
-
-/* -------------------------------------------------------------------------- */
-template<typename T, bool pack_helper>
-inline void SolidMechanicsModel::packUnpackElementDataHelper(Vector<T> & data,
-							     CommunicationBuffer & buffer,
-							     const Vector<Element> & elements) const {
-  UInt nb_component = data.getNbComponent();
-  UInt nb_nodes_per_element = 0;
-
-  ElementType current_element_type = _not_defined;
-  GhostType current_ghost_type = _casper;
-  UInt * conn = NULL;
-
-  Vector<Element>::const_iterator<Element> it  = elements.begin();
-  Vector<Element>::const_iterator<Element> end = elements.end();
-  for (; it != end; ++it) {
-    const Element & el = *it;
-    if(el.type != current_element_type || el.ghost_type != current_ghost_type) {
-      current_element_type = el.type;
-      current_ghost_type   = el.ghost_type;
-      conn = mesh.getConnectivity(el.type, el.ghost_type).storage();
-      nb_nodes_per_element = Mesh::getNbNodesPerElement(el.type);
-    }
-
-    UInt el_offset  = el.element * nb_nodes_per_element;
-    for (UInt n = 0; n < nb_nodes_per_element; ++n) {
-      UInt offset_conn = conn[el_offset + n];
-      types::Vector<T> data_vect(data.storage() + offset_conn * nb_component,
-				 nb_component);
-
-      if(pack_helper)
-	buffer << data_vect;
-      else
-	buffer >> data_vect;
-    }
-  }
-}
-
 /* -------------------------------------------------------------------------- */
 inline UInt SolidMechanicsModel::getNbDataForElements(const Vector<Element> & elements,
 						      SynchronizationTag tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
 
 #ifndef AKANTU_NDEBUG
   size += elements.getSize() * spatial_dimension * sizeof(Real); /// position of the barycenter of the element (only for check)
 #endif
 
   UInt nb_nodes_per_element = 0;
 
   Vector<Element>::const_iterator<Element> it  = elements.begin();
   Vector<Element>::const_iterator<Element> end = elements.end();
   for (; it != end; ++it) {
     const Element & el = *it;
     nb_nodes_per_element += Mesh::getNbNodesPerElement(el.type);
   }
 
   switch(tag) {
   case _gst_smm_mass: {
     size += nb_nodes_per_element * sizeof(Real) * spatial_dimension; // mass vector
     break;
   }
   case _gst_smm_for_strain: {
     size += nb_nodes_per_element * spatial_dimension * sizeof(Real); // displacement
    break;
   }
   case _gst_smm_boundary: {
     // force, displacement, boundary
     size += nb_nodes_per_element * spatial_dimension * (2 * sizeof(Real) + sizeof(bool));
     break;
   }
   default: {  }
   }
 
 
   Vector<Element> * elements_per_mat = new Vector<Element>[materials.size()];
   this->splitElementByMaterial(elements, elements_per_mat);
 
   for (UInt i = 0; i < materials.size(); ++i) {
     size += materials[i]->getNbDataForElements(elements_per_mat[i], tag);
   }
   delete [] elements_per_mat;
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void SolidMechanicsModel::packElementData(CommunicationBuffer & buffer,
 						 const Vector<Element> & elements,
 						 SynchronizationTag tag) const {
   AKANTU_DEBUG_IN();
 
 #ifndef AKANTU_NDEBUG
   Vector<Element>::const_iterator<Element> bit  = elements.begin();
   Vector<Element>::const_iterator<Element> bend = elements.end();
   for (; bit != bend; ++bit) {
     const Element & element = *bit;
     types::RVector barycenter(spatial_dimension);
     mesh.getBarycenter(element.element, element.type, barycenter.storage(), element.ghost_type);
     buffer << barycenter;
   }
 #endif
 
   switch(tag) {
   case _gst_smm_mass: {
-    packElementDataHelper(*mass, buffer, elements);
+    packNodalDataHelper(*mass, buffer, elements);
     break;
   }
   case _gst_smm_for_strain: {
-    packElementDataHelper(*displacement, buffer, elements);
+    packNodalDataHelper(*displacement, buffer, elements);
     break;
   }
   case _gst_smm_boundary: {
-    packElementDataHelper(*force, buffer, elements);
-    packElementDataHelper(*velocity, buffer, elements);
-    packElementDataHelper(*boundary, buffer, elements);
+    packNodalDataHelper(*force, buffer, elements);
+    packNodalDataHelper(*velocity, buffer, elements);
+    packNodalDataHelper(*boundary, buffer, elements);
     break;
   }
   default: {
   }
   }
 
   Vector<Element> * elements_per_mat = new Vector<Element>[materials.size()];
   splitElementByMaterial(elements, elements_per_mat);
 
   for (UInt i = 0; i < materials.size(); ++i) {
     materials[i]->packElementData(buffer, elements_per_mat[i], tag);
   }
 
   delete [] elements_per_mat;
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void SolidMechanicsModel::unpackElementData(CommunicationBuffer & buffer,
 						   const Vector<Element> & elements,
 						   SynchronizationTag tag) {
   AKANTU_DEBUG_IN();
 
 #ifndef AKANTU_NDEBUG
   Vector<Element>::const_iterator<Element> bit  = elements.begin();
   Vector<Element>::const_iterator<Element> bend = elements.end();
   for (; bit != bend; ++bit) {
     const Element & element = *bit;
 
     types::RVector barycenter_loc(spatial_dimension);
     mesh.getBarycenter(element.element, element.type, barycenter_loc.storage(), element.ghost_type);
 
     types::RVector barycenter(spatial_dimension);
     buffer >> barycenter;
     Real tolerance = 1e-15;
     for (UInt i = 0; i < spatial_dimension; ++i) {
       if(!(std::abs(barycenter(i) - barycenter_loc(i)) <= tolerance))
 	AKANTU_DEBUG_ERROR("Unpacking an unknown value for the element: "
 			   << element
 			   << "(barycenter[" << i << "] = " << barycenter_loc(i)
 			   << " and buffer[" << i << "] = " << barycenter(i) << ") - tag: " << tag);
     }
   }
 #endif
 
   switch(tag) {
   case _gst_smm_mass: {
-    unpackElementDataHelper(*mass, buffer, elements);
+    unpackNodalDataHelper(*mass, buffer, elements);
     break;
   }
   case _gst_smm_for_strain: {
-    unpackElementDataHelper(*displacement, buffer, elements);
+    unpackNodalDataHelper(*displacement, buffer, elements);
     break;
   }
   case _gst_smm_boundary: {
-    unpackElementDataHelper(*force, buffer, elements);
-    unpackElementDataHelper(*velocity, buffer, elements);
-    unpackElementDataHelper(*boundary, buffer, elements);
+    unpackNodalDataHelper(*force, buffer, elements);
+    unpackNodalDataHelper(*velocity, buffer, elements);
+    unpackNodalDataHelper(*boundary, buffer, elements);
     break;
   }
   default: {
   }
   }
 
   Vector<Element> * elements_per_mat = new Vector<Element>[materials.size()];
   splitElementByMaterial(elements, elements_per_mat);
 
   for (UInt i = 0; i < materials.size(); ++i) {
     materials[i]->unpackElementData(buffer, elements_per_mat[i], tag);
   }
 
   delete [] elements_per_mat;
 
   AKANTU_DEBUG_OUT();
 }
 
 
 /* -------------------------------------------------------------------------- */
 inline UInt SolidMechanicsModel::getNbDataToPack(SynchronizationTag tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   //  UInt nb_nodes = mesh.getNbNodes();
 
   switch(tag) {
   case _gst_smm_uv: {
     size += sizeof(Real) * spatial_dimension * 2;
     break;
   }
   case _gst_smm_res: {
     size += sizeof(Real) * spatial_dimension;
     break;
   }
   case _gst_smm_mass: {
     size += sizeof(Real) * spatial_dimension;
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline UInt SolidMechanicsModel::getNbDataToUnpack(SynchronizationTag tag) const {
   AKANTU_DEBUG_IN();
 
   UInt size = 0;
   //  UInt nb_nodes = mesh.getNbNodes();
 
   switch(tag) {
   case _gst_smm_uv: {
     size += sizeof(Real) * spatial_dimension * 2;
     break;
   }
   case _gst_smm_res: {
     size += sizeof(Real) * spatial_dimension;
     break;
   }
   case _gst_smm_mass: {
     size += sizeof(Real) * spatial_dimension;
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
   return size;
 }
 
 /* -------------------------------------------------------------------------- */
 inline void SolidMechanicsModel::packData(CommunicationBuffer & buffer,
 					  const UInt index,
 					  SynchronizationTag tag) const {
   AKANTU_DEBUG_IN();
 
   switch(tag) {
   case _gst_smm_uv: {
     Vector<Real>::iterator<types::RVector> it_disp = displacement->begin(spatial_dimension);
     Vector<Real>::iterator<types::RVector> it_velo = velocity->begin(spatial_dimension);
     buffer << it_disp[index];
     buffer << it_velo[index];
     break;
   }
   case _gst_smm_res: {
     Vector<Real>::iterator<types::RVector> it_res = residual->begin(spatial_dimension);
     buffer << it_res[index];
     break;
   }
   case _gst_smm_mass: {
     AKANTU_DEBUG_INFO("pack mass of node " << index << " which is " << (*mass)(index,0));
     Vector<Real>::iterator<types::RVector> it_mass = mass->begin(spatial_dimension);
     buffer << it_mass[index];
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 inline void SolidMechanicsModel::unpackData(CommunicationBuffer & buffer,
 					    const UInt index,
 					    SynchronizationTag tag) {
   AKANTU_DEBUG_IN();
 
   switch(tag) {
   case _gst_smm_uv: {
     Vector<Real>::iterator<types::RVector> it_disp = displacement->begin(spatial_dimension);
     Vector<Real>::iterator<types::RVector> it_velo = velocity->begin(spatial_dimension);
     buffer >> it_disp[index];
     buffer >> it_velo[index];
     break;
   }
   case _gst_smm_res: {
     Vector<Real>::iterator<types::RVector> it_res = residual->begin(spatial_dimension);
     buffer >> it_res[index];
     break;
   }
   case _gst_smm_mass: {
     AKANTU_DEBUG_INFO("mass of node " << index << " was " << (*mass)(index,0));
     Vector<Real>::iterator<types::RVector> it_mass = mass->begin(spatial_dimension);
     buffer >> it_mass[index];
     AKANTU_DEBUG_INFO("mass of node " << index << " is now " << (*mass)(index,0));
     break;
   }
   default: {
     AKANTU_DEBUG_ERROR("Unknown ghost synchronization tag : " << tag);
   }
   }
 
   AKANTU_DEBUG_OUT();
 }
 
 
 __END_AKANTU__
 #include "sparse_matrix.hh"
 #include "solver.hh"
 __BEGIN_AKANTU__
 
 /* -------------------------------------------------------------------------- */
 template<NewmarkBeta::IntegrationSchemeCorrectorType type>
 void SolidMechanicsModel::solveDynamic(Vector<Real> & increment) {
   AKANTU_DEBUG_INFO("Solving Ma + Cv + Ku = f");
 
   NewmarkBeta * nmb_int = dynamic_cast<NewmarkBeta *>(integrator);
   Real c = nmb_int->getAccelerationCoefficient<type>(time_step);
   Real d = nmb_int->getVelocityCoefficient<type>(time_step);
   Real e = nmb_int->getDisplacementCoefficient<type>(time_step);
 
   // A = c M + d C + e K
   jacobian_matrix->clear();
 
   if(type != NewmarkBeta::_acceleration_corrector)
     jacobian_matrix->add(*stiffness_matrix, e);
 
   jacobian_matrix->add(*mass_matrix, c);
 
   mass_matrix->saveMatrix("M.mtx");
   if(velocity_damping_matrix)
     jacobian_matrix->add(*velocity_damping_matrix, d);
 
   jacobian_matrix->applyBoundary(*boundary);
 
 #ifndef AKANTU_NDEBUG
   if(AKANTU_DEBUG_TEST(dblDump))
     jacobian_matrix->saveMatrix("J.mtx");
 #endif
 
   jacobian_matrix->saveMatrix("J.mtx");
 
   solver->setRHS(*residual);
 
   // solve A w = f
   solver->solve(increment);
 }
 /* -------------------------------------------------------------------------- */
diff --git a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d.cc b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d.cc
index 31e16dbba..e2432631f 100644
--- a/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d.cc
+++ b/test/test_model/test_heat_transfer_model/test_heat_transfer_model_square2d.cc
@@ -1,167 +1,168 @@
 /**
  * @file   test_heat_transfer_model_square2d.cc
  *
  *
  * @date   Sun May 01 19:14:43 2011
  *
  * @brief  test of the class HeatTransferModel on the 3d cube
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 #include "mesh_io.hh"
 #include "mesh_io_msh.hh"
 #include "heat_transfer_model.hh"
 #include "pbc_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <fstream>
-#include <string.h>
+#include <string>
 using namespace std;
 /* -------------------------------------------------------------------------- */
 
-#ifdef AKANTU_USE_IOHELPER
 #include "io_helper.hh"
 
 static void paraviewInit(akantu::HeatTransferModel & model, iohelper::Dumper & dumper);
 static void paraviewDump(iohelper::Dumper & dumper);
 iohelper::ElemType paraview_type = iohelper::TRIANGLE1;
 
-#endif //AKANTU_USE_IOHELPER
-
 /* -------------------------------------------------------------------------- */
 akantu::UInt spatial_dimension = 2;
 akantu:: ElementType type = akantu::_triangle_3;
 /* -------------------------------------------------------------------------- */
 
+std::string base_name;
+
 int main(int argc, char *argv[])
 {
   akantu::debug::setDebugLevel(akantu::dblWarning);
   akantu::initialize(argc, argv);
 
   //create mesh
   akantu::Mesh mesh(spatial_dimension);
   akantu::MeshIOMSH mesh_io;
   mesh_io.read("square_tri3.msh", mesh);
   
   akantu::HeatTransferModel model(mesh);
   //initialize everything
   model.initFull("material.dat");
   
   //assemble the lumped capacity
   model.assembleCapacityLumped();
   
   //get stable time step
   akantu::Real time_step = model.getStableTimeStep()*0.8;
   cout<<"time step is:" << time_step << endl;
   model.setTimeStep(time_step);
   
   //boundary conditions
   const akantu::Vector<akantu::Real> & nodes = model.getFEM().getMesh().getNodes();
   akantu::Vector<bool> & boundary = model.getBoundary();
   akantu::Vector<akantu::Real> & temperature = model.getTemperature();
   double length;
   length = 1.;
   akantu::UInt nb_nodes = model.getFEM().getMesh().getNbNodes();
   for (akantu::UInt i = 0; i < nb_nodes; ++i) {
     temperature(i) = 100.;
 
     akantu::Real dx = nodes(i,0) - length/4.;
     akantu::Real dy = 0.0;
     akantu::Real dz = 0.0;
 
     if (spatial_dimension > 1) dy = nodes(i,1) - length/4.;
     if (spatial_dimension == 3) dz = nodes(i,2) - length/4.;
     akantu::Real d = sqrt(dx*dx + dy*dy + dz*dz);
     //    if(dx < 0.0){
     if(d < 0.1){
       boundary(i) = true;
       temperature(i) = 300.;
     }
   }
 
-#ifdef AKANTU_USE_IOHELPER
   iohelper::DumperParaview dumper;
   paraviewInit(model,dumper);
-#endif
+
   //main loop
   int max_steps = 1000;
   for(int i=0; i<max_steps; i++)
     {
       model.explicitPred();
       model.updateResidual();
       model.explicitCorr();
       
 #ifdef AKANTU_USE_IOHELPER
       if(i % 100 == 0)
 	paraviewDump(dumper);
 #endif
       if(i % 10 == 0)
       std::cout << "Step " << i << "/" << max_steps << std::endl;
     }
   cout<< "\n\n Stable Time Step is : " << time_step << "\n \n" <<endl;
 
   return 0;
 }
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_IOHELPER
-/* -------------------------------------------------------------------------- */
 
 void paraviewInit(akantu::HeatTransferModel & model, iohelper::Dumper & dumper) {
-  // akantu::UInt nb_nodes = model.getFEM().getMesh().getNbNodes();
-  // akantu::UInt nb_element = model.getFEM().getMesh().getNbElement(type);
+  base_name =  "coordinates2";
+  akantu::UInt nb_nodes = model.getFEM().getMesh().getNbNodes();
+  akantu::UInt nb_element = model.getFEM().getMesh().getNbElement(type);
 
 #pragma message "To change with new dumper"
-  // //  dumper.SetMode(iohelper::TEXT);
-  // dumper.SetPoints(model.getFEM().getMesh().getNodes().values,
-  // 		   spatial_dimension, nb_nodes, "coordinates2");
-  // dumper.SetConnectivity((int *)model.getFEM().getMesh().getConnectivity(type).values,
-  // 			 paraview_type, nb_element, iohelper::C_MODE);
-  // dumper.AddNodeDataField(model.getTemperature().values,
-  // 			  1, "temperature");
-  // dumper.AddNodeDataField(model.getTemperatureRate().values,
+  //  dumper.SetMode(iohelper::TEXT);
+  dumper.setPoints(model.getFEM().getMesh().getNodes().values,
+  		   spatial_dimension, nb_nodes, base_name);
+  dumper.setConnectivity((int *)model.getFEM().getMesh().getConnectivity(type).values,
+  			 paraview_type, nb_element, iohelper::C_MODE);
+  dumper.addNodeDataField("temperature",model.getTemperature().values,
+  			  1,nb_nodes);
+  // dumper.addNodeDataField(model.getTemperatureRate().values,
   //  			  1, "temperature_rate");
-  // dumper.AddNodeDataField(model.getResidual().values,
+  // dumper.addNodeDataField(model.getResidual().values,
   //  			  1, "residual");
-  // dumper.AddNodeDataField(model.getCapacityLumped().values,
+  // dumper.addNodeDataField(model.getCapacityLumped().values,
   //  			  1, "capacity_lumped");
-  // dumper.AddElemDataField(model.getTemperatureGradient(type).values,
+  // dumper.addElemDataField(model.getTemperatureGradient(type).values,
   //   			  spatial_dimension, "temperature_gradient");
 
-  // dumper.AddElemDataField(model.getConductivityOnQpoints(type).values,
+  // dumper.addElemDataField(model.getConductivityOnQpoints(type).values,
   //   			  spatial_dimension*spatial_dimension, "conductivity_qpoints");
 
 
-  // dumper.SetPrefix("paraview/");
-  // dumper.Init();
+  dumper.setPrefix("./");
+  dumper.init();
 }
 
 /* -------------------------------------------------------------------------- */
 
 void paraviewDump(iohelper::Dumper & dumper) {
-  //  dumper.Dump();
-}
+  static int dump_step = 0;
+  std::stringstream sstr;
+  sstr << base_name << "-";
+  sstr.width(5);
+  sstr.fill('0');
+  sstr << dump_step;
 
-/* -------------------------------------------------------------------------- */
-#endif
-/* -------------------------------------------------------------------------- */
+  dumper.dump(sstr.str());
+
+  ++dump_step;
+}