diff --git a/packages/00_core.cmake b/packages/00_core.cmake
index bdf3e8fc3..b8e823857 100644
--- a/packages/00_core.cmake
+++ b/packages/00_core.cmake
@@ -1,432 +1,434 @@
 #===============================================================================
 # @file   00_core.cmake
 #
 # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date creation: Mon Nov 21 2011
 # @date last modification: Fri Sep 19 2014
 #
 # @brief  package description for core
 #
 # @section LICENSE
 #
 # Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
 # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
 #
 # Akantu is free  software: you can redistribute it and/or  modify it under the
 # terms  of the  GNU Lesser  General Public  License as  published by  the Free
 # Software Foundation, either version 3 of the License, or (at your option) any
 # later version.
 #
 # Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
 # details.
 #
 # 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_CORE ON CACHE INTERNAL "core package for Akantu" FORCE)
 
 set(AKANTU_CORE_FILES
   common/aka_array.cc
   common/aka_array.hh
   common/aka_array_tmpl.hh
   common/aka_blas_lapack.hh
   common/aka_circular_array.hh
   common/aka_circular_array_inline_impl.cc
   common/aka_common.cc
   common/aka_common.hh
   common/aka_common_inline_impl.cc
   common/aka_csr.hh
   common/aka_error.cc
   common/aka_error.hh
   common/aka_event_handler_manager.hh
   common/aka_extern.cc
   common/aka_fwd.hh
   common/aka_grid_dynamic.hh
   common/aka_math.cc
   common/aka_math.hh
   common/aka_math_tmpl.hh
   common/aka_memory.cc
   common/aka_memory.hh
   common/aka_memory_inline_impl.cc
   common/aka_random_generator.hh
   common/aka_safe_enum.hh
   common/aka_static_memory.cc
   common/aka_static_memory.hh
   common/aka_static_memory_inline_impl.cc
   common/aka_static_memory_tmpl.hh
   common/aka_typelist.hh
   common/aka_types.hh
   common/aka_visitor.hh
   common/aka_voigthelper.hh
   common/aka_voigthelper.cc
 
   fe_engine/element_class.cc
   fe_engine/element_class.hh
   fe_engine/element_class_tmpl.hh
   fe_engine/element_classes/element_class_hexahedron_8_inline_impl.cc
   fe_engine/element_classes/element_class_pentahedron_6_inline_impl.cc
   fe_engine/element_classes/element_class_point_1_inline_impl.cc
   fe_engine/element_classes/element_class_quadrangle_4_inline_impl.cc
   fe_engine/element_classes/element_class_quadrangle_8_inline_impl.cc
   fe_engine/element_classes/element_class_segment_2_inline_impl.cc
   fe_engine/element_classes/element_class_segment_3_inline_impl.cc
   fe_engine/element_classes/element_class_tetrahedron_10_inline_impl.cc
   fe_engine/element_classes/element_class_tetrahedron_4_inline_impl.cc
   fe_engine/element_classes/element_class_triangle_3_inline_impl.cc
   fe_engine/element_classes/element_class_triangle_6_inline_impl.cc
 
   fe_engine/fe_engine.cc
   fe_engine/fe_engine.hh
   fe_engine/fe_engine_inline_impl.cc
   fe_engine/fe_engine_template.hh
   fe_engine/fe_engine_template_tmpl.hh
   fe_engine/geometrical_data_tmpl.hh
   fe_engine/geometrical_element.cc
   fe_engine/integration_element.cc
   fe_engine/integrator.hh
   fe_engine/integrator_gauss.hh
   fe_engine/integrator_gauss_inline_impl.cc
   fe_engine/interpolation_element.cc
   fe_engine/interpolation_element_tmpl.hh
   fe_engine/shape_functions.hh
   fe_engine/shape_functions_inline_impl.cc
   fe_engine/shape_lagrange.cc
   fe_engine/shape_lagrange.hh
   fe_engine/shape_lagrange_inline_impl.cc
   fe_engine/shape_linked.cc
   fe_engine/shape_linked.hh
   fe_engine/shape_linked_inline_impl.cc
   fe_engine/element.hh
 
   io/dumper/dumpable.hh
   io/dumper/dumpable.cc
   io/dumper/dumpable_inline_impl.hh
   io/dumper/dumper_field.hh
   io/dumper/dumper_material_padders.hh
   io/dumper/dumper_filtered_connectivity.hh
   io/dumper/dumper_element_type.hh
   io/dumper/dumper_element_partition.hh
 
   io/mesh_io.cc
   io/mesh_io.hh
   io/mesh_io/mesh_io_abaqus.cc
   io/mesh_io/mesh_io_abaqus.hh
   io/mesh_io/mesh_io_diana.cc
   io/mesh_io/mesh_io_diana.hh
   io/mesh_io/mesh_io_msh.cc
   io/mesh_io/mesh_io_msh.hh
   io/model_io.cc
   io/model_io.hh
 
   io/parser/algebraic_parser.hh
   io/parser/input_file_parser.hh
   io/parser/parsable.cc
   io/parser/parsable.hh
   io/parser/parsable_tmpl.hh
   io/parser/parser.cc
   io/parser/parser.hh
   io/parser/parser_tmpl.hh
   io/parser/cppargparse/cppargparse.hh
   io/parser/cppargparse/cppargparse.cc
   io/parser/cppargparse/cppargparse_tmpl.hh
 
   mesh/element_group.cc
   mesh/element_group.hh
   mesh/element_group_inline_impl.cc
   mesh/element_type_map.hh
   mesh/element_type_map_tmpl.hh
   mesh/element_type_map_filter.hh
   mesh/group_manager.cc
   mesh/group_manager.hh
   mesh/group_manager_inline_impl.cc
   mesh/mesh.cc
   mesh/mesh.hh
   mesh/mesh_filter.hh
   mesh/mesh_data.cc
   mesh/mesh_data.hh
   mesh/mesh_data_tmpl.hh
   mesh/mesh_inline_impl.cc
   mesh/node_group.cc
   mesh/node_group.hh
   mesh/node_group_inline_impl.cc
 
   mesh_utils/mesh_partition.cc
   mesh_utils/mesh_partition.hh
   mesh_utils/mesh_partition/mesh_partition_mesh_data.cc
   mesh_utils/mesh_partition/mesh_partition_mesh_data.hh
   mesh_utils/mesh_partition/mesh_partition_scotch.hh
   mesh_utils/mesh_pbc.cc
   mesh_utils/mesh_utils.cc
   mesh_utils/mesh_utils.hh
   mesh_utils/mesh_utils_inline_impl.cc
 
   model/boundary_condition.hh
   model/boundary_condition_functor.hh
   model/boundary_condition_functor_inline_impl.cc
   model/boundary_condition_tmpl.hh
   model/integration_scheme/generalized_trapezoidal.hh
   model/integration_scheme/generalized_trapezoidal_inline_impl.cc
   model/integration_scheme/integration_scheme_1st_order.hh
   model/integration_scheme/integration_scheme_2nd_order.hh
   model/integration_scheme/newmark-beta.hh
   model/integration_scheme/newmark-beta_inline_impl.cc
   model/model.cc
   model/model.hh
   model/model_inline_impl.cc
 
   model/solid_mechanics/material.cc
   model/solid_mechanics/material.hh
   model/solid_mechanics/material_inline_impl.cc
   model/solid_mechanics/material_list.hh
   model/solid_mechanics/material_random_internal.hh
   model/solid_mechanics/material_selector.hh
   model/solid_mechanics/material_selector_tmpl.hh
   model/solid_mechanics/materials/internal_field.hh
   model/solid_mechanics/materials/internal_field_tmpl.hh
   model/solid_mechanics/materials/random_internal_field.hh
   model/solid_mechanics/materials/random_internal_field_tmpl.hh
   model/solid_mechanics/solid_mechanics_model.cc
   model/solid_mechanics/solid_mechanics_model.hh
   model/solid_mechanics/solid_mechanics_model_inline_impl.cc
   model/solid_mechanics/solid_mechanics_model_mass.cc
   model/solid_mechanics/solid_mechanics_model_material.cc
   model/solid_mechanics/solid_mechanics_model_tmpl.hh
   model/solid_mechanics/solid_mechanics_model_event_handler.hh
   model/solid_mechanics/materials/plane_stress_toolbox.hh
   model/solid_mechanics/materials/plane_stress_toolbox_tmpl.hh
 
 
   model/solid_mechanics/materials/material_elastic.cc
   model/solid_mechanics/materials/material_elastic.hh
   model/solid_mechanics/materials/material_elastic_inline_impl.cc
   model/solid_mechanics/materials/material_thermal.cc
   model/solid_mechanics/materials/material_thermal.hh
   model/solid_mechanics/materials/material_elastic_linear_anisotropic.cc
   model/solid_mechanics/materials/material_elastic_linear_anisotropic.hh
   model/solid_mechanics/materials/material_elastic_orthotropic.cc
   model/solid_mechanics/materials/material_elastic_orthotropic.hh
   model/solid_mechanics/materials/material_damage/material_damage.hh
   model/solid_mechanics/materials/material_damage/material_damage_tmpl.hh
   model/solid_mechanics/materials/material_damage/material_marigo.cc
   model/solid_mechanics/materials/material_damage/material_marigo.hh
   model/solid_mechanics/materials/material_damage/material_marigo_inline_impl.cc
   model/solid_mechanics/materials/material_damage/material_mazars.cc
   model/solid_mechanics/materials/material_damage/material_mazars.hh
   model/solid_mechanics/materials/material_damage/material_mazars_inline_impl.cc
   model/solid_mechanics/materials/material_finite_deformation/material_neohookean.cc
   model/solid_mechanics/materials/material_finite_deformation/material_neohookean.hh
   model/solid_mechanics/materials/material_finite_deformation/material_neohookean_inline_impl.cc
   model/solid_mechanics/materials/material_plastic/material_plastic.cc
   model/solid_mechanics/materials/material_plastic/material_plastic.hh
   model/solid_mechanics/materials/material_plastic/material_plastic_inline_impl.cc
   model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.cc
   model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening.hh
   model/solid_mechanics/materials/material_plastic/material_linear_isotropic_hardening_inline_impl.cc
   model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.cc
   model/solid_mechanics/materials/material_viscoelastic/material_standard_linear_solid_deviatoric.hh
 
 
 
   solver/solver.cc
   solver/solver.hh
   solver/sparse_matrix.cc
   solver/sparse_matrix.hh
   solver/sparse_matrix_inline_impl.cc
+  solver/static_solver.hh
+  solver/static_solver.cc
 
   synchronizer/communication_buffer.hh
   synchronizer/communication_buffer_inline_impl.cc
   synchronizer/data_accessor.cc
   synchronizer/data_accessor.hh
   synchronizer/data_accessor_inline_impl.cc
   synchronizer/distributed_synchronizer.cc
   synchronizer/distributed_synchronizer.hh
   synchronizer/distributed_synchronizer_tmpl.hh
   synchronizer/dof_synchronizer.cc
   synchronizer/dof_synchronizer.hh
   synchronizer/dof_synchronizer_inline_impl.cc
   synchronizer/filtered_synchronizer.cc
   synchronizer/filtered_synchronizer.hh
   synchronizer/mpi_type_wrapper.hh
   synchronizer/pbc_synchronizer.cc
   synchronizer/pbc_synchronizer.hh
   synchronizer/real_static_communicator.hh
   synchronizer/static_communicator.cc
   synchronizer/static_communicator.hh
   synchronizer/static_communicator_dummy.hh
   synchronizer/static_communicator_inline_impl.hh
   synchronizer/synchronizer.cc
   synchronizer/synchronizer.hh
   synchronizer/synchronizer_registry.cc
   synchronizer/synchronizer_registry.hh
   )
 
 
 set(AKANTU_CORE_DEB_DEPEND
   libboost-dev
   )
 
 set(AKANTU_CORE_TESTS
   test_csr
   test_facet_element_mapping
   test_facet_extraction_tetrahedron_4
   test_facet_extraction_triangle_3
   test_grid
   test_interpolate_stress
   test_local_material
   test_material_damage_non_local
   test_material_thermal
   test_matrix
   test_mesh_boundary
   test_mesh_data
   test_mesh_io_msh
   test_mesh_io_msh_physical_names
   test_mesh_partitionate_mesh_data
   test_parser
   test_dumper
   test_pbc_tweak
   test_purify_mesh
   test_solid_mechanics_model_bar_traction2d
   test_solid_mechanics_model_bar_traction2d_structured
   test_solid_mechanics_model_bar_traction2d_structured_pbc
   test_solid_mechanics_model_boundary_condition
   test_solid_mechanics_model_circle_2
   test_solid_mechanics_model_cube3d
   test_solid_mechanics_model_cube3d_pbc
   test_solid_mechanics_model_cube3d_tetra10
   test_solid_mechanics_model_square
   test_solid_mechanics_model_material_eigenstrain
   test_static_memory
   test_surface_extraction_tetrahedron_4
   test_surface_extraction_triangle_3
   test_vector
   test_vector_iterator
   test_weight
   test_math
   test_material_standard_linear_solid_deviatoric_relaxation
   test_material_standard_linear_solid_deviatoric_relaxation_tension
   test_material_plasticity
   )
 
 set(AKANTU_CORE_MANUAL_FILES
   manual.sty
   manual.cls
   manual.tex
   manual-macros.sty
   manual-titlepages.tex
   manual-introduction.tex
   manual-gettingstarted.tex
   manual-io.tex
   manual-solidmechanicsmodel.tex
   manual-constitutive-laws.tex
   manual-lumping.tex
   manual-elements.tex
   manual-appendix-elements.tex
   manual-appendix-materials.tex
   manual-appendix-packages.tex
   manual-backmatter.tex
   manual-bibliography.bib
   manual-bibliographystyle.bst
 
   figures/bc_and_ic_example.pdf
   figures/boundary.pdf
   figures/boundary.svg
   figures/dirichlet.pdf
   figures/dirichlet.svg
   figures/doc_wheel.pdf
   figures/doc_wheel.svg
   figures/dynamic_analysis.png
   figures/explicit_dynamic.pdf
   figures/explicit_dynamic.svg
   figures/static.pdf
   figures/static.svg
   figures/hooke_law.pdf
   figures/hot-point-1.png
   figures/hot-point-2.png
   figures/implicit_dynamic.pdf
   figures/implicit_dynamic.svg
   figures/insertion.pdf
   figures/interpolate.pdf
   figures/interpolate.svg
   figures/problemDomain.pdf_tex
   figures/problemDomain.pdf
   figures/static_analysis.png
   figures/stress_strain_el.pdf
   figures/tangent.pdf
   figures/tangent.svg
   figures/vectors.pdf
   figures/vectors.svg
 
   figures/stress_strain_neo.pdf
   figures/visco_elastic_law.pdf
   figures/isotropic_hardening_plasticity.pdf
   figures/stress_strain_visco.pdf
 
   figures/elements/hexahedron_8.pdf
   figures/elements/hexahedron_8.svg
   figures/elements/quadrangle_4.pdf
   figures/elements/quadrangle_4.svg
   figures/elements/quadrangle_8.pdf
   figures/elements/quadrangle_8.svg
   figures/elements/segment_2.pdf
   figures/elements/segment_2.svg
   figures/elements/segment_3.pdf
   figures/elements/segment_3.svg
   figures/elements/tetrahedron_10.pdf
   figures/elements/tetrahedron_10.svg
   figures/elements/tetrahedron_4.pdf
   figures/elements/tetrahedron_4.svg
   figures/elements/triangle_3.pdf
   figures/elements/triangle_3.svg
   figures/elements/triangle_6.pdf
   figures/elements/triangle_6.svg
   figures/elements/xtemp.pdf
   )
 
 find_program(READLINK_COMMAND readlink)
 find_program(ADDR2LINE_COMMAND addr2line)
 mark_as_advanced(READLINK_COMMAND)
 mark_as_advanced(ADDR2LINE_COMMAND)
 
 include(CheckFunctionExists)
 
 check_function_exists(clock_gettime _clock_gettime)
 
 if(NOT _clock_gettime)
   set(AKANTU_USE_OBSOLETE_GETTIMEOFDAY ON)
 else()
   set(AKANTU_USE_OBSOLETE_GETTIMEOFDAY OFF)
 endif()
 
 set(AKANTU_CORE_DOCUMENTATION
 "
 This package is the core engine of \\akantu. It depends on:
 \\begin{itemize}
 \\item A C++ compiler (\\href{http://gcc.gnu.org/}{GCC} >= 4, or \\href{https://software.intel.com/en-us/intel-compilers}{Intel}).
 \\item The cross-platform, open-source \\href{http://www.cmake.org/}{CMake} build system.
 \\item The \\href{http://www.boost.org/}{Boost} C++ portable libraries.
 \\item The \\href{http://www.zlib.net/}{zlib} compression library.
 \\end{itemize}
 
 Under Ubuntu (14.04 LTS) the installation can be performed using the commands:
 \\begin{command}
   > sudo apt-get install build-essential cmake-curses-gui libboost-dev zlib1g-dev
 \\end{command}
 
 Under Mac OS X the installation requires the following steps:
 \\begin{itemize}
 \\item Install Xcode
 \\item Install the command line tools.
 \\item Install the MacPorts project which allows to automatically 
 download and install opensource packages. 
 \\end{itemize}
 Then the following commands should be typed in a terminal:
 \\begin{command}
   > sudo port install cmake gcc48 boost
 \\end{command}
 ")
\ No newline at end of file
diff --git a/packages/84_petsc.cmake b/packages/84_petsc.cmake
index ad0483993..dceacb9ba 100644
--- a/packages/84_petsc.cmake
+++ b/packages/84_petsc.cmake
@@ -1,41 +1,45 @@
 #===============================================================================
 # @file   petsc.cmake
 #
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 # @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
 # @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
 #
 # @date   Mon Nov 21 18:19:15 2011
 #
 # @brief  package description for PETSc support
 #
 # @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/>.
 #
 #===============================================================================
 
 add_optional_external_package(PETSc "Add PETSc support in akantu" OFF ARGS COMPONENT ARGS CXX)
 add_internal_package_dependencies(petsc parallel)
 
 set(AKANTU_PETSC_FILES
   solver/petsc_matrix.hh
   solver/petsc_matrix.cc
   solver/petsc_matrix_inline_impl.cc
   solver/solver_petsc.hh
   solver/solver_petsc.cc
   )
+
+set(AKANTU_PETSC_TESTS
+  test_petsc_matrix_profile
+  )
diff --git a/src/common/aka_common.cc b/src/common/aka_common.cc
index 92311f159..d5240f3aa 100644
--- a/src/common/aka_common.cc
+++ b/src/common/aka_common.cc
@@ -1,137 +1,145 @@
 /**
  * @file   aka_common.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
  * @date last modification: Mon Sep 15 2014
  *
  * @brief  Initialization of global variables
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_static_memory.hh"
 #include "static_communicator.hh"
+#include "static_solver.hh"
 #include "aka_random_generator.hh"
 
 #include "parser.hh"
 #include "cppargparse.hh"
 
 /* -------------------------------------------------------------------------- */
 
 __BEGIN_AKANTU__
 
 /* -------------------------------------------------------------------------- */
 void initialize(int & argc, char ** & argv) {
   AKANTU_DEBUG_IN();
 
   initialize("", argc, argv);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 void initialize(const std::string & input_file, int & argc, char ** & argv) {
   AKANTU_DEBUG_IN();
   StaticMemory::getStaticMemory();
   StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator(argc, argv);
   debug::debugger.setParallelContext(comm.whoAmI(), comm.getNbProc());
   debug::initSignalHandler();
 
   static_argparser.setParallelContext(comm.whoAmI(), comm.getNbProc());
   static_argparser.setExternalExitFunction(debug::exit);
   static_argparser.addArgument("--aka_input_file", "Akantu's input file",
 			       1, cppargparse::_string, std::string());
   static_argparser.addArgument("--aka_debug_level", std::string("Akantu's overall debug level") +
 			       std::string(" (0: error, 1: exceptions, 4: warnings, 5: info, ..., 100: dump,") +
 			       std::string(" more info on levels can be foind in aka_error.hh)"),
 			       1,
 			       cppargparse::_integer, int(dblWarning));
 
   static_argparser.addArgument("--aka_print_backtrace",
 			       "Should Akantu print a backtrace in case of error",
 			       0,
 			       cppargparse::_boolean, false, true);
 
   static_argparser.parse(argc, argv, cppargparse::_remove_parsed);
 
   
   std::string infile = static_argparser["aka_input_file"];
   if(infile == "") infile = input_file;
 
   debug::setDebugLevel(dblError);
 
   if ("" != infile) {
     static_parser.parse(infile);
   }
 
   long int seed;
   try {
     seed = static_parser.getParameter("seed", _ppsc_current_scope);
   } catch (debug::Exception &) {
     seed = time(NULL);
   }
 
   int dbl_level = static_argparser["aka_debug_level"];
   debug::setDebugLevel(DebugLevel(dbl_level));
   debug::debugger.printBacktrace(static_argparser["aka_print_backtrace"]);
 
   seed *= (comm.whoAmI() + 1);
   Rand48Generator<Real>::seed(seed);
   RandGenerator<Real>::seed(seed);
   AKANTU_DEBUG_INFO("Random seed set to " << seed);
 
+  /// initialize external solvers 
+  StaticSolver::getStaticSolver().initialize(argc, argv);
+
   AKANTU_DEBUG_OUT();
 
 }
 
 /* -------------------------------------------------------------------------- */
 void finalize() {
   AKANTU_DEBUG_IN();
 
+  /// finalize external solvers 
+  StaticSolver::getStaticSolver().finalize();
+
   if(StaticMemory::isInstantiated()) delete &(StaticMemory::getStaticMemory());
   if(StaticCommunicator::isInstantiated()) {
     StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
     comm.barrier();
     delete &comm;
   }
 
+
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 cppargparse::ArgumentParser & getStaticArgumentParser() {
   return static_argparser;
 }
 
 /* -------------------------------------------------------------------------- */
 Parser & getStaticParser() {
   return static_parser;
 }
 
 /* -------------------------------------------------------------------------- */
 const ParserSection & getUserParser() {
   return *(static_parser.getSubSections(_st_user).first);
 }
 
 __END_AKANTU__
diff --git a/src/common/aka_config.hh.in b/src/common/aka_config.hh.in
index 44aad462b..248cf67da 100644
--- a/src/common/aka_config.hh.in
+++ b/src/common/aka_config.hh.in
@@ -1,87 +1,88 @@
 /**
  * @file   aka_config.hh.in
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Fri Jan 13 12:34:54 2012
  *
  * @brief  Compilation time configuration of Akantu
  *
  * @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_CONFIG_HH__
 #define __AKANTU_AKA_CONFIG_HH__
 
 #define AKANTU_VERSION @AKANTU_VERSION@
 #define AKANTU_VERSION_MAJOR @AKANTU_MAJOR_VERSION@
 #define AKANTU_VERSION_MINOR @AKANTU_MINOR_VERSION@
 #define AKANTU_VERSION_PATCH @AKANTU_PATCH_VERSION@
 
 #cmakedefine AKANTU_USE_BLAS
 #cmakedefine AKANTU_USE_LAPACK
 
 #cmakedefine AKANTU_PARALLEL
 #cmakedefine AKANTU_USE_MPI
 
 #cmakedefine AKANTU_USE_SCOTCH
 #cmakedefine AKANTU_USE_PTSCOTCH
 #cmakedefine AKANTU_SCOTCH_NO_EXTERN
 
 #cmakedefine AKANTU_USE_MUMPS
+#cmakedefine AKANTU_USE_PETSC
 
 #cmakedefine AKANTU_USE_IOHELPER
 #cmakedefine AKANTU_USE_QVIEW
 #cmakedefine AKANTU_USE_BLACKDYNAMITE
 
 #cmakedefine AKANTU_USE_NLOPT
 #cmakedefine AKANTU_USE_CPPARRAY
 
 #cmakedefine AKANTU_USE_OBSOLETE_GETTIMEOFDAY
 
 #cmakedefine AKANTU_EXTRA_MATERIALS
 #cmakedefine AKANTU_DAMAGE_NON_LOCAL
 
 #cmakedefine AKANTU_STRUCTURAL_MECHANICS
 #cmakedefine AKANTU_HEAT_TRANSFER
 
 #cmakedefine AKANTU_COHESIVE_ELEMENT
 #cmakedefine AKANTU_PARALLEL_COHESIVE_ELEMENT
 
 #cmakedefine AKANTU_IGFEM
 
 // BOOST Section
 #cmakedefine AKANTU_BOOST_CHRONO
 #cmakedefine AKANTU_BOOST_SYSTEM
 
 // Experimental part
 #cmakedefine AKANTU_CORE_CXX11
 
 // Debug tools
 //#cmakedefine AKANTU_NDEBUG
 #cmakedefine AKANTU_DEBUG_TOOLS
 #cmakedefine READLINK_COMMAND @READLINK_COMMAND@
 #cmakedefine ADDR2LINE_COMMAND @ADDR2LINE_COMMAND@
 
 #define __aka_inline__ inline
 
 #endif /* __AKANTU_AKA_CONFIG_HH__ */
diff --git a/src/common/aka_error.cc b/src/common/aka_error.cc
index 52b816bf5..51e6661b8 100644
--- a/src/common/aka_error.cc
+++ b/src/common/aka_error.cc
@@ -1,362 +1,338 @@
 /**
  * @file   aka_error.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Sep 06 2010
  * @date last modification: Tue Jul 29 2014
  *
  * @brief  handling of errors
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_config.hh"
 #include "aka_error.hh"
 #include "aka_common.hh"
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <csignal>
 #include <execinfo.h>
 #include <cxxabi.h>
 #include <fstream>
 #include <iomanip>
 #include <cmath>
 #include <cstring>
 #include <map>
 #include <sys/wait.h>
 #include <sys/types.h>
 #include <unistd.h>
 
 #if defined(AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
 #  include <sys/time.h>
 #else
 #  include <time.h>
 #endif
 
 #ifdef AKANTU_USE_MPI
-#if defined(AKANTU_CORE_CXX11)
-#if defined(__INTEL_COMPILER)
-//#pragma warning ( disable : 383 )
-#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
-#elif (defined(__GNUC__) || defined(__GNUG__))
-#  define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-#  if GCC_VERSION > 40600
-#    pragma GCC diagnostic push
-#  endif
-#  pragma GCC diagnostic ignored "-Wliteral-suffix"
-#endif
-#endif
 #  include <mpi.h>
-#if defined(AKANTU_CORE_CXX11)
-#if defined(__INTEL_COMPILER)
-//#pragma warning ( disable : 383 )
-#elif defined (__clang__) // test clang to be sure that when we test for gnu it is only gnu
-#elif defined(__GNUG__)
-#  if GCC_VERSION > 40600
-#    pragma GCC diagnostic pop
-#  else
-#    pragma GCC diagnostic warning "-Wliteral-suffix"
-#  endif
-#endif
-#endif
 #endif
 
 #define __BEGIN_AKANTU_DEBUG__ namespace akantu { namespace debug {
 #define __END_AKANTU_DEBUG__ } }
 
 /* -------------------------------------------------------------------------- */
 
 __BEGIN_AKANTU_DEBUG__
 
 static void printBacktraceAndExit(int sig) {
   printBacktrace(sig);
   debugger.exit(-50);
 }
 
 /* ------------------------------------------------------------------------ */
 void initSignalHandler() {
   struct sigaction action;
 
   action.sa_handler = &printBacktraceAndExit;
   sigemptyset(&(action.sa_mask));
   action.sa_flags = SA_RESETHAND;
 
   sigaction(SIGSEGV, &action, NULL);
   sigaction(SIGABRT, &action, NULL);
 }
 
 /* ------------------------------------------------------------------------ */
 std::string demangle(const char *symbol) {
   int status;
   std::string result;
   char *demangled_name;
 
   if ((demangled_name = abi::__cxa_demangle(symbol, NULL, 0, &status)) != NULL) {
     result = demangled_name;
     free(demangled_name);
   } else {
     result = symbol;
   }
 
   return result;
 }
 
 /* ------------------------------------------------------------------------ */
 std::string exec(std::string cmd) {
   FILE *pipe = popen(cmd.c_str(), "r");
   if (!pipe) return "";
   char buffer[1024];
   std::string result = "";
   while (!feof(pipe)) {
     if (fgets(buffer, 128, pipe) != NULL)
       result += buffer;
   }
 
   result = result.substr(0, result.size() - 1);
   pclose(pipe);
   return result;
 }
 
 /* ------------------------------------------------------------------------ */
 void printBacktrace(__attribute__((unused)) int sig) {
   AKANTU_DEBUG_INFO("Caught  signal " << sig << "!");
 
 #if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
   std::string me = "";
   char buf[1024];
   /* The manpage says it won't null terminate.  Let's zero the buffer. */
   memset(buf, 0, sizeof(buf));
   /* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */
   if (readlink("/proc/self/exe", buf, sizeof(buf) - 1))
     me = std::string(buf);
 
   std::ifstream inmaps;
   inmaps.open("/proc/self/maps");
   std::map <std::string, size_t> addr_map;
   std::string line;
   while (inmaps.good()) {
     std::getline(inmaps, line);
     std::stringstream sstr(line);
 
     size_t first = line.find('-');
     std::stringstream sstra(line.substr(0, first));
     size_t addr; sstra >> std::hex >> addr;
 
     std::string lib;
     sstr >> lib;
     sstr >> lib;
     sstr >> lib;
     sstr >> lib;
     sstr >> lib;
     sstr >> lib;
     if (lib != "" && addr_map.find(lib) == addr_map.end()) {
       addr_map[lib] = addr;
     }
   }
 
   if (me != "") addr_map[me] = 0;
 #endif
 
   const size_t max_depth = 100;
   size_t stack_depth;
   void *stack_addrs[max_depth];
   char **stack_strings;
 
   size_t i;
 
   stack_depth = backtrace(stack_addrs, max_depth);
   stack_strings = backtrace_symbols(stack_addrs, stack_depth);
 
   std::cerr << "BACKTRACE :  " << stack_depth << " stack frames." << std::endl;
   size_t w = size_t(std::floor(log(double(stack_depth)) / std::log(10.)) + 1);
 
   /// -1 to remove the call to the printBacktrace function
   for (i = 1; i < stack_depth; i++) {
     std::cerr << std::dec << "  [" << std::setw(w) << i << "] ";
     std::string bt_line(stack_strings[i]);
     size_t first, second;
 
     if ((first = bt_line.find('(')) != std::string::npos && (second = bt_line.find('+')) != std::string::npos) {
       std::string location = bt_line.substr(0, first);
 #if defined(READLINK_COMMAND)
       location = exec(std::string(BOOST_PP_STRINGIZE(READLINK_COMMAND)) + std::string(" -f ") + location);
 #endif
       std::string call = demangle(bt_line.substr(first + 1, second - first - 1).c_str());
       size_t f = bt_line.find('[');
       size_t s = bt_line.find(']');
       std::string address = bt_line.substr(f + 1, s - f - 1);
       std::stringstream sstra(address);
       size_t addr; sstra >> std::hex >> addr;
 
       std::cerr << location << " [" << call << "]";
 
 #if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
       std::map <std::string, size_t>::iterator it = addr_map.find(location);
       if (it != addr_map.end()) {
 	std::stringstream syscom;
 	syscom << BOOST_PP_STRINGIZE(ADDR2LINE_COMMAND) << " 0x" << std::hex << (addr - it->second) << " -i -e " << location;
 	std::string line = exec(syscom.str());
 	std::cerr << " (" << line << ")" << std::endl;
       } else {
 #endif
 	std::cerr << " (0x" << std::hex << addr << ")" << std::endl;
 #if defined(READLINK_COMMAND) && defined(ADDR2LINE_COMMAND)
       }
 #endif
     } else {
       std::cerr << bt_line << std::endl;
     }
   }
 
   free(stack_strings);
 
   std::cerr << "END BACKTRACE" << std::endl;
 }
 
 /* ------------------------------------------------------------------------ */
 /* ------------------------------------------------------------------------ */
 Debugger::Debugger() {
   cout = &std::cerr;
   level = dblWarning;
   parallel_context = "";
   file_open = false;
   print_backtrace = false;
 }
 
 /* ------------------------------------------------------------------------ */
 Debugger::~Debugger() {
   if (file_open) {
     dynamic_cast <std::ofstream *>(cout)->close();
     delete cout;
   }
 }
 
 
 /* ------------------------------------------------------------------------ */
 void Debugger::exit(int status) {
   if (status != EXIT_SUCCESS && status != -50) {
 #ifndef AKANTU_NDEBUG
     int * a = NULL;
     *a = 1;
 #endif
     if(this->print_backtrace)
       akantu::debug::printBacktrace(15);
   }
 
 #ifdef AKANTU_USE_MPI
   if (status != EXIT_SUCCESS)
     MPI_Abort(MPI_COMM_WORLD, MPI_ERR_UNKNOWN);
 #endif
 
   std::exit(status); // not  called when compiled  with MPI  due to  MPI_Abort, but
   // MPI_Abort does not have the noreturn attribute
 }
 
 /*------------------------------------------------------------------------- */
 void Debugger::throwException(const std::string & info,
 			      const std::string & file,
 			      unsigned int line,
 			      __attribute__((unused)) bool silent,
 			      __attribute__((unused)) const std::string & location) const
   throw(akantu::debug::Exception) {
 
 #if !defined(AKANTU_NDEBUG)
   if (!silent) {
     printMessage("###", dblWarning, info + location);
   }
 #endif
 
   debug::Exception ex(info, file, line);
   throw ex;
 }
 
 /* ------------------------------------------------------------------------ */
 void Debugger::printMessage(const std::string & prefix,
 			    const DebugLevel &  level,
 			    const std::string & info) const {
   if (this->level >= level) {
 #if defined(AKANTU_USE_OBSOLETE_GETTIMEOFDAY)
     struct timeval time;
     gettimeofday(&time, NULL);
     double timestamp = time.tv_sec * 1e6 + time.tv_usec; /*in us*/
 #else
     struct timespec time;
     clock_gettime(CLOCK_REALTIME_COARSE, &time);
     double timestamp = time.tv_sec * 1e6 + time.tv_nsec * 1e-3; /*in us*/
 #endif
     *(cout) << parallel_context
 	    << "{" << (unsigned int)timestamp << "} "
 	    << prefix << " " << info
 	    << std::endl;
   }
 }
 
 /* ------------------------------------------------------------------------ */
 void Debugger::setDebugLevel(const DebugLevel & level) {
   this->level = level;
 }
 
 /* ------------------------------------------------------------------------ */
 const DebugLevel & Debugger::getDebugLevel() const {
   return level;
 }
 
 /* ------------------------------------------------------------------------ */
 void Debugger::setLogFile(const std::string & filename) {
   if (file_open) {
     dynamic_cast <std::ofstream *>(cout)->close();
     delete cout;
   }
 
   std::ofstream *fileout = new std::ofstream(filename.c_str());
   file_open = true;
   cout = fileout;
 }
 
 std::ostream & Debugger::getOutputStream() {
   return *cout;
 }
 
 /* ------------------------------------------------------------------------ */
 void Debugger::setParallelContext(int rank, int size) {
   std::stringstream sstr;
   UInt pad = std::ceil(std::log10(size));
   sstr << "<" << getpid() << ">[R" << std::setfill(' ') << std::right << std::setw(pad)
        << rank << "|S" << size << "] ";
   parallel_context = sstr.str();
 }
 
 void setDebugLevel(const DebugLevel & level) {
   debugger.setDebugLevel(level);
 }
 
 const DebugLevel &  getDebugLevel() {
   return debugger.getDebugLevel();
 }
 
 /* -------------------------------------------------------------------------- */
 void exit(int status) {
   debugger.exit(status);
 }
 
 
 __END_AKANTU_DEBUG__
diff --git a/src/common/aka_extern.cc b/src/common/aka_extern.cc
index 5dd4bd8ea..b2648381c 100644
--- a/src/common/aka_extern.cc
+++ b/src/common/aka_extern.cc
@@ -1,96 +1,101 @@
 /**
  * @file   aka_extern.cc
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Jun 14 2010
  * @date last modification: Thu Apr 03 2014
  *
  * @brief  initialisation of all global variables
  * to insure the order of creation
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "aka_array.hh"
 #include "aka_math.hh"
 #include "aka_random_generator.hh"
 #include "parser.hh"
 #include "cppargparse.hh"
+#include "static_solver.hh"
 
 /* -------------------------------------------------------------------------- */
 #include <iostream>
 #include <limits>
 /* -------------------------------------------------------------------------- */
 #if defined(AKANTU_DEBUG_TOOLS)
 #  include "aka_debug_tools.hh"
 #endif
 
 __BEGIN_AKANTU__
 
 /** \todo write function to get this
  *   values from the environment or a config file
  */
 
 /* -------------------------------------------------------------------------- */
 /* error.hpp variables                                                        */
 /* -------------------------------------------------------------------------- */
 namespace debug {
   /// standard output for debug messages
   std::ostream *_akantu_debug_cout = &std::cerr;
 
   /// standard output for normal messages
   std::ostream & _akantu_cout = std::cout;
 
   /// parallel context used in debug messages
   std::string _parallel_context = "";
 
   Debugger debugger;
 
 #if defined(AKANTU_DEBUG_TOOLS)
   DebugElementManager element_manager;
 #endif
 }
 
 /// Paser for commandline arguments
 ::cppargparse::ArgumentParser static_argparser;
 
 /// Parser containing the information parsed by the input file given to initFull
 Parser static_parser;
 
 bool Parser::parser_permissive = false;
 
 Real Math::tolerance = std::numeric_limits<Real>::epsilon();
 
 const UInt _all_dimensions = UInt(-1);
 
 const Array<UInt> empty_filter(0, 1, "empty_filter");
 
 template<> long int RandGenerator<Real>::_seed = 0;
 template<> long int RandGenerator<bool>::_seed = 0; // useless just defined due to a template instantiation
 template<> long int RandGenerator<UInt>::_seed = 0;
 template<> long int RandGenerator<Int>::_seed = 0;
 template<> long int Rand48Generator<Real>::_seed = 0;
 
+/* -------------------------------------------------------------------------- */
+UInt StaticSolver::nb_references = 0;
+StaticSolver * StaticSolver::static_solver = NULL;
+
 /* -------------------------------------------------------------------------- */
 
 __END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_damage/material_damage_iterative.cc b/src/model/solid_mechanics/materials/material_damage/material_damage_iterative.cc
index 22e45ab96..4aaa3aa70 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_damage_iterative.cc
+++ b/src/model/solid_mechanics/materials/material_damage/material_damage_iterative.cc
@@ -1,222 +1,226 @@
 /**
  * @file   material_damage_iterative.cc
  * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Fri Feb 14 14:54:44 2014
  *
  * @brief  Specialization of the class material damage to damage only one gauss
  * point at a time and propagate damage in a linear way. Max principal stress
  * criterion is used as a failure criterion.
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * You should  have received  a copy  of the GNU  Lesser General  Public License
  * along with Akantu. If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "material_damage_iterative.hh"
 #include "solid_mechanics_model.hh"
 
 __BEGIN_AKANTU__
 
 /* -------------------------------------------------------------------------- */
 template<UInt spatial_dimension>
 MaterialDamageIterative<spatial_dimension>::MaterialDamageIterative(SolidMechanicsModel & model,
-						  const ID & id)  :
+								    const ID & id)  :
   Material(model, id),
   MaterialDamage<spatial_dimension>(model, id),
   Sc("Sc", *this),
   equivalent_stress("equivalent_stress", *this),
   norm_max_equivalent_stress(0) {
   AKANTU_DEBUG_IN();
 
   this->registerParam("Sc",                  Sc,                  _pat_parsable, "critical stress threshold");
   this->registerParam("prescribed_dam",      prescribed_dam, 0.1, _pat_parsable | _pat_modifiable, "increase of damage in every step" );
   this->registerParam("dam_threshold",       dam_threshold,  0.8,  _pat_parsable | _pat_modifiable, "damage threshold at which damage damage will be set to 1" );
   this->registerParam("dam_tolerance",       dam_tolerance,  0.01,  _pat_parsable | _pat_modifiable, "damage tolerance to decide if quadrature point will be damageed" );
   this->registerParam("max_damage",       max_damage,  0.99999,  _pat_parsable | _pat_modifiable, "maximum damage value" );
 
 
   this->use_previous_stress          = true;
   this->use_previous_gradu           = true;
   this->Sc.initialize(1);
   this->equivalent_stress.initialize(1);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 template<UInt spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::computeNormalizedEquivalentStress(const Array<Real> & grad_u,
-										   ElementType el_type,
-										   GhostType ghost_type) {
+                                                                                   ElementType el_type,
+                                                                                   GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// Vector to store eigenvalues of current stress tensor
   Vector<Real> eigenvalues(spatial_dimension);
 
   Array<Real>::const_iterator<Real> Sc_it = Sc(el_type).begin();
   Array<Real>::iterator<Real> equivalent_stress_it = equivalent_stress(el_type).begin();
 
   Array<Real>::const_matrix_iterator grad_u_it = grad_u.begin(spatial_dimension,
-							      spatial_dimension);
+                                                              spatial_dimension);
   Array<Real>::const_matrix_iterator grad_u_end = grad_u.end(spatial_dimension,
-							     spatial_dimension);
+                                                             spatial_dimension);
   Real * dam = this->damage(el_type, ghost_type).storage();
   Matrix<Real> sigma(spatial_dimension, spatial_dimension);
   for(;grad_u_it != grad_u_end; ++ grad_u_it) {
     sigma.clear();
     MaterialElastic<spatial_dimension>::computeStressOnQuad(*grad_u_it, sigma, 0.);
     computeDamageAndStressOnQuad(sigma,*dam);
 
     /// compute eigenvalues
     sigma.eig(eigenvalues);
     /// find max eigenvalue and normalize by tensile strength
     *equivalent_stress_it = *(std::max_element(eigenvalues.storage(),
-					       eigenvalues.storage() + spatial_dimension)) / *(Sc_it);
+                                               eigenvalues.storage() + spatial_dimension)) / *(Sc_it);
     ++Sc_it;
     ++equivalent_stress_it;
     ++dam;
   }
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 template<UInt spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::computeAllStresses(GhostType ghost_type) {
   AKANTU_DEBUG_IN();
   /// reset normalized maximum equivalent stress
-  if(ghost_type==_not_ghost) 
+  if(ghost_type==_not_ghost)
     norm_max_equivalent_stress = 0;
-  
+ 
   MaterialDamage<spatial_dimension>::computeAllStresses(ghost_type);
 
   /// find global Gauss point with highest stress
   StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
   comm.allReduce(&norm_max_equivalent_stress, 1, _so_max);
 
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 template<UInt spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::findMaxNormalizedEquivalentStress(ElementType el_type,
-						      GhostType ghost_type) {
+										   GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
   if(ghost_type==_not_ghost) {
 
     // const Array<Real> & e_stress = equivalent_stress(el_type);
 
     // if (e_stress.begin() != e_stress.end() ) {
     //   Array<Real>::const_iterator<Real> equivalent_stress_it_max = std::max_element(e_stress.begin(),e_stress.end());
     //   /// check if max equivalent stress for this element type is greater than the current norm_max_eq_stress
     //   if (*equivalent_stress_it_max > norm_max_equivalent_stress) 
     // 	norm_max_equivalent_stress = *equivalent_stress_it_max;
     // }
     const Array<Real> & e_stress = equivalent_stress(el_type);
     Array<Real>::const_iterator<Real> equivalent_stress_it = e_stress.begin();
     Array<Real>::const_iterator<Real> equivalent_stress_end = e_stress.end();
     Array<Real> & dam = this->damage(el_type);
     Array<Real>::iterator<Real> dam_it = dam.begin();
 
+
     for (; equivalent_stress_it != equivalent_stress_end; ++equivalent_stress_it, ++dam_it ) {
       /// check if max equivalent stress for this element type is greater than the current norm_max_eq_stress and if the element is not already fully damaged
       if (*equivalent_stress_it > norm_max_equivalent_stress && *dam_it < max_damage) {
 	norm_max_equivalent_stress = *equivalent_stress_it;
       }
+
     }
 
 
 
   }
   AKANTU_DEBUG_OUT();
 }
 /* -------------------------------------------------------------------------- */
 template<UInt spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::computeStress(ElementType el_type,
-							       GhostType ghost_type) {
+                                                               GhostType ghost_type) {
   AKANTU_DEBUG_IN();
 
 
   MaterialDamage<spatial_dimension>::computeStress(el_type, ghost_type);
 
   Real * dam = this->damage(el_type, ghost_type).storage();
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_BEGIN(el_type, ghost_type);
 
   computeDamageAndStressOnQuad(sigma,*dam);
   ++dam;
 
   MATERIAL_STRESS_QUADRATURE_POINT_LOOP_END;
 
   computeNormalizedEquivalentStress(this->gradu(el_type, ghost_type), el_type, ghost_type);
   norm_max_equivalent_stress = 0;
   findMaxNormalizedEquivalentStress(el_type, ghost_type);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
 template<UInt spatial_dimension>
 UInt MaterialDamageIterative<spatial_dimension>::updateDamage() {
   UInt nb_damaged_elements = 0;
   AKANTU_DEBUG_ASSERT(prescribed_dam > 0.,
-			"Your prescribed damage must be greater than zero");
+		      "Your prescribed damage must be greater than zero");
 
   if (norm_max_equivalent_stress >= 1.) {
 
     AKANTU_DEBUG_IN();
     GhostType ghost_type = _not_ghost;;
 
     Mesh::type_iterator it = this->model->getFEEngine().getMesh().firstType(spatial_dimension, ghost_type);
     Mesh::type_iterator last_type = this->model->getFEEngine().getMesh().lastType(spatial_dimension, ghost_type);
 
     for(; it != last_type; ++it) {
       ElementType el_type = *it;
 
       const Array<Real> & e_stress = equivalent_stress(el_type);
       Array<Real>::const_iterator<Real> equivalent_stress_it = e_stress.begin();
       Array<Real>::const_iterator<Real> equivalent_stress_end = e_stress.end();
       Array<Real> & dam = this->damage(el_type);
       Array<Real>::iterator<Real> dam_it = dam.begin();
 
       for (; equivalent_stress_it != equivalent_stress_end; ++equivalent_stress_it, ++dam_it ) {
+
 	/// check if damage occurs
 	if (*equivalent_stress_it >= (1-dam_tolerance)*norm_max_equivalent_stress) {
 	  if (*dam_it < dam_threshold)
 	    *dam_it +=prescribed_dam;
 	  else *dam_it = max_damage;
 	  nb_damaged_elements += 1;
 	}
+
       }
     }
   }
   StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
   comm.allReduce(&nb_damaged_elements, 1, _so_sum);
   AKANTU_DEBUG_OUT();
   return nb_damaged_elements;
 }
 /* -------------------------------------------------------------------------- */
 template<UInt spatial_dimension>
 void MaterialDamageIterative<spatial_dimension>::updateEnergiesAfterDamage(ElementType el_type, GhostType ghost_type) {
   MaterialDamage<spatial_dimension>::updateEnergies(el_type, ghost_type);
 }
 
 /* -------------------------------------------------------------------------- */
 
 INSTANSIATE_MATERIAL(MaterialDamageIterative);
 
 
 __END_AKANTU__
diff --git a/src/model/solid_mechanics/materials/material_damage/material_damage_iterative.hh b/src/model/solid_mechanics/materials/material_damage/material_damage_iterative.hh
index 6b21c4ffd..de5922931 100644
--- a/src/model/solid_mechanics/materials/material_damage/material_damage_iterative.hh
+++ b/src/model/solid_mechanics/materials/material_damage/material_damage_iterative.hh
@@ -1,136 +1,136 @@
 /**
  * @file   material_damage_iterative.hh
  * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Fri Feb 14 14:34:37 2014
  *
  * @brief  Specialization of the class material damage to damage only one gauss 
  * point at a time and propagate damage in a linear way. Max principal stress 
  * criterion is used as a failure criterion.
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-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 "material_damage.hh"
 #include "material.hh"
 /* -------------------------------------------------------------------------- */
 
 #ifndef __AKANTU_MATERIAL_DAMAGE_ITERATIVE_HH__
 #define __AKANTU_MATERIAL_DAMAGE_ITERATIVE_HH__
 
 __BEGIN_AKANTU__
 
 /**
  * Material damage iterative
  *
  * parameters in the material files :
  *   - Sc  
  */
 template<UInt spatial_dimension>
 class MaterialDamageIterative : public MaterialDamage<spatial_dimension> {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
 
   MaterialDamageIterative(SolidMechanicsModel & model, const ID & id = "");
 
   virtual ~MaterialDamageIterative() {};
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
 
   ///  virtual void updateInternalParameters();
 
   virtual void computeAllStresses(GhostType ghost_type = _not_ghost);
 
   /// update internal field damage
   UInt updateDamage();
 
   /// update energies after damage has been updated
   virtual void updateEnergiesAfterDamage(ElementType el_type, GhostType ghost_typ);
   
   virtual void onBeginningSolveStep(const AnalysisMethod & method) { };
 
   virtual void onEndSolveStep(const AnalysisMethod & method) { };
 protected:
   /// constitutive law for all element of a type
   virtual void computeStress(ElementType el_type, GhostType ghost_type = _not_ghost);
 
   ///compute the equivalent stress on each Gauss point (i.e. the max prinicpal stress) and normalize it by the tensile strength
   void computeNormalizedEquivalentStress(const Array<Real> & grad_u,
-					 ElementType el_type, GhostType ghost_type = _not_ghost);
+                                         ElementType el_type, GhostType ghost_type = _not_ghost);
 
   /// find max normalized equivalent stress
   void findMaxNormalizedEquivalentStress(ElementType el_type, GhostType ghost_type = _not_ghost);
 
 
   inline void computeDamageAndStressOnQuad(Matrix<Real> & sigma,
-					   Real & dam);
+                                           Real & dam);
 
   /* ------------------------------------------------------------------------ */
   /* DataAccessor inherited members                                           */
   /* ------------------------------------------------------------------------ */
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// get max normalized equivalent stress
   AKANTU_GET_MACRO(NormMaxEquivalentStress, norm_max_equivalent_stress, Real);
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
 protected:
 
   /// resistance to damage
   RandomInternalField<Real> Sc;
 
   /// internal field to store equivalent stress on each Gauss point
   InternalField<Real> equivalent_stress;
 
   /// damage increment
   Real prescribed_dam;
 
   /// maximum equivalent stress
   Real norm_max_equivalent_stress;
 
   /// deviation from max stress at which Gauss point will still get damaged 
   Real dam_tolerance;
 
   /// define damage threshold at which damage will be set to 1 
   Real dam_threshold; 
 
   /// maximum damage value
   Real max_damage;
 };
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #include "material_damage_iterative_inline_impl.cc"
 
 __END_AKANTU__
 
 #endif /* __AKANTU_MATERIAL_DAMAGE_ITERATIVE_HH__ */
diff --git a/src/solver/petsc_matrix.cc b/src/solver/petsc_matrix.cc
index 5ad256638..e40de7b40 100644
--- a/src/solver/petsc_matrix.cc
+++ b/src/solver/petsc_matrix.cc
@@ -1,717 +1,509 @@
 /**
  * @file   petsc_matrix.cc
  * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Mon Jul 21 17:40:41 2014
  *
  * @brief  Implementation of PETSc matrix 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/>.
  *
  */
 
 /* -------------------------------------------------------------------------- */
 #include "petsc_matrix.hh"
+#include "static_communicator.hh"
+#include "static_communicator_mpi.hh"
+#include "mpi_type_wrapper.hh"
+#include "dof_synchronizer.hh"
 /* -------------------------------------------------------------------------- */
+#include <cstring>
+#include <mpi.h>
 #include <petscmat.h>
+#include <petscao.h>
+#include <petscis.h>
+#include <petscsys.h>  
+
 
 __BEGIN_AKANTU__
 
+struct PETScWrapper {
+  Mat mat;
+  AO ao;
+  ISLocalToGlobalMapping mapping;
+  /// pointer to the MPI communicator for PETSc commands
+  MPI_Comm communicator;
+};
+
 /* -------------------------------------------------------------------------- */
-PetscMatrix::PetscMatrix(UInt size,
-			   const SparseMatrixType & sparse_matrix_type,
-			   UInt nb_degree_of_freedom,
-			   const ID & id,
-			   const MemoryID & memory_id) :
-  PetscMatrix(size, sparse_matrix_type, nb_degree_of_freedom, id, memory_id) {
+PETScMatrix::PETScMatrix(UInt size,
+			 const SparseMatrixType & sparse_matrix_type,
+			 const ID & id,
+			 const MemoryID & memory_id) :
+  SparseMatrix(size, sparse_matrix_type, id, memory_id), 
+  petsc_wrapper(new PETScWrapper), d_nnz(0,1,"dnnz"), o_nnz(0,1,"onnz") {
   AKANTU_DEBUG_IN();
-
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
-  nb_proc = comm.getNbProc();
-
-  UInt nb_local_nodes = model.getMesh().getNbNodes();
-
-  MatCreate(&comm, mat);
-
-  MatSetSizes(mat, nb_degree_of_freedom*nb_local_nodes, nb_degree_of_freedom*nb_local_nodes, size, size);
+  
+  this->init();
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-PetscMatrix::PetscMatrix(const PetscMatrix & matrix,
+PETScMatrix::PETScMatrix(const SparseMatrix & matrix,
 			   const ID & id,
 			   const MemoryID & memory_id) :
-  PetscMatrix(matrix, id, memory_id) {
+  SparseMatrix(matrix, id, memory_id),
+  petsc_wrapper(new PETScWrapper), d_nnz(0,1,"dnnz"), o_nnz(0,1,"onnz") {
   AKANTU_DEBUG_IN();
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
-  nb_proc = comm.getNbProc();
+  this->init();
 
-  UInt nb_local_nodes = model.getMesh().getNbNodes();
-  MatCreate(&comm, &mat);
-  MatSetSizes(mat, nb_degree_of_freedom*nb_local_nodes, nb_degree_of_freedom*nb_local_nodes, size, size);
+  AKANTU_DEBUG_OUT();
+}
+
+/* -------------------------------------------------------------------------- */
+PETScMatrix::~PETScMatrix() {
+  AKANTU_DEBUG_IN();
+
+  PetscErrorCode ierr;
 
+  ierr = MatDestroy(&(this->petsc_wrapper->mat)); CHKERRXX(ierr);
+  delete petsc_wrapper;
 
   AKANTU_DEBUG_OUT();
 }
 
-
 /* -------------------------------------------------------------------------- */
-PetscMatrix::~PetscMatrix() {
+void PETScMatrix::init() {
   AKANTU_DEBUG_IN();
 
-  MatDestroy(&mat);
+#if defined(AKANTU_USE_MPI)
+    StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
+    const StaticCommunicatorMPI & mpi_st_comm =
+      dynamic_cast<const StaticCommunicatorMPI &>(comm.getRealStaticCommunicator());
+    this->petsc_wrapper->communicator = mpi_st_comm.getMPITypeWrapper().getMPICommunicator();
+#else
+    this->petsc_wrapper->communicator = PETSC_COMM_SELF;
+#endif
+ 
+  PetscErrorCode ierr;
+
+  ierr = MatCreate(this->petsc_wrapper->communicator, &(this->petsc_wrapper->mat)); CHKERRXX(ierr);
+  /// set matrix type
+  ierr = MatSetType(this->petsc_wrapper->mat,  MATAIJ); CHKERRXX(ierr);
+
+
+  if (this->sparse_matrix_type==_symmetric)
+    /// set flag for symmetry to enable ICC/Cholesky preconditioner
+    ierr = MatSetOption(this->petsc_wrapper->mat, MAT_SYMMETRIC, PETSC_TRUE); CHKERRXX(ierr);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-PetscMatrix::createAkantuToPetscMap(Mesh & mesh) {
+void PETScMatrix::resize(const DOFSynchronizer & dof_synchronizer) {
   AKANTU_DEBUG_IN();
 
-  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator();
-  Int nb_proc = comm.getNbProc();
-  Int rank = comm.whoAmI();
+  PetscErrorCode ierr;
 
   this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
 
-  //initialize vector to store the number of local and master nodes for each processor
-  Vector<UInt> master_local_ndofs_per_proc(nb_proc);
+  /// find the number of dofs corresponding to master or local nodes
+  UInt nb_dofs = dof_synchronizer.getNbDOFs();
+  UInt nb_local_master_dofs = 0;
 
-  //find the number of dofs corresponding to master or local nodes and store their akantu global dof number
-  Real nb_dofs = dof_sychronizer.getNbDOFs();
-  Real nb_local_master_dofs = 0;
+  /// create array to store the global equation number of all local and master dofs
+  Array<Int> local_master_eq_nbs(nb_dofs);
+  Array<Int>::scalar_iterator it_eq_nb = local_master_eq_nbs.begin();
 
-  Array<Real> local_master_dofs(nb_dofs);
-  Array<Real>::scalar_iterator it_dof = local_master_dofs.begin();
+  Array<Int> dof_types = dof_synchronizer.getDOFTypes();
+  Array<Int>::scalar_iterator it_dof_type = dof_types.begin();
 
-  Array<Real> dof_types = dof_sychronizer.getDOFTypes();
-  Array<Real>::scalar_iterator it_dof_type = dof_types.begin();
+  /// get the pointer to the gloabl equation number array
+  Int * eq_nb_val = dof_synchronizer.getGlobalDOFEquationNumbers().storage();
 
-  for (UInt i = 0; i <nb_dofs; ++i; ++it_dof_type) {
+  for (UInt i = 0; i <nb_dofs; ++i, ++it_dof_type) {
     if (*it_dof_type == -2 || *it_dof_type == -1 ) {
-      *it_dof = dof_sychronizer.dof_global_ids(i);
-      ++it_dof;
+      /// get for the local dof the global equation number
+      *it_eq_nb = eq_nb_val[i];
+      ++it_eq_nb;
       ++nb_local_master_dofs;
     }
   }
 
-  local_master_dofs.resize(nb_local_master_dofs);
-
-  // store the nb of master and local dofs on each processor
-  master_local_ndofs_per_proc(rank) = nb_local_master_dofs;
-  
-  //exchange the information among all processors
-  comm.allGather(local_master_ndofs_per_proc.storage(), 1);
-
-  //each processor creates a map for his akantu global dofs to the corresponding petsc global dofs
-  UInt petsc_start_index = 0;
+  local_master_eq_nbs.resize(nb_local_master_dofs);
 
-  for (UInt i = 0; i < rank; ++i) {
-    petsc_start_index +=  local_master_ndofs_per_proc(rank);
-  }
+  /// set the local size
+  this->local_size = nb_local_master_dofs;
 
-  Int * local_master_dofs_ptr = local_master_dofs.storage();
-  AOCreateBasic(&comm, nb_local_master_dofs,index_akantu, index_petsc, &ao);
+  /// resize PETSc matrix
+#if defined(AKANTU_USE_MPI)
+  ierr = MatSetSizes(this->petsc_wrapper->mat, this->size, this->size, this->local_size, this->local_size); CHKERRXX(ierr);
+#else
+  ierr =  MatSetSizes(this->petsc_wrapper->mat, this->local_size, this->local_size); CHKERRXX(ierr);
+#endif
+  
 
+  /// create mapping from akantu global numbering to petsc global numbering
+  this->createGlobalAkantuToPETScMap(local_master_eq_nbs.storage());
+ 
   AKANTU_DEBUG_OUT();
 }
+
 /* -------------------------------------------------------------------------- */
-void PetscMatrix::buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer) {
+void PETScMatrix::createGlobalAkantuToPETScMap(Int* local_master_eq_nbs_ptr) {
   AKANTU_DEBUG_IN();
 
-  // if(irn_jcn_to_k) delete irn_jcn_to_k;
-  // irn_jcn_to_k = new std::map<std::pair<UInt, UInt>, UInt>;
-  clearProfile();
-
-  this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
+  PetscErrorCode ierr;
+ 
+  StaticCommunicator & comm = StaticCommunicator::getStaticCommunicator(); 
+  UInt rank = comm.whoAmI();
 
-  coordinate_list_map::iterator irn_jcn_k_it;
+  //initialize vector to store the number of local and master nodes that are assigned to each processor
+  Vector<UInt> master_local_ndofs_per_proc(nb_proc);
 
-  Int * eq_nb_val = dof_synchronizer.getGlobalDOFEquationNumbers().storage();
+  /// store the nb of master and local dofs on each processor
+  master_local_ndofs_per_proc(rank) = this->local_size;
+  
 
-  Mesh::type_iterator it  = mesh.firstType(mesh.getSpatialDimension(), _not_ghost, _ek_not_defined);
-  Mesh::type_iterator end = mesh.lastType (mesh.getSpatialDimension(), _not_ghost, _ek_not_defined);
-  for(; it != end; ++it) {
-    UInt nb_element = mesh.getNbElement(*it);
-    UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
-    UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
 
-    UInt * conn_val = mesh.getConnectivity(*it, _not_ghost).storage();
-    Int * local_eq_nb_val = new Int[nb_degree_of_freedom * nb_nodes_per_element];
+  /// exchange the information among all processors
+  comm.allGather(master_local_ndofs_per_proc.storage(), 1);
 
+  /// each processor creates a map for his akantu global dofs to the corresponding petsc global dofs
 
-    for (UInt e = 0; e < nb_element; ++e) {
-      Int * tmp_local_eq_nb_val = local_eq_nb_val;
-      for (UInt i = 0; i < nb_nodes_per_element; ++i) {
-	UInt n = conn_val[i];
-	for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
-	  *tmp_local_eq_nb_val++ = eq_nb_val[n * nb_degree_of_freedom + d];
-	}
-	// memcpy(tmp_local_eq_nb_val, eq_nb_val + n * nb_degree_of_freedom, nb_degree_of_freedom * sizeof(Int));
-	// tmp_local_eq_nb_val += nb_degree_of_freedom;
-      }
-
-      for (UInt i = 0; i < size_mat; ++i) {
-	UInt c_irn = local_eq_nb_val[i];
-	if(c_irn < size) {
-	  UInt j_start = (sparse_matrix_type == _symmetric) ? i : 0;
-	  for (UInt j = j_start; j < size_mat; ++j) {
-	    UInt c_jcn = local_eq_nb_val[j];
-	    if(c_jcn < size) {
-	      MatSetValue(this->mat,1,c_irn, 1, c_jcn, INSERT_VALUES);
-
-	      if (irn_jcn_k_it == irn_jcn_k.end()) {
-		irn_jcn_k[irn_jcn] = nb_non_zero;
-		irn.push_back(c_irn + 1);
-		jcn.push_back(c_jcn + 1);
-		nb_non_zero++;
-	      }
-	    }
-	  }
-	}
-      }
-      conn_val += nb_nodes_per_element;
-    }
+  /// determine the PETSc-index for the first dof on each processor
+  UInt petsc_start_index = 0;
 
-    delete [] local_eq_nb_val;
+  for (UInt i = 0; i < rank; ++i) {
+    petsc_start_index +=  master_local_ndofs_per_proc(rank);
   }
 
-  /// for pbc @todo correct it for parallel
-  if(StaticCommunicator::getStaticCommunicator().getNbProc() == 1) {
-    for (UInt i = 0; i < size; ++i) {
-      KeyCOO irn_jcn = key(i, i);
-      irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
-      if(irn_jcn_k_it == irn_jcn_k.end()) {
-        irn_jcn_k[irn_jcn] = nb_non_zero;
-        irn.push_back(i + 1);
-        jcn.push_back(i + 1);
-        nb_non_zero++;
-      }
-    }
+  /// create array for petsc ordering
+  Array<Int> petsc_dofs(this->local_size);
+  Array<Int>::scalar_iterator it_petsc_dofs = petsc_dofs.begin();
+
+  for (UInt i = petsc_start_index; i < petsc_start_index + this->local_size; ++i, ++it_petsc_dofs) {
+    *it_petsc_dofs = i; 
   }
 
-  a.resize(nb_non_zero);
+  ierr = AOCreateBasic(this->petsc_wrapper->communicator, this->local_size, local_master_eq_nbs_ptr, petsc_dofs.storage(), &(this->petsc_wrapper->ao)); CHKERRXX(ierr);
 
   AKANTU_DEBUG_OUT();
 }
 
 /* -------------------------------------------------------------------------- */
-void PetscMatrix::applyBoundaryNormal(Array<bool> & boundary_normal, Array<Real> & EulerAngles, Array<Real> & rhs, const Array<Real> & matrix, Array<Real> & rhs_rotated) {
-    AKANTU_DEBUG_IN();
-
-
-    const UInt dim = nb_degree_of_freedom;
-    const UInt nb_nodes = boundary_normal.getSize();
-    Matrix<Real> Ti(dim, dim);
-    Matrix<Real> Tj(dim, dim);
-    Matrix<Real> small_matrix(dim, dim);
-    Matrix<Real> Ti_small_matrix(dim, dim);
-    Matrix<Real> Ti_small_matrix_Tj(dim, dim);
-    Matrix<Real> small_rhs(dim, 1);
-    Matrix<Real> Ti_small_rhs(dim, 1);
-    //Transformation matrix based on euler angles X_1Y_2Z_3
-
-    const DOFSynchronizer::GlobalEquationNumberMap & local_eq_num_to_global = dof_synchronizer->getGlobalEquationNumberToLocal();
-
-    Int * irn_val = irn.storage();
-    Int * jcn_val = jcn.storage();
-    Int * eq_nb_val = dof_synchronizer->getGlobalDOFEquationNumbers().storage();
-    Int * eq_nb_rhs_val = dof_synchronizer->getLocalDOFEquationNumbers().storage();
-    
-    Array<bool> * nodes_rotated = new Array<bool > (nb_nodes, dim, "nodes_rotated");
-    nodes_rotated->clear();
-    
-    Array<Int> * local_eq_nb_val_node_i = new Array<Int > (1, nb_degree_of_freedom, "local_eq_nb_val_node_i");
-    local_eq_nb_val_node_i->clear();
-    Array<Int> * local_eq_nb_val_node_j = new Array<Int > (1, nb_degree_of_freedom, "local_eq_nb_val_node_j");
-    local_eq_nb_val_node_j->clear();
-
-    for (UInt i = 0; i < nb_non_zero; ++i) {
-        UInt ni = local_eq_num_to_global.find(*irn_val - 1)->second;
-        UInt node_i = (ni - ni % nb_degree_of_freedom) / nb_degree_of_freedom;
-        UInt nj = local_eq_num_to_global.find(*jcn_val - 1)->second;
-        UInt node_j = (nj - nj % nb_degree_of_freedom) / nb_degree_of_freedom;
-        bool constrain_ij = false;
-        for (UInt j = 0; j < dim; j++){
-            if ( (boundary_normal(node_i, j) || boundary_normal(node_j, j)) ) {
-                constrain_ij = true;
-                break;
-            }
-        }
-        
-        if(constrain_ij){
-            if(dim==2){
-                Real Theta=EulerAngles(node_i,0);
-                Ti(0,0)=cos(Theta);
-                Ti(0,1)=-sin(Theta);
-                Ti(1,1)=cos(Theta);
-                Ti(1,0)=sin(Theta);
-                
-                Theta=EulerAngles(node_j,0);
-                Tj(0,0)=cos(Theta);
-                Tj(0,1)=-sin(Theta);
-                Tj(1,1)=cos(Theta);
-                Tj(1,0)=sin(Theta);
-            }
-            else if(dim==3){
-                Real Theta_x=EulerAngles(node_i,0);
-                Real Theta_y=EulerAngles(node_i,1);
-                Real Theta_z=EulerAngles(node_i,2);
-                
-                Ti(0,0)=cos(Theta_y)*cos(Theta_z);
-                Ti(0,1)=-cos(Theta_y)*sin(Theta_z);
-                Ti(0,2)=sin(Theta_y);
-                Ti(1,0)=cos(Theta_x)*sin(Theta_z)+cos(Theta_z)*sin(Theta_x)*sin(Theta_y);
-                Ti(1,1)=cos(Theta_x)*cos(Theta_z)-sin(Theta_x)*sin(Theta_y)*sin(Theta_z);
-                Ti(1,2)=-cos(Theta_y)*sin(Theta_x);
-                Ti(2,0)=sin(Theta_x)*sin(Theta_z)-cos(Theta_x)*cos(Theta_z)*sin(Theta_y);
-                Ti(2,1)=cos(Theta_z)*sin(Theta_x)+cos(Theta_x)*sin(Theta_y)*sin(Theta_z);
-                Ti(2,2)=cos(Theta_x)*cos(Theta_y);
-                
-                Theta_x=EulerAngles(node_j,0);
-                Theta_y=EulerAngles(node_j,1);
-                Theta_z=EulerAngles(node_j,2);
-                
-                Tj(0,0)=cos(Theta_y)*cos(Theta_z);
-                Tj(0,1)=-cos(Theta_y)*sin(Theta_z);
-                Tj(0,2)=sin(Theta_y);
-                Tj(1,0)=cos(Theta_x)*sin(Theta_z)+cos(Theta_z)*sin(Theta_x)*sin(Theta_y);
-                Tj(1,1)=cos(Theta_x)*cos(Theta_z)-sin(Theta_x)*sin(Theta_y)*sin(Theta_z);
-                Tj(1,2)=-cos(Theta_y)*sin(Theta_x);
-                Tj(2,0)=sin(Theta_x)*sin(Theta_z)-cos(Theta_x)*cos(Theta_z)*sin(Theta_y);
-                Tj(2,1)=cos(Theta_z)*sin(Theta_x)+cos(Theta_x)*sin(Theta_y)*sin(Theta_z);
-                Tj(2,2)=cos(Theta_x)*cos(Theta_y);
-            }
-            for (UInt j = 0; j < nb_degree_of_freedom; ++j){
-                local_eq_nb_val_node_i->storage()[j] = eq_nb_val[node_i * nb_degree_of_freedom + j];
-                local_eq_nb_val_node_j->storage()[j] = eq_nb_val[node_j * nb_degree_of_freedom + j];
-            }
-            for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
-                for (UInt k = 0; k < nb_degree_of_freedom; ++k) {
-                    KeyCOO jcn_irn = key(local_eq_nb_val_node_i->storage()[j], local_eq_nb_val_node_j->storage()[k]);
-                    coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
-                    small_matrix(j, k) = matrix.storage()[irn_jcn_k_it->second];
-                }
-                small_rhs(j,0)=rhs.storage()[eq_nb_rhs_val[node_i*dim+j]];
-            }
-            
-            Ti_small_matrix.mul < false, false > (Ti, small_matrix);
-            Ti_small_matrix_Tj.mul < false, true> (Ti_small_matrix, Tj);
-            Ti_small_rhs.mul<false, false>(Ti, small_rhs);
-            
-            /*for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
-                for (UInt k = 0; k < nb_degree_of_freedom; ++k) {
-                    KeyCOO jcn_irn = key(local_eq_nb_val_node_i->storage()[j], local_eq_nb_val_node_j->storage()[k]);
-                    coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
-                    a.storage()[irn_jcn_k_it->second] = T_small_matrix_T(j,k);
-                }
-                if(node_constrain==node_i && !( nodes_rotated->storage()[node_i]))
-                    rhs.storage()[eq_nb_rhs_val[node_i*dim+j]]=T_small_rhs(j,0);
-            }*/
-            KeyCOO jcn_irn = key(ni, nj);
-            coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
-            a.storage()[irn_jcn_k_it->second] = Ti_small_matrix_Tj(ni % nb_degree_of_freedom, nj % nb_degree_of_freedom);
-            //this->saveMatrix("stiffness_partial.out");
-            if (!(nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]])) {
-                rhs_rotated.storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = Ti_small_rhs(ni % nb_degree_of_freedom, 0);
-                nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = true;
-            }
-        }
-        else{
-            if (!(nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]])) {
-                rhs_rotated.storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = rhs.storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]];
-                nodes_rotated->storage()[eq_nb_rhs_val[node_i * dim + ni % nb_degree_of_freedom]] = true;
-            }
-        }
-        irn_val++;
-        jcn_val++;
-    }
+// void PETScMatrix::createLocalAkantuToPETScMap(const DOFSynchronizer & dof_synchronizer) {
+//   AKANTU_DEBUG_IN();
 
-    delete local_eq_nb_val_node_i;
-    delete local_eq_nb_val_node_j;
-    delete nodes_rotated;
-    this->saveMatrix("stiffness_rotated.out");
-    applyBoundary(boundary_normal);
-
-    /*Real norm = 0;
-    UInt n_zeros = 0;
-    for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
-        norm += Normal.storage()[j] * Normal.storage()[j];
-        if (std::abs(Normal.storage()[j]) < Math::getTolerance())
-            n_zeros++;
-    }
-    norm = sqrt(norm);
-    AKANTU_DEBUG_ASSERT(norm > Math::getTolerance(), "The normal is not right");
-    for (UInt j = 0; j < nb_degree_of_freedom; ++j)
-        Normal.storage()[j] /= norm;
-    
-    if (n_zeros == nb_degree_of_freedom - 1) {
-        UInt nb_nodes = boundary_normal.getSize();
-        for (UInt i = 0; i < nb_nodes; ++i) {
-            if (boundary_normal(i, 0))
-                for (UInt j = 0; j < nb_degree_of_freedom; ++j)
-                    boundary(i, j) += Normal(0, j);
-        }
-    } else {
-
-        const DOFSynchronizer::GlobalEquationNumberMap & local_eq_num_to_global = dof_synchronizer->getGlobalEquationNumberToLocal();
-
-        Int * irn_val = irn.storage();
-        Int * eq_nb_val = dof_synchronizer->getGlobalDOFEquationNumbers().storage();
-        Array<Int> * local_eq_nb_val = new Array<Int > (1, nb_degree_of_freedom, "local_eq_nb_val");
-        local_eq_nb_val->clear();
-        UInt nb_nodes = boundary_normal.getSize();
-        Array<bool> * node_set = new Array<bool > (nb_nodes, 1, "node_set");
-        node_set->clear();
-
-        for (UInt i = 0; i < nb_non_zero; ++i) {
-            UInt ni = local_eq_num_to_global.find(*irn_val - 1)->second;
-            UInt node_i = (ni - ni % nb_degree_of_freedom) / nb_degree_of_freedom;
-            if (boundary_normal.storage()[ni]) {
-                if ((!number.storage()[ni]) && (!node_set->storage()[node_i])) {
-                    UInt normal_component_i = ni % nb_degree_of_freedom; //DOF of node node_i to be removed
-                    if (std::abs(Normal.storage()[normal_component_i]) > Math::getTolerance()) {
-                        for (UInt j = 0; j < nb_degree_of_freedom; ++j)
-                            local_eq_nb_val->storage()[j] = eq_nb_val[node_i * nb_degree_of_freedom + j];
-
-                        UInt DOF_remove = local_eq_nb_val->storage()[normal_component_i];
-                        KeyCOO jcn_irn = key(DOF_remove, DOF_remove);
-                        coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
-
-                        Real aii = a.storage()[irn_jcn_k_it->second];
-                        Real normal_constant = (1 - aii) / (Normal.storage()[normal_component_i] * Normal.storage()[normal_component_i]);
-
-                        for (UInt j = 0; j < nb_degree_of_freedom; ++j) {
-                            UInt line_j = local_eq_nb_val->storage()[j];
-                            for (UInt k = 0; k < nb_degree_of_freedom; ++k) {
-                                UInt column_k = local_eq_nb_val->storage()[k];
-                                jcn_irn = key(line_j, column_k);
-                                if ((line_j == column_k) && (line_j == DOF_remove))
-                                    a.storage()[irn_jcn_k_it->second] = 1;
-                                else
-                                    a.storage()[irn_jcn_k_it->second] += Normal.storage()[j] * Normal.storage()[k] * normal_constant;
-                            }
-                        }
-
-                        number.storage()[ni]++;
-                        node_set->storage()[node_i] = false;
-                    }
-                }
-            }
-            irn_val++;
-        }
-
-        delete local_eq_nb_val;
-        delete node_set;
-    }*/
-    AKANTU_DEBUG_OUT();
-}
+//   AKANTU_DEBUG_ASSERT(this->petsc_wrapper->ao != NULL,
+//                       "You should first create a mapping from the global"
+// 		      << " Akantu numbering to the global PETSc numbering");
 
-/* -------------------------------------------------------------------------- */
-void PetscMatrix::applyBoundary(const Array<bool> & boundary, Real block_val) {
-  AKANTU_DEBUG_IN();
+//   this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
 
-  const DOFSynchronizer::GlobalEquationNumberMap & local_eq_num_to_global = dof_synchronizer->getGlobalEquationNumberToLocal();
-  Int * irn_val = irn.storage();
-  Int * jcn_val = jcn.storage();
-  Real * a_val   = a.storage();
-
-  for (UInt i = 0; i < nb_non_zero; ++i) {
-    UInt ni = local_eq_num_to_global.find(*irn_val - 1)->second;
-    UInt nj = local_eq_num_to_global.find(*jcn_val - 1)->second;
-    if(boundary.storage()[ni]  || boundary.storage()[nj]) {
-      if (*irn_val != *jcn_val) {
-        *a_val = 0;
-      } else {
-        if(dof_synchronizer->getDOFTypes()(ni) >= 0) {
-          *a_val = 0;
-        } else {
-          *a_val = block_val;
-        }
-      }
-    }
-    irn_val++; jcn_val++; a_val++;
-  }
+//   /// get the number of dofs
+//   Int nb_dofs = dof_synchronizer.getNbDOFs();
 
-  AKANTU_DEBUG_OUT();
-}
+//   /// get the global equation numbers for each node
+//   Array<Int> global_dof_equation_numbers = dof_synchronizer.getGlobalDOFEquationNumbers();
+
+//   /// map the global dof equation numbers to the corresponding PETSc ordering
+//   AOApplicationToPETSc(this->petsc_wrapper->ao, nb_dofs,
+// 		       global_dof_equation_numbers.storage());
+
+//   /// create the mapping from the local Akantu ordering to the global PETSc ordering
+//   ISLocalToGlobalMappingCreate(this->petsc_wrapper->communicator,
+// 			       1, nb_dofs, global_dof_equation_numbers.storage(),
+// 			       PETSC_COPY_VALUES, mapping);
+
+//   AKANTU_DEBUG_OUT();
+// }
 
 /* -------------------------------------------------------------------------- */
-void PetscMatrix::removeBoundary(const Array<bool> & boundary) {
+void PETScMatrix::buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom) {
   AKANTU_DEBUG_IN();
 
-  if(irn_save) delete irn_save;
-  if(jcn_save) delete jcn_save;
+  //clearProfile();
 
-  irn_save = new Array<Int>(irn, true);
-  jcn_save = new Array<Int>(jcn, true);
+  PetscErrorCode ierr;
 
-  UInt n = boundary.getSize()*boundary.getNbComponent();
+  /// resize arrays to store the number of nonzeros in each row
+  this->d_nnz.resize(this->local_size);
+  this->o_nnz.resize(this->local_size);
 
-  UInt * perm = new UInt[n];
+  /// set arrays to zero everywhere
+  this->d_nnz.set(0);
+  this->o_nnz.set(0); 
 
-  size_save = size;
-  size = 0;
-  for (UInt i = 0; i < n; ++i) {
-    if(!boundary.storage()[i]) {
-      perm[i] = size;
-      //      std::cout <<  "perm["<< i <<"] = " << size << std::endl;
-      size++;
-    }
-  }
+  this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
 
-  for (UInt i = 0; i < nb_non_zero;) {
-    if(boundary.storage()[irn(i) - 1] || boundary.storage()[jcn(i) - 1]) {
-      irn.erase(i);
-      jcn.erase(i);
-      a.erase(i);
-      nb_non_zero--;
-    } else {
-      irn(i) = perm[irn(i) - 1] + 1;
-      jcn(i) = perm[jcn(i) - 1] + 1;
-      i++;
-    }
-  }
 
-  delete [] perm;
+  /// get the types for each local dof
+  const Array<Int> & dof_types = dof_synchronizer.getDOFTypes();
+  Int* dof_type_ptr = dof_types.storage();
+  // if(irn_jcn_to_k) delete irn_jcn_to_k;
+  // irn_jcn_to_k = new std::map<std::pair<UInt, UInt>, UInt>;
+  
 
-  AKANTU_DEBUG_OUT();
-}
+  this->dof_synchronizer = &const_cast<DOFSynchronizer &>(dof_synchronizer);
 
-/* -------------------------------------------------------------------------- */
-void PetscMatrix::restoreProfile() {
-  AKANTU_DEBUG_IN();
+  coordinate_list_map::iterator irn_jcn_k_it;
 
-  irn.resize(irn_save->getSize());
-  jcn.resize(jcn_save->getSize());
+  Int * eq_nb_val = dof_synchronizer.getGlobalDOFEquationNumbers().storage();
 
-  nb_non_zero = irn.getSize();
-  a.resize(nb_non_zero);
-  size = size_save;
+  /// Loop over all the ghost types
+  for (ghost_type_t::iterator gt = ghost_type_t::begin(); gt != ghost_type_t::end(); ++gt) {
+    const GhostType & ghost_type = *gt;
+    /// Loop over all element types 
+    Mesh::type_iterator it  = mesh.firstType(mesh.getSpatialDimension(), ghost_type, _ek_not_defined);
+    Mesh::type_iterator end = mesh.lastType (mesh.getSpatialDimension(), ghost_type, _ek_not_defined);
 
-  memcpy(irn.storage(), irn_save->storage(), irn.getSize()*sizeof(Int));
-  memcpy(jcn.storage(), jcn_save->storage(), jcn.getSize()*sizeof(Int));
+    for(; it != end; ++it) {
+      UInt nb_element = mesh.getNbElement(*it);
+      UInt nb_nodes_per_element = Mesh::getNbNodesPerElement(*it);
+      UInt size_mat = nb_nodes_per_element * nb_degree_of_freedom;
 
-  delete irn_save; irn_save = NULL;
-  delete jcn_save; jcn_save = NULL;
+      UInt * conn_val = mesh.getConnectivity(*it, _not_ghost).storage();
+      Int * global_eq_nb_val = new Int[nb_degree_of_freedom * nb_nodes_per_element];
+      Int * local_eq_nb_val = new Int[nb_degree_of_freedom * nb_nodes_per_element];
 
-  AKANTU_DEBUG_OUT();
-}
 
-/* -------------------------------------------------------------------------- */
-void PetscMatrix::saveProfile(const std::string & filename) const {
-  AKANTU_DEBUG_IN();
+      for (UInt e = 0; e < nb_element; ++e) {
+	Int * tmp_global_eq_nb_val = global_eq_nb_val;
+	Int * tmp_local_eq_nb_val = local_eq_nb_val;
 
-  std::ofstream outfile;
-  outfile.open(filename.c_str());
+	for (UInt i = 0; i < nb_nodes_per_element; ++i) {
+	  UInt n = conn_val[i];
+	  for (UInt d = 0; d < nb_degree_of_freedom; ++d) {
+	    *tmp_global_eq_nb_val++ = eq_nb_val[n * nb_degree_of_freedom + d];
+	    *tmp_local_eq_nb_val++ = n * nb_degree_of_freedom + d;
+	  }
+	  // memcpy(tmp_global_eq_nb_val, eq_nb_val + n * nb_degree_of_freedom, nb_degree_of_freedom * sizeof(Int));
+	  // tmp_global_eq_nb_val += nb_degree_of_freedom;
+	}
 
-  outfile << "%%MatrixMarket matrix coordinate pattern";
+	for (UInt i = 0; i < size_mat; ++i) {
+	  if (dof_type_ptr[local_eq_nb_val[i]] == -2 || dof_type_ptr[local_eq_nb_val[i]] == -1 ) {
+	    UInt c_irn = global_eq_nb_val[i];
+	    if(c_irn < size ) {
+	      //UInt j_start = (sparse_matrix_type == _symmetric) ? i : 0;
+	      for (UInt j = 0; j < size_mat; ++j) {
+		UInt c_jcn = global_eq_nb_val[j];
+		if(c_jcn < size) {
+		  KeyCOO irn_jcn = key(c_irn, c_jcn);
+		  irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
+
+		  if (irn_jcn_k_it == irn_jcn_k.end()) {
+		    if (dof_type_ptr[local_eq_nb_val[j]] == -2 || dof_type_ptr[local_eq_nb_val[j]] == -1 )
+		      this->d_nnz(local_eq_nb_val[i]) += 1;
+		    else
+		      this->o_nnz(local_eq_nb_val[i]) += 1;
+		  }
+		}
+	      }
+	    }
+	  }
+	}
+	conn_val += nb_nodes_per_element;
+      }
 
-  if(sparse_matrix_type == _symmetric) outfile << " symmetric";
-  else outfile << " general";
-  outfile << std::endl;
+      delete [] global_eq_nb_val;
+      delete [] local_eq_nb_val;
+    }
 
-  UInt m = size;
-  outfile << m << " " << m << " " << nb_non_zero << std::endl;
+    // /// for pbc @todo correct it for parallel
+    // if(StaticCommunicator::getStaticCommunicator().getNbProc() == 1) {
+    //   for (UInt i = 0; i < size; ++i) {
+    // 	KeyCOO irn_jcn = key(i, i);
+    // 	irn_jcn_k_it = irn_jcn_k.find(irn_jcn);
+    // 	if(irn_jcn_k_it == irn_jcn_k.end()) {
+    // 	  irn_jcn_k[irn_jcn] = nb_non_zero;
+    // 	  irn.push_back(i + 1);
+    // 	  jcn.push_back(i + 1);
+    // 	  nb_non_zero++;
+    // 	}
+    //   }
+    // }
+  }
 
-  for (UInt i = 0; i < nb_non_zero; ++i) {
-    outfile << irn.storage()[i] << " " << jcn.storage()[i] << " 1" << std::endl;
+  /// map arrays of nonzeros per row from akantu global to petsc global numbering
+  ierr = AOApplicationToPetsc(this->petsc_wrapper->ao,
+		       local_size, d_nnz.storage()); CHKERRXX(ierr);
+  ierr = AOApplicationToPetsc(this->petsc_wrapper->ao,
+		       local_size, o_nnz.storage()); CHKERRXX(ierr);
+
+  // std::string mat_type;
+  // mat_type.resize(20, 'a');
+  // std::cout << "MatType: " << mat_type << std::endl;
+  // const char * mat_type_ptr = mat_type.c_str();
+
+  MatType type;
+  MatGetType(this->petsc_wrapper->mat, &type);
+
+  //  PetscTypeCompare((PetscObject)(this->petsc_wrapper->mat),MATSEQAIJ,&sametype);
+  //ierr = PetscTypeCompare(pet, MATSEQAIJ, &sametype); CHKERRXX(ierr);
+
+  /// build profile:
+  if (strcmp(type, MATSEQAIJ) == 0) {
+    ierr = MatSeqAIJSetPreallocation(this->petsc_wrapper->mat,
+				     0, d_nnz.storage()); CHKERRXX(ierr);
+  } else if ((strcmp(type, MATMPIAIJ) == 0)) {
+    ierr = MatMPIAIJSetPreallocation(this->petsc_wrapper->mat,
+				     0, d_nnz.storage(), 0,
+				     o_nnz.storage()); CHKERRXX(ierr); 
+  } else {
+    AKANTU_DEBUG_ERROR("The type " << type << " of PETSc matrix is not handled by"
+		       << " akantu in the preallocation step");
   }
 
-  outfile.close();
+  /// assemble matrix
+  MatAssemblyBegin(this->petsc_wrapper->mat, MAT_FINAL_ASSEMBLY);
+  MatAssemblyEnd(this->petsc_wrapper->mat, MAT_FINAL_ASSEMBLY);
 
   AKANTU_DEBUG_OUT();
 }
 
 
 /* -------------------------------------------------------------------------- */
-void PetscMatrix::saveMatrix(const std::string & filename) const {
+void PETScMatrix::saveMatrix(const std::string & filename) const {
   AKANTU_DEBUG_IN();
 
-  std::ofstream outfile;
-  outfile.precision(std::numeric_limits<Real>::digits10);
-
-  outfile.open(filename.c_str());
-
-  outfile << "%%MatrixMarket matrix coordinate real";
-
-  if(sparse_matrix_type == _symmetric) outfile << " symmetric";
-  else outfile << " general";
-  outfile << std::endl;
-
-  outfile << size << " " << size << " " << nb_non_zero << std::endl;
-
-  for (UInt i = 0; i < nb_non_zero; ++i) {
-    outfile << irn(i) << " " << jcn(i) << " " << a(i) << std::endl;
-  }
+  PetscErrorCode ierr;
+  
+  /// create Petsc viewer
+  PetscViewer viewer; 
+  ierr = PetscViewerASCIIOpen(this->petsc_wrapper->communicator, filename.c_str(), &viewer); CHKERRXX(ierr);
+  /// save the matrix
+  ierr =  MatView(this->petsc_wrapper->mat, viewer); CHKERRXX(ierr);
 
-  outfile.close();
+  /// destroy the viewer
+  ierr =  PetscViewerDestroy(&viewer); CHKERRXX(ierr);
 
   AKANTU_DEBUG_OUT();
 }
 
-/* -------------------------------------------------------------------------- */
-Array<Real> & operator*=(Array<Real> & vect, const PetscMatrix & mat) {
-  AKANTU_DEBUG_IN();
+// /* -------------------------------------------------------------------------- */
+// Array<Real> & operator*=(Array<Real> & vect, const PETScMatrix & mat) {
+//   AKANTU_DEBUG_IN();
 
-  Array<Real> result 
-  MatMult(this->mat, vect, )
+//   Array<Real> result 
+//   MatMult(this->mat, vect, )
 
-  // AKANTU_DEBUG_ASSERT((vect.getSize()*vect.getNbComponent() == mat.getSize()) &&
-  // 		      (vect.getNbComponent() == mat.getNbDegreOfFreedom()),
-  // 		      "The size of the matrix and the vector do not match");
+//   // AKANTU_DEBUG_ASSERT((vect.getSize()*vect.getNbComponent() == mat.getSize()) &&
+//   // 		      (vect.getNbComponent() == mat.getNbDegreOfFreedom()),
+//   // 		      "The size of the matrix and the vector do not match");
 
-  const PetscMatrixType & sparse_matrix_type = mat.getPetscMatrixType();
-  DOFSynchronizer * dof_synchronizer = mat.getDOFSynchronizerPointer();
+//   const PETScMatrixType & sparse_matrix_type = mat.getPETScMatrixType();
+//   DOFSynchronizer * dof_synchronizer = mat.getDOFSynchronizerPointer();
 
-  UInt nb_non_zero = mat.getNbNonZero();
-  Real * tmp = new Real [vect.getNbComponent() * vect.getSize()];
-  std::fill_n(tmp, vect.getNbComponent() * vect.getSize(), 0);
+//   UInt nb_non_zero = mat.getNbNonZero();
+//   Real * tmp = new Real [vect.getNbComponent() * vect.getSize()];
+//   std::fill_n(tmp, vect.getNbComponent() * vect.getSize(), 0);
 
-  Int * i_val  = mat.getIRN().storage();
-  Int * j_val  = mat.getJCN().storage();
-  Real * a_val = mat.getA().storage();
+//   Int * i_val  = mat.getIRN().storage();
+//   Int * j_val  = mat.getJCN().storage();
+//   Real * a_val = mat.getA().storage();
 
-  Real * vect_val = vect.storage();
+//   Real * vect_val = vect.storage();
 
-  for (UInt k = 0; k < nb_non_zero; ++k) {
-    UInt i = *(i_val++);
-    UInt j = *(j_val++);
-    Real a = *(a_val++);
+//   for (UInt k = 0; k < nb_non_zero; ++k) {
+//     UInt i = *(i_val++);
+//     UInt j = *(j_val++);
+//     Real a = *(a_val++);
 
-    UInt local_i = i - 1;
-    UInt local_j = j - 1;
-    if(dof_synchronizer) {
-      local_i = dof_synchronizer->getDOFLocalID(local_i);
-      local_j = dof_synchronizer->getDOFLocalID(local_j);
-    }
+//     UInt local_i = i - 1;
+//     UInt local_j = j - 1;
+//     if(dof_synchronizer) {
+//       local_i = dof_synchronizer->getDOFLocalID(local_i);
+//       local_j = dof_synchronizer->getDOFLocalID(local_j);
+//     }
 
-    tmp[local_i] += a * vect_val[local_j];
-    if((sparse_matrix_type == _symmetric) && (local_i != local_j))
-      tmp[local_j] += a * vect_val[local_i];
-  }
+//     tmp[local_i] += a * vect_val[local_j];
+//     if((sparse_matrix_type == _symmetric) && (local_i != local_j))
+//       tmp[local_j] += a * vect_val[local_i];
+//   }
 
-  memcpy(vect_val, tmp, vect.getNbComponent() * vect.getSize() * sizeof(Real));
-  delete [] tmp;
+//   memcpy(vect_val, tmp, vect.getNbComponent() * vect.getSize() * sizeof(Real));
+//   delete [] tmp;
 
-  if(dof_synchronizer)
-    dof_synchronizer->reduceSynchronize<AddOperation>(vect);
+//   if(dof_synchronizer)
+//     dof_synchronizer->reduceSynchronize<AddOperation>(vect);
 
-  AKANTU_DEBUG_OUT();
+//   AKANTU_DEBUG_OUT();
 
-  return vect;
-}
+//   return vect;
+// }
 
-/* -------------------------------------------------------------------------- */
-void PetscMatrix::copyContent(const PetscMatrix & matrix) {
-  AKANTU_DEBUG_IN();
-  AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
-		      "The two matrices don't have the same profiles");
+// /* -------------------------------------------------------------------------- */
+// void PETScMatrix::copyContent(const PETScMatrix & matrix) {
+//   AKANTU_DEBUG_IN();
+//   AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
+// 		      "The two matrices don't have the same profiles");
 
-  MatCopy(this->mat, matrix->mat, SAME_NONZERO_PATTERN);
+//   MatCopy(this->mat, matrix->mat, SAME_NONZERO_PATTERN);
 
-  AKANTU_DEBUG_OUT();
-}
+//   AKANTU_DEBUG_OUT();
+// }
 
-///* -------------------------------------------------------------------------- */
-//void PetscMatrix::copyProfile(const PetscMatrix & matrix) {
-//  AKANTU_DEBUG_IN();
-//  irn = matrix.irn;
-//  jcn = matrix.jcn;
-//  nb_non_zero = matrix.nb_non_zero;
-//  irn_jcn_k = matrix.irn_jcn_k;
-//  a.resize(nb_non_zero);
-//  AKANTU_DEBUG_OUT();
-//}
+// ///* -------------------------------------------------------------------------- */
+// //void PETScMatrix::copyProfile(const PETScMatrix & matrix) {
+// //  AKANTU_DEBUG_IN();
+// //  irn = matrix.irn;
+// //  jcn = matrix.jcn;
+// //  nb_non_zero = matrix.nb_non_zero;
+// //  irn_jcn_k = matrix.irn_jcn_k;
+// //  a.resize(nb_non_zero);
+// //  AKANTU_DEBUG_OUT();
+// //}
 
 /* -------------------------------------------------------------------------- */
-void PetscMatrix::add(const SparseMatrix & matrix, Real alpha) {
+void PETScMatrix::add(const SparseMatrix & matrix, Real alpha) {
+  PetscErrorCode ierr;
   AKANTU_DEBUG_ASSERT(nb_non_zero == matrix.getNbNonZero(),
-		      "The two matrices don't have the same profile");
-
-  // get values and local indices of matrix that has to be added
-  UInt i_global;
-  UInt j_global;
+		      "The two matrix don't have the same profiles");
 
-  Array<UInt>::scalar_iterator i_global_it = i_global.begin();
-  Array<UInt>::scalar_iterator i_global_end = i_global.end();
-  Array<UInt>::scalar_iterator j_global_it = j_global.begin();
+  const Array<Real> matrix_a = matrix.getA();
+  Array<Int> matrix_irn = matrix.getIRN();
+  Array<Int> matrix_jcn = matrix.getJCN();
+  UInt matrix_nb_non_zero = matrix.getNbNonZero();
 
-  Int * i = matrix.irn.storage();
-  Int *j = matrix.jcn.storage();
-  Real * a_val = matrix.a.storage();
+  /// map global akantu to global petsc
+  ierr = AOApplicationToPetsc(this->petsc_wrapper->ao, matrix_nb_non_zero,matrix_irn.storage()); CHKERRXX(ierr);
+  ierr = AOApplicationToPetsc(this->petsc_wrapper->ao, matrix_nb_non_zero,matrix_jcn.storage()); CHKERRXX(ierr);
 
-  for (; i != i_global_end; ++i_global_it; ++j_global_it; ++i; ++j; ++a_val) {
-    // get the akantu global dof index
-    i_global = dof_synchronizer->getDOFGlobalID(*i);
-    j_global = dof_synchronizer->getDOFGlobalID(*j);
+  Real val_to_add = 0;
 
-    // get the petsc gloobal dof index
-    AOApplicationToPetsc(&ao,2,{i_global,j_global})
-    MatSetValue(*mat,i,j,*a_val,INSERT_VALUES); 
+  for (UInt n = 0; n < matrix_nb_non_zero; ++n) {
+    val_to_add = alpha * matrix_a(n);
+    ierr = MatSetValue(this->petsc_wrapper->mat, matrix_irn(n), matrix_jcn(n), val_to_add,INSERT_VALUES); CHKERRXX(ierr);
   }
 
- 
-}
 
+}
 
 /* -------------------------------------------------------------------------- */
-void PetscMatrix::lump(Array<Real> & lumped) {
-  AKANTU_DEBUG_IN();
-
-  AKANTU_DEBUG_ASSERT((lumped.getNbComponent() == nb_degree_of_freedom),
-		      "The size of the matrix and the vector do not match");
-
-  UInt vect_size = size / nb_degree_of_freedom;
-  if(dof_synchronizer) vect_size = dof_synchronizer->getNbDOFs() / nb_degree_of_freedom;
-
-  lumped.resize(vect_size);
-  lumped.clear();
-
-  Int * i_val  = irn.storage();
-  Int * j_val  = jcn.storage();
-  Real * a_val = a.storage();
-
-  Real * vect_val = lumped.storage();
-
-  for (UInt k = 0; k < nb_non_zero; ++k) {
-    UInt i = *(i_val++);
-    UInt j = *(j_val++);
-    Real a = *(a_val++);
-
-    UInt local_i = i - 1;
-    UInt local_j = j - 1;
-    if(dof_synchronizer) {
-      local_i = dof_synchronizer->getDOFLocalID(local_i);
-      local_j = dof_synchronizer->getDOFLocalID(local_j);
-    }
-
-    vect_val[local_i] += a;
-    if(sparse_matrix_type == _symmetric && (i != j))
-      vect_val[local_j] += a;
-  }
-
-  if(dof_synchronizer)
-    dof_synchronizer->reduceSynchronize<AddOperation>(lumped);
-
-  AKANTU_DEBUG_OUT();
+void PETScMatrix::performAssembly() {
+  PetscErrorCode ierr;
+  ierr = MatAssemblyBegin(this->petsc_wrapper->mat, MAT_FINAL_ASSEMBLY); CHKERRXX(ierr);
+  ierr = MatAssemblyEnd(this->petsc_wrapper->mat, MAT_FINAL_ASSEMBLY); CHKERRXX(ierr);
 }
 
+
 __END_AKANTU__
diff --git a/src/solver/petsc_matrix.hh b/src/solver/petsc_matrix.hh
index 75d7bc308..40a04103d 100644
--- a/src/solver/petsc_matrix.hh
+++ b/src/solver/petsc_matrix.hh
@@ -1,126 +1,158 @@
 /**
  * @file   petsc_matrix.hh
  * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Mon Jul 21 14:49:49 2014
  *
  * @brief  Interface for PETSc matrices
  *
  * @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_PETSC_MATRIX_HH__
 #define __AKANTU_PETSC_MATRIX_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "sparse_matrix.hh"
 
-struct Mat;
-struct AO;
-
 /* -------------------------------------------------------------------------- */
 __BEGIN_AKANTU__
 
+class PETScWrapper;
+
+class PETScMatrix : public SparseMatrix {
+  /* ------------------------------------------------------------------------ */
+  /* Constructors/Destructors                                                 */
+  /* ------------------------------------------------------------------------ */
+public:
+  PETScMatrix(UInt size,
+	      const SparseMatrixType & sparse_matrix_type,
+	      const ID & id = "petsc_matrix",
+	      const MemoryID & memory_id = 0);
+
+  PETScMatrix(const SparseMatrix & matrix,
+	      const ID & id = "petsc_matrix",
+	      const MemoryID & memory_id = 0);
 
+  virtual ~PETScMatrix();
+
+
+private:
+  /// init internal PETSc matrix
+  void init();
 
-class PetscMatrix : SparseMatrix {
   /* ------------------------------------------------------------------------ */
-  /* Typedefs                                                                 */
-  /* ------------------------------------------------------------------------ */  
+  /* Methods                                                                  */
+  /* ------------------------------------------------------------------------ */
+public:
+  /// resize PETSc matrix
+  void resize(const DOFSynchronizer & dof_synchronizer);
 
-  class PetscMatrixValue {
+  // /// remove the existing profile
+  // inline void clearProfile();
 
-  public:
+  // /// add a non-zero element
+  // virtual UInt addToProfile(UInt i, UInt j);
 
-    PetscMatrixValue(){}
+  // /// set the matrix to 0
+  // inline void clear();
 
-    inline PetscMatrixValue operator = (Real v){
-      MatSetValue(*mat,i,j,v,INSERT_VALUES);
-      return *this;
-    };
+  // /// assemble a local matrix in the sparse one
+  // inline void addToMatrix(UInt i, UInt j, Real value);
 
+  /// fill the profil of the matrix
+  virtual void buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom);
 
-    inline PetscMatrixValue operator += (Real v){
-      //     std::cout << "set " << std::abs(Real(i)-Real(j)) << std::endl;
-      MatSetValue(*mat,i,j,v,ADD_VALUES);
-      return *this;
-    };
+  // /// modify the matrix to "remove" the blocked dof
+  // virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
 
-    inline PetscMatrixValue operator -= (Real v){
-      MatSetValue(*mat,i,j,-1.*v,ADD_VALUES);
-      return *this;
-    };
+  /// modify the matrix to "remove" the blocked dof
+  virtual void applyBoundaryNormal(Array<bool> & boundary_normal, Array<Real> & EulerAngles, Array<Real> & rhs, const Array<Real> & matrix, Array<Real> & rhs_rotated) {
+    AKANTU_DEBUG_TO_IMPLEMENT();
+  }
 
-    friend PetscMatrix;
+  /// modify the matrix to "remove" the blocked dof
+  virtual void removeBoundary(const Array<bool> & boundary) {
+    AKANTU_DEBUG_TO_IMPLEMENT();
+  }
+  
+  /// perform assembly so that matrix is ready for use
+  void performAssembly();
 
-  private:
+  // /// restore the profile that was before removing the boundaries
+  // virtual void restoreProfile();
 
-    UInt i,j;
-    Mat * mat;
-  };
+  // /// save the profil in a file using the MatrixMarket file format
+  // virtual void saveProfile(const std::string & filename) const;
 
-  /* ------------------------------------------------------------------------ */
-  /* Constructors/Destructors                                                 */
-  /* ------------------------------------------------------------------------ */
-public:
-  PetscMatrix(UInt size,
-	       const SparseMatrixType & sparse_matrix_type,
-	       UInt nb_degree_of_freedom,
-	       const ID & id = "petsc_matrix",
-	       const MemoryID & memory_id = 0);
+  /// save the matrix in a file using the MatrixMarket file format
+  virtual void saveMatrix(const std::string & filename) const;
 
-  PetscMatrix(const PetscMatrix & matrix,
-	       const ID & id = "petsc_matrix",
-	       const MemoryID & memory_id = 0);
+  // /// copy assuming the profile are the same
+  // virtual void copyContent(const SparseMatrix & matrix);
 
-  virtual ~PetscMatrix();
+  // /// copy profile
+  // //  void copyProfile(const SparseMatrix & matrix);
 
-  typedef std::pair<UInt, UInt> KeyCOO;
-  typedef unordered_map<KeyCOO, UInt>::type coordinate_list_map;
+  /// add matrix assuming the profile are the same
+  virtual void add(const SparseMatrix & matrix, Real alpha);
 
+  // /// diagonal lumping
+  // virtual void lump(Array<Real> & lumped);
 
-  /* ------------------------------------------------------------------------ */
-  /* Methods                                                                  */
-  /* ------------------------------------------------------------------------ */
-public:
+  // /// function to print the contain of the class
+  // //virtual void printself(std::ostream & stream, int indent = 0) const;
+
+private:
+  /// create a mapping from the global akantu numbering to the PETSc numbering
+  void createGlobalAkantuToPETScMap(Int* local_master_eq_nbs_ptr);
+
+  /// create a mapping from the local akantu numbering to the PETSc numbering
+  void createLocalAkantuToPETScMap(const DOFSynchronizer & dof_synchronizer);
 
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
 
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
-  
+
 
 private:
+  /// store the PETSc structures
+  PETScWrapper * petsc_wrapper;
 
-  Mat * mat;
-  AO  * ao;
+  /// size of the diagonal part of the matrix partition
+  Int local_size;
 
+  /// number of nonzeros in every row of the diagonal part
+  Array<Int> d_nnz;
 
+  /// number of nonzeros in every row of the off-diagonal part
+  Array<Int> o_nnz;
 };
 
 __END_AKANTU__
 
 #endif /* __AKANTU_PETSCI_MATRIX_HH__ */
diff --git a/src/solver/petsc_matrix_inline_impl.cc b/src/solver/petsc_matrix_inline_impl.cc
index a4c0792ae..b3fe55d54 100644
--- a/src/solver/petsc_matrix_inline_impl.cc
+++ b/src/solver/petsc_matrix_inline_impl.cc
@@ -1,73 +1,73 @@
 /**
  * @file   petsc_matrix_inline_impl.cc
  * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
  * @date   Mon Jul 21 21:42:12 2014
  *
  * @brief  Implementation of PetscMatrix inline functions
  *
  * @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 UInt PetscMatrix::addToProfile(UInt i, UInt j) {
+// /* -------------------------------------------------------------------------- */
+// inline UInt PetscMatrix::addToProfile(UInt i, UInt j) {
 
-  // initialize new value
-  MatSetValuesLocal(this->mat,1,i,1,j,0,INSERT_VALUES);
+//   // initialize new value
+//   MatSetValuesLocal(this->mat,1,i,1,j,0,INSERT_VALUES);
 
-  nb_non_zero++;
+//   nb_non_zero++;
 
-  return nb_non_zero - 1;
-}
+//   return nb_non_zero - 1;
+// }
 
-/* -------------------------------------------------------------------------- */
-inline void PetscMatrix::clearProfile() {
-  //retain matrix but reinitialize its content
-  MatZeroEntries(this->mat);
-  nb_non_zero = 0;
-}
+// /* -------------------------------------------------------------------------- */
+// inline void PetscMatrix::clearProfile() {
+//   //retain matrix but reinitialize its content
+//   MatZeroEntries(this->mat);
+//   nb_non_zero = 0;
+// }
 
-/* -------------------------------------------------------------------------- */
-inline void PetscMatrix::clear() {
-  memset(a.storage(), 0, nb_non_zero*sizeof(Real));
-}
+// /* -------------------------------------------------------------------------- */
+// inline void PetscMatrix::clear() {
+//   memset(a.storage(), 0, nb_non_zero*sizeof(Real));
+// }
 
-/* -------------------------------------------------------------------------- */
-inline void PetscMatrix::addToMatrix(UInt i, UInt j, Real value) {
-  MatSetValue(this->mat,1,i,1,j,value,ADD_VALUES);
-}
+// /* -------------------------------------------------------------------------- */
+// inline void PetscMatrix::addToMatrix(UInt i, UInt j, Real value) {
+//   MatSetValue(this->mat,1,i,1,j,value,ADD_VALUES);
+// }
 
-/* -------------------------------------------------------------------------- */
-inline Real PetscMatrix::operator()(UInt i, UInt j) const {
-  KeyCOO jcn_irn = key(i, j);
-  coordinate_list_map::const_iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
-  if(irn_jcn_k_it == irn_jcn_k.end()) return 0;
-  return this->mat(i,j).
-}
+// /* -------------------------------------------------------------------------- */
+// inline Real PetscMatrix::operator()(UInt i, UInt j) const {
+//   KeyCOO jcn_irn = key(i, j);
+//   coordinate_list_map::const_iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
+//   if(irn_jcn_k_it == irn_jcn_k.end()) return 0;
+//   return this->mat(i,j).
+// }
 
-/* -------------------------------------------------------------------------- */
-inline Real & PetscMatrix::operator()(UInt i, UInt j) {
-  KeyCOO jcn_irn = key(i, j);
-  coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
-  AKANTU_DEBUG_ASSERT(irn_jcn_k_it != irn_jcn_k.end(),
-		      "Couple (i,j) = (" << i << "," << j << ") does not exist in the profile");
+// /* -------------------------------------------------------------------------- */
+// inline Real & PetscMatrix::operator()(UInt i, UInt j) {
+//   KeyCOO jcn_irn = key(i, j);
+//   coordinate_list_map::iterator irn_jcn_k_it = irn_jcn_k.find(jcn_irn);
+//   AKANTU_DEBUG_ASSERT(irn_jcn_k_it != irn_jcn_k.end(),
+// 		      "Couple (i,j) = (" << i << "," << j << ") does not exist in the profile");
 
-  return a.storage()[irn_jcn_k_it->second];
-}
+//   return a.storage()[irn_jcn_k_it->second];
+// }
 
diff --git a/src/solver/solver_petsc.cc b/src/solver/solver_petsc.cc
index a2bd2348e..ce058bc87 100644
--- a/src/solver/solver_petsc.cc
+++ b/src/solver/solver_petsc.cc
@@ -1,954 +1,954 @@
-/**
- * @file   solver_petsc.cc
- *
- * @author Nicolas Richart <nicolas.richart@epfl.ch>
- # @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
- *
- * @date   Mon Dec 13 10:48:06 2010
- *
- * @brief  Solver class implementation for the petsc solver
- *
- * @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/>.
- *
- */
+// /**
+//  * @file   solver_petsc.cc
+//  *
+//  * @author Nicolas Richart <nicolas.richart@epfl.ch>
+//  # @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
+//  *
+//  * @date   Mon Dec 13 10:48:06 2010
+//  *
+//  * @brief  Solver class implementation for the petsc solver
+//  *
+//  * @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/>.
+//  *
+//  */
 
-/* -------------------------------------------------------------------------- */
-#ifdef AKANTU_USE_MPI
-#include "static_communicator_mpi.hh"
-#endif
+// /* -------------------------------------------------------------------------- */
+// #ifdef AKANTU_USE_MPI
+// #include "static_communicator_mpi.hh"
+// #endif
 
-#include "solver_petsc.hh"
-#include "dof_synchronizer.hh"
+// #include "solver_petsc.hh"
+// #include "dof_synchronizer.hh"
 
-__BEGIN_AKANTU__
+// __BEGIN_AKANTU__
 
 
-void finalize_petsc() {
+// void finalize_petsc() {
   
-  static bool finalized = false;
-  if (!finalized) {
+//   static bool finalized = false;
+//   if (!finalized) {
     
-    cout<<"*** INFO *** PETSc is finalizing..."<<endl;
-    // finalize PETSc
-    PetscErrorCode ierr = PetscFinalize();CHKERRCONTINUE(ierr);
-    finalized = true;
-  }
-}
+//     cout<<"*** INFO *** PETSc is finalizing..."<<endl;
+//     // finalize PETSc
+//     PetscErrorCode ierr = PetscFinalize();CHKERRCONTINUE(ierr);
+//     finalized = true;
+//   }
+// }
 
 
-SolverPETSc::sparse_vector_type
-SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& AA,
-                         const SolverPETSc::sparse_vector_type& bb) {
-  
-  
-#ifdef CPPUTILS_VERBOSE
-  // parallel output stream
-  Output_stream out;
-  // timer
-  cpputils::ctimer timer;
-  out<<"Inside PETSc solver: "<<timer<<endl;
-#endif
-  
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Inside operator()(const sparse_matrix_type&, const sparse_vector_type&)... "<<timer<<endl;
-#endif
-  
-  assert(AA.rows() == bb.size());
-  
-  //  KSP ksp;            //!< linear solver context
-  
-  Vec            b;                /* RHS */
-  PC             pc;               /* preconditioner context */
-  PetscErrorCode ierr;
-  PetscInt       nlocal;
-  PetscInt       n = bb.size();
-  VecScatter ctx;
-  
-  /*
-   Create vectors.  Note that we form 1 vector from scratch and
-   then duplicate as needed. For this simple case let PETSc decide how
-   many elements of the vector are stored on each processor. The second
-   argument to VecSetSizes() below causes PETSc to decide.
-   */
-  ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRCONTINUE(ierr);
-  ierr = VecSetSizes(b,PETSC_DECIDE,n);CHKERRCONTINUE(ierr);
-  ierr = VecSetFromOptions(b);CHKERRCONTINUE(ierr);
-  if (!allocated_) {
-    ierr = VecDuplicate(b,&x_);CHKERRCONTINUE(ierr);
-  } else
-    VecZeroEntries(x_);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Vectors created... "<<timer<<endl;
-#endif
-  
-  
-  /* Set hight-hand-side vector */
-  for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
-    int row = it->first;
-    ierr = VecSetValues(b, 1, &row, &it->second, ADD_VALUES);
-  }
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Right hand side set... "<<timer<<endl;
-#endif
-  
-  
-  /*
-   Assemble vector, using the 2-step process:
-   VecAssemblyBegin(), VecAssemblyEnd()
-   Computations can be done while messages are in transition
-   by placing code between these two statements.
-   */
-  ierr = VecAssemblyBegin(b);CHKERRCONTINUE(ierr);
-  ierr = VecAssemblyEnd(b);CHKERRCONTINUE(ierr);
-  
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Right-hand-side vector assembled... "<<timer<<endl;
-  
-  ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
-  
-  Vec b_all;
-  ierr = VecScatterCreateToAll(b, &ctx, &b_all);CHKERRCONTINUE(ierr);
-  ierr = VecScatterBegin(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
-  ierr = VecScatterEnd(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
-  
-  value_type nrm;
-  VecNorm(b_all,NORM_2,&nrm);
-  out<<"  Norm of right hand side... "<<nrm<<endl;
-#endif
-  
-  /* Identify the starting and ending mesh points on each
-   processor for the interior part of the mesh. We let PETSc decide
-   above. */
-  
-  //    PetscInt rstart,rend;
-  //    ierr = VecGetOwnershipRange(x_,&rstart,&rend);CHKERRCONTINUE(ierr);
-  ierr = VecGetLocalSize(x_,&nlocal);CHKERRCONTINUE(ierr);
-  
-  
-  /*
-   Create matrix.  When using MatCreate(), the matrix format can
-   be specified at runtime.
+// SolverPETSc::sparse_vector_type
+// SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& AA,
+//                          const SolverPETSc::sparse_vector_type& bb) {
+  
+  
+// #ifdef CPPUTILS_VERBOSE
+//   // parallel output stream
+//   Output_stream out;
+//   // timer
+//   cpputils::ctimer timer;
+//   out<<"Inside PETSc solver: "<<timer<<endl;
+// #endif
+  
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Inside operator()(const sparse_matrix_type&, const sparse_vector_type&)... "<<timer<<endl;
+// #endif
+  
+//   assert(AA.rows() == bb.size());
+  
+//   //  KSP ksp;            //!< linear solver context
+  
+//   Vec            b;                /* RHS */
+//   PC             pc;               /* preconditioner context */
+//   PetscErrorCode ierr;
+//   PetscInt       nlocal;
+//   PetscInt       n = bb.size();
+//   VecScatter ctx;
+  
+//   /*
+//    Create vectors.  Note that we form 1 vector from scratch and
+//    then duplicate as needed. For this simple case let PETSc decide how
+//    many elements of the vector are stored on each processor. The second
+//    argument to VecSetSizes() below causes PETSc to decide.
+//    */
+//   ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRCONTINUE(ierr);
+//   ierr = VecSetSizes(b,PETSC_DECIDE,n);CHKERRCONTINUE(ierr);
+//   ierr = VecSetFromOptions(b);CHKERRCONTINUE(ierr);
+//   if (!allocated_) {
+//     ierr = VecDuplicate(b,&x_);CHKERRCONTINUE(ierr);
+//   } else
+//     VecZeroEntries(x_);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Vectors created... "<<timer<<endl;
+// #endif
+  
+  
+//   /* Set hight-hand-side vector */
+//   for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
+//     int row = it->first;
+//     ierr = VecSetValues(b, 1, &row, &it->second, ADD_VALUES);
+//   }
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Right hand side set... "<<timer<<endl;
+// #endif
+  
+  
+//   /*
+//    Assemble vector, using the 2-step process:
+//    VecAssemblyBegin(), VecAssemblyEnd()
+//    Computations can be done while messages are in transition
+//    by placing code between these two statements.
+//    */
+//   ierr = VecAssemblyBegin(b);CHKERRCONTINUE(ierr);
+//   ierr = VecAssemblyEnd(b);CHKERRCONTINUE(ierr);
+  
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Right-hand-side vector assembled... "<<timer<<endl;
+  
+//   ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
+  
+//   Vec b_all;
+//   ierr = VecScatterCreateToAll(b, &ctx, &b_all);CHKERRCONTINUE(ierr);
+//   ierr = VecScatterBegin(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+//   ierr = VecScatterEnd(ctx,b,b_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+  
+//   value_type nrm;
+//   VecNorm(b_all,NORM_2,&nrm);
+//   out<<"  Norm of right hand side... "<<nrm<<endl;
+// #endif
+  
+//   /* Identify the starting and ending mesh points on each
+//    processor for the interior part of the mesh. We let PETSc decide
+//    above. */
+  
+//   //    PetscInt rstart,rend;
+//   //    ierr = VecGetOwnershipRange(x_,&rstart,&rend);CHKERRCONTINUE(ierr);
+//   ierr = VecGetLocalSize(x_,&nlocal);CHKERRCONTINUE(ierr);
+  
+  
+//   /*
+//    Create matrix.  When using MatCreate(), the matrix format can
+//    be specified at runtime.
    
-   Performance tuning note:  For problems of substantial size,
-   preallocation of matrix memory is crucial for attaining good
-   performance. See the matrix chapter of the users manual for details.
+//    Performance tuning note:  For problems of substantial size,
+//    preallocation of matrix memory is crucial for attaining good
+//    performance. See the matrix chapter of the users manual for details.
    
-   We pass in nlocal as the "local" size of the matrix to force it
-   to have the same parallel layout as the vector created above.
-   */
-  if (!allocated_) {
+//    We pass in nlocal as the "local" size of the matrix to force it
+//    to have the same parallel layout as the vector created above.
+//    */
+//   if (!allocated_) {
     
-    ierr = MatCreate(PETSC_COMM_WORLD,&A_);CHKERRCONTINUE(ierr);
-    ierr = MatSetSizes(A_,nlocal,nlocal,n,n);CHKERRCONTINUE(ierr);
-    ierr = MatSetFromOptions(A_);CHKERRCONTINUE(ierr);
-    ierr = MatSetUp(A_);CHKERRCONTINUE(ierr);
-  } else {
-    // zero-out matrix
-    MatZeroEntries(A_);
-  }
-  
-  
-  /*
-   Assemble matrix.
+//     ierr = MatCreate(PETSC_COMM_WORLD,&A_);CHKERRCONTINUE(ierr);
+//     ierr = MatSetSizes(A_,nlocal,nlocal,n,n);CHKERRCONTINUE(ierr);
+//     ierr = MatSetFromOptions(A_);CHKERRCONTINUE(ierr);
+//     ierr = MatSetUp(A_);CHKERRCONTINUE(ierr);
+//   } else {
+//     // zero-out matrix
+//     MatZeroEntries(A_);
+//   }
+  
+  
+//   /*
+//    Assemble matrix.
    
-   The linear system is distributed across the processors by
-   chunks of contiguous rows, which correspond to contiguous
-   sections of the mesh on which the problem is discretized.
-   For matrix assembly, each processor contributes entries for
-   the part that it owns locally.
-   */
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Zeroed-out sparse matrix entries... "<<timer<<endl;
-#endif
-  
-  for (sparse_matrix_type::const_hash_iterator it = AA.map_.begin(); it != AA.map_.end(); ++it) {
+//    The linear system is distributed across the processors by
+//    chunks of contiguous rows, which correspond to contiguous
+//    sections of the mesh on which the problem is discretized.
+//    For matrix assembly, each processor contributes entries for
+//    the part that it owns locally.
+//    */
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Zeroed-out sparse matrix entries... "<<timer<<endl;
+// #endif
+  
+//   for (sparse_matrix_type::const_hash_iterator it = AA.map_.begin(); it != AA.map_.end(); ++it) {
     
-    // get subscripts
-    std::pair<size_t,size_t> subs = AA.unhash(it->first);
-    PetscInt row = subs.first;
-    PetscInt col = subs.second;
-    ierr = MatSetValues(A_, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
-  }
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Filled sparse matrix... "<<timer<<endl;
-#endif
-  
-  
-  
-  
-  /* Assemble the matrix */
-  ierr = MatAssemblyBegin(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
-  ierr = MatAssemblyEnd(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
-  
-  
-  if (!allocated_) {
-    // set after the first MatAssemblyEnd
-    //        ierr = MatSetOption(A_, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE);CHKERRCONTINUE(ierr);
-    ierr = MatSetOption(A_, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRCONTINUE(ierr);
-  }
-  
-  
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Sparse matrix assembled... "<<timer<<endl;
-  // view matrix
-  MatView(A_, PETSC_VIEWER_STDOUT_WORLD);
-  
-  MatNorm(A_,NORM_FROBENIUS,&nrm);
-  out<<"  Norm of stiffness matrix... "<<nrm<<endl;
-#endif
-  
-  /*
-   Set operators. Here the matrix that defines the linear system
-   also serves as the preconditioning matrix.
-   */
-  //    ierr = KSPSetOperators(ksp,A_,A_,DIFFERENT_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
-  ierr = KSPSetOperators(ksp_,A_,A_,SAME_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
-  
-  
-  //
-  //    /*
-  //     Set runtime options, e.g.,
-  //     -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
-  //     These options will override those specified above as long as
-  //     KSPSetFromOptions() is called _after_ any other customization
-  //     routines.
-  //     */
-  //    ierr = KSPSetFromOptions(ksp);CHKERRCONTINUE(ierr);
-  
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Solving system... "<<timer<<endl;
-#endif
-  
-  
-  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-   Solve the linear system
-   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-  /*
-   Solve linear system
-   */
-  ierr = KSPSolve(ksp_,b,x_);CHKERRCONTINUE(ierr);
-  
-  
-#ifdef CPPUTILS_VERBOSE
-  
-  /*
-   View solver info; we could instead use the option -ksp_view to
-   print this info to the screen at the conclusion of KSPSolve().
-   */
-  ierr = KSPView(ksp_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
-  
-  int iter;
-  KSPGetIterationNumber(ksp_, &iter);
-  out<<"  System solved in "<<iter<<" iterations... "<<timer<<endl;
-  KSPConvergedReason reason;
-  ierr = KSPGetConvergedReason(ksp_,&reason);CHKERRCONTINUE(ierr);
-  if (reason < 0)
-    out<<"*** WARNING *** PETSc solver diverged with flag ";
-  else
-    out<<"*** INFO *** PETSc solver converged with flag ";
-  
-  if (reason == KSP_CONVERGED_RTOL)
-    out<<"KSP_CONVERGED_RTOL"<<endl;
-  else if (reason == KSP_CONVERGED_ATOL)
-    out<<"KSP_CONVERGED_ATOL"<<endl;
-  else if (reason == KSP_CONVERGED_ITS)
-    out<<"KSP_CONVERGED_ITS"<<endl;
-  else if (reason == KSP_CONVERGED_CG_NEG_CURVE)
-    out<<"KSP_CONVERGED_CG_NEG_CURVE"<<endl;
-  else if (reason == KSP_CONVERGED_CG_CONSTRAINED)
-    out<<"KSP_CONVERGED_CG_CONSTRAINED"<<endl;
-  else if (reason == KSP_CONVERGED_STEP_LENGTH)
-    out<<"KSP_CONVERGED_STEP_LENGTH"<<endl;
-  else if (reason == KSP_CONVERGED_HAPPY_BREAKDOWN)
-    out<<"KSP_CONVERGED_HAPPY_BREAKDOWN"<<endl;
-  else if (reason == KSP_DIVERGED_NULL)
-    out<<"KSP_DIVERGED_NULL"<<endl;
-  else if (reason == KSP_DIVERGED_ITS)
-    out<<"KSP_DIVERGED_ITS"<<endl;
-  else if (reason == KSP_DIVERGED_DTOL)
-    out<<"KSP_DIVERGED_DTOL"<<endl;
-  else if (reason == KSP_DIVERGED_BREAKDOWN)
-    out<<"KSP_DIVERGED_BREAKDOWN"<<endl;
-  else if (reason == KSP_DIVERGED_BREAKDOWN_BICG)
-    out<<"KSP_DIVERGED_BREAKDOWN_BICG"<<endl;
-  else if (reason == KSP_DIVERGED_NONSYMMETRIC)
-    out<<"KSP_DIVERGED_NONSYMMETRIC"<<endl;
-  else if (reason == KSP_DIVERGED_INDEFINITE_PC)
-    out<<"KSP_DIVERGED_INDEFINITE_PC"<<endl;
-  else if (reason == KSP_DIVERGED_NAN)
-    out<<"KSP_DIVERGED_NAN"<<endl;
-  else if (reason == KSP_DIVERGED_INDEFINITE_MAT)
-    out<<"KSP_DIVERGED_INDEFINITE_MAT"<<endl;
-  else if (reason == KSP_CONVERGED_ITERATING)
-    out<<"KSP_CONVERGED_ITERATING"<<endl;
-  
-  PetscReal rnorm;
-  ierr = KSPGetResidualNorm(ksp_,&rnorm);CHKERRCONTINUE(ierr);
-  
-  out<<"PETSc last residual norm computed: "<<rnorm<<endl;
-  
-  ierr = VecView(x_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
-  
-  VecNorm(x_,NORM_2,&nrm);
-  out<<"  Norm of solution vector... "<<nrm<<endl;
-  
-#endif
-  
-  
-  
-  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-   Check solution and clean up
-   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-  
-  Vec x_all;
-  
-  ierr = VecScatterCreateToAll(x_, &ctx, &x_all);CHKERRCONTINUE(ierr);
-  ierr = VecScatterBegin(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
-  ierr = VecScatterEnd(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
-  
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Solution vector scattered... "<<timer<<endl;
-  VecNorm(x_all,NORM_2,&nrm);
-  out<<"  Norm of scattered vector... "<<nrm<<endl;
-  //    ierr = VecView(x_all,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
-#endif
-  
-  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-   Get values from solution and store them in the object that will be
-   returned
-   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-  
-  sparse_vector_type xx(bb.size());
-  
-  /* Set solution vector */
-  double zero = 0.;
-  double val;
-  for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
-    int row = it->first;
-    ierr = VecGetValues(x_all, 1, &row, &val);
-    if (val != zero)
-      xx[row] = val;
-  }
-  
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Solution vector copied... "<<timer<<endl;
-  //    out<<"  Norm of copied solution vector... "<<norm(xx, Insert_t)<<endl;
-#endif
-  
-  
-  /*
-   Free work space.  All PETSc objects should be destroyed when they
-   are no longer needed.
-   */
-  ierr = VecDestroy(&b);CHKERRCONTINUE(ierr);
-  //    ierr = KSPDestroy(&ksp);CHKERRCONTINUE(ierr);
-  
-  // set allocated flag
-  if (!allocated_) {
-    allocated_ = true;
-  }
-  
-  
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Temporary data structures destroyed... "<<timer<<endl;
-#endif
-  
-  return xx;
-}
+//     // get subscripts
+//     std::pair<size_t,size_t> subs = AA.unhash(it->first);
+//     PetscInt row = subs.first;
+//     PetscInt col = subs.second;
+//     ierr = MatSetValues(A_, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
+//   }
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Filled sparse matrix... "<<timer<<endl;
+// #endif
+  
+  
+  
+  
+//   /* Assemble the matrix */
+//   ierr = MatAssemblyBegin(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+//   ierr = MatAssemblyEnd(A_,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+  
+  
+//   if (!allocated_) {
+//     // set after the first MatAssemblyEnd
+//     //        ierr = MatSetOption(A_, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE);CHKERRCONTINUE(ierr);
+//     ierr = MatSetOption(A_, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRCONTINUE(ierr);
+//   }
+  
+  
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Sparse matrix assembled... "<<timer<<endl;
+//   // view matrix
+//   MatView(A_, PETSC_VIEWER_STDOUT_WORLD);
+  
+//   MatNorm(A_,NORM_FROBENIUS,&nrm);
+//   out<<"  Norm of stiffness matrix... "<<nrm<<endl;
+// #endif
+  
+//   /*
+//    Set operators. Here the matrix that defines the linear system
+//    also serves as the preconditioning matrix.
+//    */
+//   //    ierr = KSPSetOperators(ksp,A_,A_,DIFFERENT_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
+//   ierr = KSPSetOperators(ksp_,A_,A_,SAME_NONZERO_PATTERN);CHKERRCONTINUE(ierr);
+  
+  
+//   //
+//   //    /*
+//   //     Set runtime options, e.g.,
+//   //     -ksp_type <type> -pc_type <type> -ksp_monitor -ksp_rtol <rtol>
+//   //     These options will override those specified above as long as
+//   //     KSPSetFromOptions() is called _after_ any other customization
+//   //     routines.
+//   //     */
+//   //    ierr = KSPSetFromOptions(ksp);CHKERRCONTINUE(ierr);
+  
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Solving system... "<<timer<<endl;
+// #endif
+  
+  
+//   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+//    Solve the linear system
+//    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+//   /*
+//    Solve linear system
+//    */
+//   ierr = KSPSolve(ksp_,b,x_);CHKERRCONTINUE(ierr);
+  
+  
+// #ifdef CPPUTILS_VERBOSE
+  
+//   /*
+//    View solver info; we could instead use the option -ksp_view to
+//    print this info to the screen at the conclusion of KSPSolve().
+//    */
+//   ierr = KSPView(ksp_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
+  
+//   int iter;
+//   KSPGetIterationNumber(ksp_, &iter);
+//   out<<"  System solved in "<<iter<<" iterations... "<<timer<<endl;
+//   KSPConvergedReason reason;
+//   ierr = KSPGetConvergedReason(ksp_,&reason);CHKERRCONTINUE(ierr);
+//   if (reason < 0)
+//     out<<"*** WARNING *** PETSc solver diverged with flag ";
+//   else
+//     out<<"*** INFO *** PETSc solver converged with flag ";
+  
+//   if (reason == KSP_CONVERGED_RTOL)
+//     out<<"KSP_CONVERGED_RTOL"<<endl;
+//   else if (reason == KSP_CONVERGED_ATOL)
+//     out<<"KSP_CONVERGED_ATOL"<<endl;
+//   else if (reason == KSP_CONVERGED_ITS)
+//     out<<"KSP_CONVERGED_ITS"<<endl;
+//   else if (reason == KSP_CONVERGED_CG_NEG_CURVE)
+//     out<<"KSP_CONVERGED_CG_NEG_CURVE"<<endl;
+//   else if (reason == KSP_CONVERGED_CG_CONSTRAINED)
+//     out<<"KSP_CONVERGED_CG_CONSTRAINED"<<endl;
+//   else if (reason == KSP_CONVERGED_STEP_LENGTH)
+//     out<<"KSP_CONVERGED_STEP_LENGTH"<<endl;
+//   else if (reason == KSP_CONVERGED_HAPPY_BREAKDOWN)
+//     out<<"KSP_CONVERGED_HAPPY_BREAKDOWN"<<endl;
+//   else if (reason == KSP_DIVERGED_NULL)
+//     out<<"KSP_DIVERGED_NULL"<<endl;
+//   else if (reason == KSP_DIVERGED_ITS)
+//     out<<"KSP_DIVERGED_ITS"<<endl;
+//   else if (reason == KSP_DIVERGED_DTOL)
+//     out<<"KSP_DIVERGED_DTOL"<<endl;
+//   else if (reason == KSP_DIVERGED_BREAKDOWN)
+//     out<<"KSP_DIVERGED_BREAKDOWN"<<endl;
+//   else if (reason == KSP_DIVERGED_BREAKDOWN_BICG)
+//     out<<"KSP_DIVERGED_BREAKDOWN_BICG"<<endl;
+//   else if (reason == KSP_DIVERGED_NONSYMMETRIC)
+//     out<<"KSP_DIVERGED_NONSYMMETRIC"<<endl;
+//   else if (reason == KSP_DIVERGED_INDEFINITE_PC)
+//     out<<"KSP_DIVERGED_INDEFINITE_PC"<<endl;
+//   else if (reason == KSP_DIVERGED_NAN)
+//     out<<"KSP_DIVERGED_NAN"<<endl;
+//   else if (reason == KSP_DIVERGED_INDEFINITE_MAT)
+//     out<<"KSP_DIVERGED_INDEFINITE_MAT"<<endl;
+//   else if (reason == KSP_CONVERGED_ITERATING)
+//     out<<"KSP_CONVERGED_ITERATING"<<endl;
+  
+//   PetscReal rnorm;
+//   ierr = KSPGetResidualNorm(ksp_,&rnorm);CHKERRCONTINUE(ierr);
+  
+//   out<<"PETSc last residual norm computed: "<<rnorm<<endl;
+  
+//   ierr = VecView(x_,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
+  
+//   VecNorm(x_,NORM_2,&nrm);
+//   out<<"  Norm of solution vector... "<<nrm<<endl;
+  
+// #endif
+  
+  
+  
+//   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+//    Check solution and clean up
+//    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+  
+//   Vec x_all;
+  
+//   ierr = VecScatterCreateToAll(x_, &ctx, &x_all);CHKERRCONTINUE(ierr);
+//   ierr = VecScatterBegin(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+//   ierr = VecScatterEnd(ctx,x_,x_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+  
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Solution vector scattered... "<<timer<<endl;
+//   VecNorm(x_all,NORM_2,&nrm);
+//   out<<"  Norm of scattered vector... "<<nrm<<endl;
+//   //    ierr = VecView(x_all,PETSC_VIEWER_STDOUT_WORLD);CHKERRCONTINUE(ierr);
+// #endif
+  
+//   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+//    Get values from solution and store them in the object that will be
+//    returned
+//    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+  
+//   sparse_vector_type xx(bb.size());
+  
+//   /* Set solution vector */
+//   double zero = 0.;
+//   double val;
+//   for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
+//     int row = it->first;
+//     ierr = VecGetValues(x_all, 1, &row, &val);
+//     if (val != zero)
+//       xx[row] = val;
+//   }
+  
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Solution vector copied... "<<timer<<endl;
+//   //    out<<"  Norm of copied solution vector... "<<norm(xx, Insert_t)<<endl;
+// #endif
+  
+  
+//   /*
+//    Free work space.  All PETSc objects should be destroyed when they
+//    are no longer needed.
+//    */
+//   ierr = VecDestroy(&b);CHKERRCONTINUE(ierr);
+//   //    ierr = KSPDestroy(&ksp);CHKERRCONTINUE(ierr);
+  
+//   // set allocated flag
+//   if (!allocated_) {
+//     allocated_ = true;
+//   }
+  
+  
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+  
+//   return xx;
+// }
 
-SolverPETSc::sparse_vector_type SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& KKpf, const SolverPETSc::sparse_matrix_type& KKpp, const SolverPETSc::sparse_vector_type& UUp) {
+// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const SolverPETSc::sparse_matrix_type& KKpf, const SolverPETSc::sparse_matrix_type& KKpp, const SolverPETSc::sparse_vector_type& UUp) {
   
-#ifdef CPPUTILS_VERBOSE
-  // parallel output stream
-  Output_stream out;
-  // timer
-  cpputils::ctimer timer;
-  out<<"Inside SolverPETSc::operator()(const sparse_matrix&, const sparse_matrix&, const sparse_vector&). "<<timer<<endl;
-#endif
+// #ifdef CPPUTILS_VERBOSE
+//   // parallel output stream
+//   Output_stream out;
+//   // timer
+//   cpputils::ctimer timer;
+//   out<<"Inside SolverPETSc::operator()(const sparse_matrix&, const sparse_matrix&, const sparse_vector&). "<<timer<<endl;
+// #endif
   
-  Mat Kpf, Kpp;
-  Vec Up, Pf, Pp;
+//   Mat Kpf, Kpp;
+//   Vec Up, Pf, Pp;
   
-  PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&Kpf);CHKERRCONTINUE(ierr);
-  ierr = MatCreate(PETSC_COMM_WORLD,&Kpp);CHKERRCONTINUE(ierr);
+//   PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&Kpf);CHKERRCONTINUE(ierr);
+//   ierr = MatCreate(PETSC_COMM_WORLD,&Kpp);CHKERRCONTINUE(ierr);
   
   
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Allocating memory... "<<timer<<endl;
-#endif
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Allocating memory... "<<timer<<endl;
+// #endif
   
-  ierr = MatSetFromOptions(Kpf);CHKERRCONTINUE(ierr);
-  ierr = MatSetFromOptions(Kpp);CHKERRCONTINUE(ierr);
+//   ierr = MatSetFromOptions(Kpf);CHKERRCONTINUE(ierr);
+//   ierr = MatSetFromOptions(Kpp);CHKERRCONTINUE(ierr);
   
-  ierr = MatSetSizes(Kpf,PETSC_DECIDE,PETSC_DECIDE, KKpf.rows(), KKpf.columns());CHKERRCONTINUE(ierr);
-  ierr = MatSetSizes(Kpp,PETSC_DECIDE,PETSC_DECIDE, KKpp.rows(), KKpp.columns());CHKERRCONTINUE(ierr);
+//   ierr = MatSetSizes(Kpf,PETSC_DECIDE,PETSC_DECIDE, KKpf.rows(), KKpf.columns());CHKERRCONTINUE(ierr);
+//   ierr = MatSetSizes(Kpp,PETSC_DECIDE,PETSC_DECIDE, KKpp.rows(), KKpp.columns());CHKERRCONTINUE(ierr);
   
-  // get number of non-zeros in both diagonal and non-diagonal portions of the matrix
+//   // get number of non-zeros in both diagonal and non-diagonal portions of the matrix
   
-  std::pair<size_t,size_t> Kpf_nz = KKpf.non_zero_off_diagonal();
-  std::pair<size_t,size_t> Kpp_nz = KKpp.non_zero_off_diagonal();
+//   std::pair<size_t,size_t> Kpf_nz = KKpf.non_zero_off_diagonal();
+//   std::pair<size_t,size_t> Kpp_nz = KKpp.non_zero_off_diagonal();
   
-  ierr = MatMPIAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL, Kpf_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
-  ierr = MatMPIAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL, Kpp_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
-  ierr = MatSeqAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL); CHKERRCONTINUE(ierr);
-  ierr = MatSeqAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL); CHKERRCONTINUE(ierr);
+//   ierr = MatMPIAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL, Kpf_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
+//   ierr = MatMPIAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL, Kpp_nz.second, PETSC_NULL); CHKERRCONTINUE(ierr);
+//   ierr = MatSeqAIJSetPreallocation(Kpf, Kpf_nz.first, PETSC_NULL); CHKERRCONTINUE(ierr);
+//   ierr = MatSeqAIJSetPreallocation(Kpp, Kpp_nz.first, PETSC_NULL); CHKERRCONTINUE(ierr);
   
-  for (sparse_matrix_type::const_hash_iterator it = KKpf.map_.begin(); it != KKpf.map_.end(); ++it) {
+//   for (sparse_matrix_type::const_hash_iterator it = KKpf.map_.begin(); it != KKpf.map_.end(); ++it) {
     
-    // get subscripts
-    std::pair<size_t,size_t> subs = KKpf.unhash(it->first);
-    int row = subs.first;
-    int col = subs.second;
-    ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
-  }
-  
-  for (sparse_matrix_type::const_hash_iterator it = KKpp.map_.begin(); it != KKpp.map_.end(); ++it) {
+//     // get subscripts
+//     std::pair<size_t,size_t> subs = KKpf.unhash(it->first);
+//     int row = subs.first;
+//     int col = subs.second;
+//     ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
+//   }
+  
+//   for (sparse_matrix_type::const_hash_iterator it = KKpp.map_.begin(); it != KKpp.map_.end(); ++it) {
     
-    // get subscripts
-    std::pair<size_t,size_t> subs = KKpp.unhash(it->first);
-    int row = subs.first;
-    int col = subs.second;
-    ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
-  }
+//     // get subscripts
+//     std::pair<size_t,size_t> subs = KKpp.unhash(it->first);
+//     int row = subs.first;
+//     int col = subs.second;
+//     ierr = MatSetValues(Kpf, 1, &row, 1, &col, &it->second, ADD_VALUES);CHKERRCONTINUE(ierr);
+//   }
   
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Filled sparse matrices... "<<timer<<endl;
-#endif
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Filled sparse matrices... "<<timer<<endl;
+// #endif
   
   
-  /*
-   Assemble matrix, using the 2-step process:
-   MatAssemblyBegin(), MatAssemblyEnd()
-   Computations can be done while messages are in transition
-   by placing code between these two statements.
-   */
-  ierr = MatAssemblyBegin(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
-  ierr = MatAssemblyBegin(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
-  ierr = MatAssemblyEnd(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
-  ierr = MatAssemblyEnd(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+//   /*
+//    Assemble matrix, using the 2-step process:
+//    MatAssemblyBegin(), MatAssemblyEnd()
+//    Computations can be done while messages are in transition
+//    by placing code between these two statements.
+//    */
+//   ierr = MatAssemblyBegin(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+//   ierr = MatAssemblyBegin(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+//   ierr = MatAssemblyEnd(Kpf,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+//   ierr = MatAssemblyEnd(Kpp,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
   
   
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Sparse matrices assembled... "<<timer<<endl;
-#endif
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Sparse matrices assembled... "<<timer<<endl;
+// #endif
   
-  ierr = VecCreate(PETSC_COMM_WORLD,&Up);CHKERRCONTINUE(ierr);
-  ierr = VecSetSizes(Up,PETSC_DECIDE, UUp.size());CHKERRCONTINUE(ierr);
-  ierr = VecSetFromOptions(Up);CHKERRCONTINUE(ierr);
+//   ierr = VecCreate(PETSC_COMM_WORLD,&Up);CHKERRCONTINUE(ierr);
+//   ierr = VecSetSizes(Up,PETSC_DECIDE, UUp.size());CHKERRCONTINUE(ierr);
+//   ierr = VecSetFromOptions(Up);CHKERRCONTINUE(ierr);
   
-  ierr = VecCreate(PETSC_COMM_WORLD,&Pf);CHKERRCONTINUE(ierr);
-  ierr = VecSetSizes(Pf,PETSC_DECIDE, KKpf.rows());CHKERRCONTINUE(ierr);
-  ierr = VecSetFromOptions(Pf);CHKERRCONTINUE(ierr);
-  ierr = VecDuplicate(Pf,&Pp);CHKERRCONTINUE(ierr);
+//   ierr = VecCreate(PETSC_COMM_WORLD,&Pf);CHKERRCONTINUE(ierr);
+//   ierr = VecSetSizes(Pf,PETSC_DECIDE, KKpf.rows());CHKERRCONTINUE(ierr);
+//   ierr = VecSetFromOptions(Pf);CHKERRCONTINUE(ierr);
+//   ierr = VecDuplicate(Pf,&Pp);CHKERRCONTINUE(ierr);
   
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Vectors created... "<<timer<<endl;
-#endif
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Vectors created... "<<timer<<endl;
+// #endif
   
   
-  /* Set hight-hand-side vector */
-  for (sparse_vector_type::const_hash_iterator it = UUp.map_.begin(); it != UUp.map_.end(); ++it) {
-    int row = it->first;
-    ierr = VecSetValues(Up, 1, &row, &it->second, ADD_VALUES);
-  }
+//   /* Set hight-hand-side vector */
+//   for (sparse_vector_type::const_hash_iterator it = UUp.map_.begin(); it != UUp.map_.end(); ++it) {
+//     int row = it->first;
+//     ierr = VecSetValues(Up, 1, &row, &it->second, ADD_VALUES);
+//   }
   
-  /*
-   Assemble vector, using the 2-step process:
-   VecAssemblyBegin(), VecAssemblyEnd()
-   Computations can be done while messages are in transition
-   by placing code between these two statements.
-   */
-  ierr = VecAssemblyBegin(Up);CHKERRCONTINUE(ierr);
-  ierr = VecAssemblyEnd(Up);CHKERRCONTINUE(ierr);
+//   /*
+//    Assemble vector, using the 2-step process:
+//    VecAssemblyBegin(), VecAssemblyEnd()
+//    Computations can be done while messages are in transition
+//    by placing code between these two statements.
+//    */
+//   ierr = VecAssemblyBegin(Up);CHKERRCONTINUE(ierr);
+//   ierr = VecAssemblyEnd(Up);CHKERRCONTINUE(ierr);
   
-  // add Kpf*Uf
-  ierr = MatMult(Kpf, x_, Pf);
+//   // add Kpf*Uf
+//   ierr = MatMult(Kpf, x_, Pf);
   
-  // add Kpp*Up
-  ierr = MatMultAdd(Kpp, Up, Pf, Pp);
+//   // add Kpp*Up
+//   ierr = MatMultAdd(Kpp, Up, Pf, Pp);
   
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Matrices multiplied... "<<timer<<endl;
-#endif
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Matrices multiplied... "<<timer<<endl;
+// #endif
   
   
-  VecScatter ctx;
-  Vec Pp_all;
+//   VecScatter ctx;
+//   Vec Pp_all;
   
-  ierr = VecScatterCreateToAll(Pp, &ctx, &Pp_all);CHKERRCONTINUE(ierr);
-  ierr = VecScatterBegin(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
-  ierr = VecScatterEnd(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+//   ierr = VecScatterCreateToAll(Pp, &ctx, &Pp_all);CHKERRCONTINUE(ierr);
+//   ierr = VecScatterBegin(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
+//   ierr = VecScatterEnd(ctx,Pp,Pp_all,INSERT_VALUES,SCATTER_FORWARD);CHKERRCONTINUE(ierr);
   
   
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Vector scattered... "<<timer<<endl;
-#endif
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Vector scattered... "<<timer<<endl;
+// #endif
   
-  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-   Get values from solution and store them in the object that will be
-   returned
-   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+//   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+//    Get values from solution and store them in the object that will be
+//    returned
+//    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
   
-  sparse_vector_type pp(KKpf.rows());
+//   sparse_vector_type pp(KKpf.rows());
   
-  // get reaction vector
-  for (int i=0; i<KKpf.rows(); ++i) {
+//   // get reaction vector
+//   for (int i=0; i<KKpf.rows(); ++i) {
     
-    PetscScalar v;
-    ierr = VecGetValues(Pp_all, 1, &i, &v);
-    if (v != PetscScalar())
-      pp[i] = v;
-  }
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Vector copied... "<<timer<<endl;
-#endif
-  
-  ierr = MatDestroy(&Kpf);CHKERRCONTINUE(ierr);
-  ierr = MatDestroy(&Kpp);CHKERRCONTINUE(ierr);
-  ierr = VecDestroy(&Up);CHKERRCONTINUE(ierr);
-  ierr = VecDestroy(&Pf);CHKERRCONTINUE(ierr);
-  ierr = VecDestroy(&Pp);CHKERRCONTINUE(ierr);
-  ierr = VecDestroy(&Pp_all);CHKERRCONTINUE(ierr);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Temporary data structures destroyed... "<<timer<<endl;
-#endif
-  
-  return pp;
-}
+//     PetscScalar v;
+//     ierr = VecGetValues(Pp_all, 1, &i, &v);
+//     if (v != PetscScalar())
+//       pp[i] = v;
+//   }
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Vector copied... "<<timer<<endl;
+// #endif
+  
+//   ierr = MatDestroy(&Kpf);CHKERRCONTINUE(ierr);
+//   ierr = MatDestroy(&Kpp);CHKERRCONTINUE(ierr);
+//   ierr = VecDestroy(&Up);CHKERRCONTINUE(ierr);
+//   ierr = VecDestroy(&Pf);CHKERRCONTINUE(ierr);
+//   ierr = VecDestroy(&Pp);CHKERRCONTINUE(ierr);
+//   ierr = VecDestroy(&Pp_all);CHKERRCONTINUE(ierr);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+  
+//   return pp;
+// }
 
 
 
-SolverPETSc::sparse_vector_type SolverPETSc::operator()(const SolverPETSc::sparse_vector_type& aa, const SolverPETSc::sparse_vector_type& bb) {
-  
-  assert(aa.size() == bb.size());
-  
-#ifdef CPPUTILS_VERBOSE
-  // parallel output stream
-  Output_stream out;
-  // timer
-  cpputils::ctimer timer;
-  out<<"Inside SolverPETSc::operator()(const sparse_vector&, const sparse_vector&). "<<timer<<endl;
-#endif
-  
-  Vec r;
-  
-  PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
-  ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
-  ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Vectors created... "<<timer<<endl;
-#endif
-  
-  // set values
-  for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
-    int row = it->first;
-    ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
-  }
-  for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
-    int row = it->first;
-    ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
-  }
-  
-  /*
-   Assemble vector, using the 2-step process:
-   VecAssemblyBegin(), VecAssemblyEnd()
-   Computations can be done while messages are in transition
-   by placing code between these two statements.
-   */
-  ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
-  ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
-  
-  
-  sparse_vector_type rr(aa.size());
-  
-  for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
-    int row = it->first;
-    ierr = VecGetValues(r, 1, &row, &rr[row]);
-  }
-  for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
-    int row = it->first;
-    ierr = VecGetValues(r, 1, &row, &rr[row]);
-  }
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Vector copied... "<<timer<<endl;
-#endif
-  
-  ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Temporary data structures destroyed... "<<timer<<endl;
-#endif
-  
-  return rr;
-}
+// SolverPETSc::sparse_vector_type SolverPETSc::operator()(const SolverPETSc::sparse_vector_type& aa, const SolverPETSc::sparse_vector_type& bb) {
+  
+//   assert(aa.size() == bb.size());
+  
+// #ifdef CPPUTILS_VERBOSE
+//   // parallel output stream
+//   Output_stream out;
+//   // timer
+//   cpputils::ctimer timer;
+//   out<<"Inside SolverPETSc::operator()(const sparse_vector&, const sparse_vector&). "<<timer<<endl;
+// #endif
+  
+//   Vec r;
+  
+//   PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
+//   ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
+//   ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Vectors created... "<<timer<<endl;
+// #endif
+  
+//   // set values
+//   for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
+//     int row = it->first;
+//     ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
+//   }
+//   for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
+//     int row = it->first;
+//     ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
+//   }
+  
+//   /*
+//    Assemble vector, using the 2-step process:
+//    VecAssemblyBegin(), VecAssemblyEnd()
+//    Computations can be done while messages are in transition
+//    by placing code between these two statements.
+//    */
+//   ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
+//   ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
+  
+  
+//   sparse_vector_type rr(aa.size());
+  
+//   for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
+//     int row = it->first;
+//     ierr = VecGetValues(r, 1, &row, &rr[row]);
+//   }
+//   for (sparse_vector_type::const_hash_iterator it = bb.map_.begin(); it != bb.map_.end(); ++it) {
+//     int row = it->first;
+//     ierr = VecGetValues(r, 1, &row, &rr[row]);
+//   }
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Vector copied... "<<timer<<endl;
+// #endif
+  
+//   ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+  
+//   return rr;
+// }
 
-SolverPETSc::value_type SolverPETSc::norm(const SolverPETSc::sparse_matrix_type& aa, Element_insertion_type flag) {
-  
-#ifdef CPPUTILS_VERBOSE
-  // parallel output stream
-  Output_stream out;
-  // timer
-  cpputils::ctimer timer;
-  out<<"Inside SolverPETSc::norm(const sparse_matrix&). "<<timer<<endl;
-#endif
-  
-  Mat r;
-  
-  PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
-  ierr = MatSetSizes(r,PETSC_DECIDE,PETSC_DECIDE, aa.rows(), aa.columns());CHKERRCONTINUE(ierr);
-  ierr = MatSetFromOptions(r);CHKERRCONTINUE(ierr);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Matrix created... "<<timer<<endl;
-#endif
-  
-  // set values
-  for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
-    // get subscripts
-    std::pair<size_t,size_t> subs = aa.unhash(it->first);
-    int row = subs.first;
-    int col = subs.second;
+// SolverPETSc::value_type SolverPETSc::norm(const SolverPETSc::sparse_matrix_type& aa, Element_insertion_type flag) {
+  
+// #ifdef CPPUTILS_VERBOSE
+//   // parallel output stream
+//   Output_stream out;
+//   // timer
+//   cpputils::ctimer timer;
+//   out<<"Inside SolverPETSc::norm(const sparse_matrix&). "<<timer<<endl;
+// #endif
+  
+//   Mat r;
+  
+//   PetscErrorCode ierr = MatCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
+//   ierr = MatSetSizes(r,PETSC_DECIDE,PETSC_DECIDE, aa.rows(), aa.columns());CHKERRCONTINUE(ierr);
+//   ierr = MatSetFromOptions(r);CHKERRCONTINUE(ierr);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Matrix created... "<<timer<<endl;
+// #endif
+  
+//   // set values
+//   for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
+//     // get subscripts
+//     std::pair<size_t,size_t> subs = aa.unhash(it->first);
+//     int row = subs.first;
+//     int col = subs.second;
     
-    if (flag == Add_t)
-      ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, ADD_VALUES);
-    else if (flag == Insert_t)
-      ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, INSERT_VALUES);
-    CHKERRCONTINUE(ierr);
-  }
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Matrix filled..."<<timer<<endl;
-#endif
-  
-  /*
-   Assemble vector, using the 2-step process:
-   VecAssemblyBegin(), VecAssemblyEnd()
-   Computations can be done while messages are in transition
-   by placing code between these two statements.
-   */
-  ierr = MatAssemblyBegin(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
-  ierr = MatAssemblyEnd(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
-  
-  value_type nrm;
-  
-  MatNorm(r,NORM_FROBENIUS,&nrm);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Norm computed... "<<timer<<endl;
-#endif
-  
-  ierr = MatDestroy(&r);CHKERRCONTINUE(ierr);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Temporary data structures destroyed... "<<timer<<endl;
-#endif
-  
-  return nrm;
-}
+//     if (flag == Add_t)
+//       ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, ADD_VALUES);
+//     else if (flag == Insert_t)
+//       ierr = MatSetValues(r, 1, &row, 1, &col, &it->second, INSERT_VALUES);
+//     CHKERRCONTINUE(ierr);
+//   }
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Matrix filled..."<<timer<<endl;
+// #endif
+  
+//   /*
+//    Assemble vector, using the 2-step process:
+//    VecAssemblyBegin(), VecAssemblyEnd()
+//    Computations can be done while messages are in transition
+//    by placing code between these two statements.
+//    */
+//   ierr = MatAssemblyBegin(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+//   ierr = MatAssemblyEnd(r,MAT_FINAL_ASSEMBLY);CHKERRCONTINUE(ierr);
+  
+//   value_type nrm;
+  
+//   MatNorm(r,NORM_FROBENIUS,&nrm);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Norm computed... "<<timer<<endl;
+// #endif
+  
+//   ierr = MatDestroy(&r);CHKERRCONTINUE(ierr);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+  
+//   return nrm;
+// }
 
 
-SolverPETSc::value_type SolverPETSc::norm(const SolverPETSc::sparse_vector_type& aa, Element_insertion_type flag) {
-  
-#ifdef CPPUTILS_VERBOSE
-  // parallel output stream
-  Output_stream out;
-  // timer
-  cpputils::ctimer timer;
-  out<<"Inside SolverPETSc::norm(const sparse_vector&). "<<timer<<endl;
-#endif
-  
-  Vec r;
-  
-  PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
-  ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
-  ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Vector created... "<<timer<<endl;
-#endif
-  
-  // set values
-  for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
-    int row = it->first;
-    if (flag == Add_t)
-      ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
-    else if (flag == Insert_t)
-      ierr = VecSetValues(r, 1, &row, &it->second, INSERT_VALUES);
-    CHKERRCONTINUE(ierr);
-  }
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Vector filled..."<<timer<<endl;
-#endif
-  
-  /*
-   Assemble vector, using the 2-step process:
-   VecAssemblyBegin(), VecAssemblyEnd()
-   Computations can be done while messages are in transition
-   by placing code between these two statements.
-   */
-  ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
-  ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
-  
-  value_type nrm;
-  
-  VecNorm(r,NORM_2,&nrm);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Norm computed... "<<timer<<endl;
-#endif
-  
-  ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
-  
-#ifdef CPPUTILS_VERBOSE
-  out<<"  Temporary data structures destroyed... "<<timer<<endl;
-#endif
-  
-  return nrm;
-  
-}
+// SolverPETSc::value_type SolverPETSc::norm(const SolverPETSc::sparse_vector_type& aa, Element_insertion_type flag) {
+  
+// #ifdef CPPUTILS_VERBOSE
+//   // parallel output stream
+//   Output_stream out;
+//   // timer
+//   cpputils::ctimer timer;
+//   out<<"Inside SolverPETSc::norm(const sparse_vector&). "<<timer<<endl;
+// #endif
+  
+//   Vec r;
+  
+//   PetscErrorCode ierr = VecCreate(PETSC_COMM_WORLD,&r);CHKERRCONTINUE(ierr);
+//   ierr = VecSetSizes(r,PETSC_DECIDE, aa.size());CHKERRCONTINUE(ierr);
+//   ierr = VecSetFromOptions(r);CHKERRCONTINUE(ierr);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Vector created... "<<timer<<endl;
+// #endif
+  
+//   // set values
+//   for (sparse_vector_type::const_hash_iterator it = aa.map_.begin(); it != aa.map_.end(); ++it) {
+//     int row = it->first;
+//     if (flag == Add_t)
+//       ierr = VecSetValues(r, 1, &row, &it->second, ADD_VALUES);
+//     else if (flag == Insert_t)
+//       ierr = VecSetValues(r, 1, &row, &it->second, INSERT_VALUES);
+//     CHKERRCONTINUE(ierr);
+//   }
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Vector filled..."<<timer<<endl;
+// #endif
+  
+//   /*
+//    Assemble vector, using the 2-step process:
+//    VecAssemblyBegin(), VecAssemblyEnd()
+//    Computations can be done while messages are in transition
+//    by placing code between these two statements.
+//    */
+//   ierr = VecAssemblyBegin(r);CHKERRCONTINUE(ierr);
+//   ierr = VecAssemblyEnd(r);CHKERRCONTINUE(ierr);
+  
+//   value_type nrm;
+  
+//   VecNorm(r,NORM_2,&nrm);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Norm computed... "<<timer<<endl;
+// #endif
+  
+//   ierr = VecDestroy(&r);CHKERRCONTINUE(ierr);
+  
+// #ifdef CPPUTILS_VERBOSE
+//   out<<"  Temporary data structures destroyed... "<<timer<<endl;
+// #endif
+  
+//   return nrm;
+  
+// }
 
 
 
-//
-///* -------------------------------------------------------------------------- */
-//SolverMumps::SolverMumps(SparseMatrix & matrix,
-//                         const ID & id,
-//                         const MemoryID & memory_id) :
-//Solver(matrix, id, memory_id), is_mumps_data_initialized(false), rhs_is_local(true) {
-//  AKANTU_DEBUG_IN();
-//  
-//#ifdef AKANTU_USE_MPI
-//  parallel_method = SolverMumpsOptions::_fully_distributed;
-//#else //AKANTU_USE_MPI
-//  parallel_method = SolverMumpsOptions::_master_slave_distributed;
-//#endif //AKANTU_USE_MPI
-//  
-//  CommunicatorEventHandler & comm_event_handler = *this;
-//  
-//  communicator.registerEventHandler(comm_event_handler);
-//  
-//  AKANTU_DEBUG_OUT();
-//}
-//
-///* -------------------------------------------------------------------------- */
-//SolverMumps::~SolverMumps() {
-//  AKANTU_DEBUG_IN();
-//  
-//  AKANTU_DEBUG_OUT();
-//}
-//
-///* -------------------------------------------------------------------------- */
-//void SolverMumps::destroyMumpsData() {
-//  AKANTU_DEBUG_IN();
-//  
-//  if(is_mumps_data_initialized) {
-//    mumps_data.job = _smj_destroy; // destroy
-//    dmumps_c(&mumps_data);
-//    is_mumps_data_initialized = false;
-//  }
-//  
-//  AKANTU_DEBUG_OUT();
-//}
-//
-///* -------------------------------------------------------------------------- */
-//void SolverMumps::onCommunicatorFinalize(const StaticCommunicator & comm) {
-//  AKANTU_DEBUG_IN();
-//  
-//  try{
-//    const StaticCommunicatorMPI & comm_mpi =
-//    dynamic_cast<const StaticCommunicatorMPI &>(comm.getRealStaticCommunicator());
-//    if(mumps_data.comm_fortran == MPI_Comm_c2f(comm_mpi.getMPICommunicator()))
-//      destroyMumpsData();
-//  } catch(...) {}
-//  
-//  AKANTU_DEBUG_OUT();
-//}
-//
-///* -------------------------------------------------------------------------- */
-//void SolverMumps::initMumpsData(SolverMumpsOptions::ParallelMethod parallel_method) {
-//  switch(parallel_method) {
-//    case SolverMumpsOptions::_fully_distributed:
-//      icntl(18) = 3; //fully distributed
-//      icntl(28) = 0; //automatic choice
-//      
-//      mumps_data.nz_loc  = matrix->getNbNonZero();
-//      mumps_data.irn_loc = matrix->getIRN().values;
-//      mumps_data.jcn_loc = matrix->getJCN().values;
-//      break;
-//    case SolverMumpsOptions::_master_slave_distributed:
-//      if(prank == 0) {
-//        mumps_data.nz  = matrix->getNbNonZero();
-//        mumps_data.irn = matrix->getIRN().values;
-//        mumps_data.jcn = matrix->getJCN().values;
-//      } else {
-//        mumps_data.nz  = 0;
-//        mumps_data.irn = NULL;
-//        mumps_data.jcn = NULL;
-//        
-//        icntl(18) = 0; //centralized
-//        icntl(28) = 0; //sequential analysis
-//      }
-//      break;
-//  }
-//}
-//
-///* -------------------------------------------------------------------------- */
-//void SolverMumps::initialize(SolverOptions & options) {
-//  AKANTU_DEBUG_IN();
-//  
-//  mumps_data.par = 1;
-//  
-//  if(SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options)) {
-//    if(opt->parallel_method == SolverMumpsOptions::_master_slave_distributed) {
-//      mumps_data.par = 0;
-//    }
-//  }
-//  
-//  mumps_data.sym = 2 * (matrix->getSparseMatrixType() == _symmetric);
-//  prank = communicator.whoAmI();
-//#ifdef AKANTU_USE_MPI
-//  mumps_data.comm_fortran = MPI_Comm_c2f(dynamic_cast<const StaticCommunicatorMPI &>(communicator.getRealStaticCommunicator()).getMPICommunicator());
-//#endif
-//  
-//  if(AKANTU_DEBUG_TEST(dblTrace)) {
-//    icntl(1) = 2;
-//    icntl(2) = 2;
-//    icntl(3) = 2;
-//    icntl(4) = 4;
-//  }
-//  
-//  mumps_data.job = _smj_initialize; //initialize
-//  dmumps_c(&mumps_data);
-//  is_mumps_data_initialized = true;
-//  
-//  /* ------------------------------------------------------------------------ */
-//  UInt size = matrix->getSize();
-//  
-//  if(prank == 0) {
-//    std::stringstream sstr_rhs; sstr_rhs << id << ":rhs";
-//    rhs = &(alloc<Real>(sstr_rhs.str(), size, 1, REAL_INIT_VALUE));
-//  } else {
-//    rhs = NULL;
-//  }
-//  
-//  /// No outputs
-//  icntl(1) = 0;
-//  icntl(2) = 0;
-//  icntl(3) = 0;
-//  icntl(4) = 0;
-//  mumps_data.nz_alloc = 0;
-//  
-//  if (AKANTU_DEBUG_TEST(dblDump)) icntl(4) = 4;
-//  
-//  mumps_data.n   = size;
-//  
-//  if(AKANTU_DEBUG_TEST(dblDump)) {
-//    strcpy(mumps_data.write_problem, "mumps_matrix.mtx");
-//  }
-//  
-//  /* ------------------------------------------------------------------------ */
-//  // Default Scaling
-//  icntl(8) = 77;
-//  
-//  icntl(5) = 0; // Assembled matrix
-//  
-//  SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options);
-//  if(opt)
-//    parallel_method = opt->parallel_method;
-//  
-//  initMumpsData(parallel_method);
-//  
-//  mumps_data.job = _smj_analyze; //analyze
-//  dmumps_c(&mumps_data);
-//  
-//  AKANTU_DEBUG_OUT();
-//}
-//
-///* -------------------------------------------------------------------------- */
-//void SolverMumps::setRHS(Array<Real> & rhs) {
-//  if(prank == 0) {
-//    matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
-//  } else {
-//    matrix->getDOFSynchronizer().gather(rhs, 0);
-//  }
-//}
-//
-///* -------------------------------------------------------------------------- */
-//void SolverMumps::solve() {
-//  AKANTU_DEBUG_IN();
-//  
-//  if(parallel_method == SolverMumpsOptions::_fully_distributed)
-//    mumps_data.a_loc  = matrix->getA().values;
-//  else
-//    if(prank == 0) {
-//      mumps_data.a  = matrix->getA().values;
-//    }
-//  
-//  if(prank == 0) {
-//    mumps_data.rhs = rhs->values;
-//  }
-//  
-//  /// Default centralized dense second member
-//  icntl(20) = 0;
-//  icntl(21) = 0;
-//  
-//  mumps_data.job = _smj_factorize_solve; //solve
-//  dmumps_c(&mumps_data);
-//  
-//  AKANTU_DEBUG_ASSERT(info(1) != -10, "Singular matrix");
-//  AKANTU_DEBUG_ASSERT(info(1) == 0,
-//                      "Error in mumps during solve process, check mumps user guide INFO(1) ="
-//                      << info(1));
-//  
-//  AKANTU_DEBUG_OUT();
-//}
-//
-///* -------------------------------------------------------------------------- */
-//void SolverMumps::solve(Array<Real> & solution) {
-//  AKANTU_DEBUG_IN();
-//  
-//  solve();
-//  
-//  if(prank == 0) {
-//    matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
-//  } else {
-//    matrix->getDOFSynchronizer().scatter(solution, 0);
-//  }
-//  
-//  AKANTU_DEBUG_OUT();
-//}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //SolverMumps::SolverMumps(SparseMatrix & matrix,
+// //                         const ID & id,
+// //                         const MemoryID & memory_id) :
+// //Solver(matrix, id, memory_id), is_mumps_data_initialized(false), rhs_is_local(true) {
+// //  AKANTU_DEBUG_IN();
+// //  
+// //#ifdef AKANTU_USE_MPI
+// //  parallel_method = SolverMumpsOptions::_fully_distributed;
+// //#else //AKANTU_USE_MPI
+// //  parallel_method = SolverMumpsOptions::_master_slave_distributed;
+// //#endif //AKANTU_USE_MPI
+// //  
+// //  CommunicatorEventHandler & comm_event_handler = *this;
+// //  
+// //  communicator.registerEventHandler(comm_event_handler);
+// //  
+// //  AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //SolverMumps::~SolverMumps() {
+// //  AKANTU_DEBUG_IN();
+// //  
+// //  AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::destroyMumpsData() {
+// //  AKANTU_DEBUG_IN();
+// //  
+// //  if(is_mumps_data_initialized) {
+// //    mumps_data.job = _smj_destroy; // destroy
+// //    dmumps_c(&mumps_data);
+// //    is_mumps_data_initialized = false;
+// //  }
+// //  
+// //  AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::onCommunicatorFinalize(const StaticCommunicator & comm) {
+// //  AKANTU_DEBUG_IN();
+// //  
+// //  try{
+// //    const StaticCommunicatorMPI & comm_mpi =
+// //    dynamic_cast<const StaticCommunicatorMPI &>(comm.getRealStaticCommunicator());
+// //    if(mumps_data.comm_fortran == MPI_Comm_c2f(comm_mpi.getMPICommunicator()))
+// //      destroyMumpsData();
+// //  } catch(...) {}
+// //  
+// //  AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::initMumpsData(SolverMumpsOptions::ParallelMethod parallel_method) {
+// //  switch(parallel_method) {
+// //    case SolverMumpsOptions::_fully_distributed:
+// //      icntl(18) = 3; //fully distributed
+// //      icntl(28) = 0; //automatic choice
+// //      
+// //      mumps_data.nz_loc  = matrix->getNbNonZero();
+// //      mumps_data.irn_loc = matrix->getIRN().values;
+// //      mumps_data.jcn_loc = matrix->getJCN().values;
+// //      break;
+// //    case SolverMumpsOptions::_master_slave_distributed:
+// //      if(prank == 0) {
+// //        mumps_data.nz  = matrix->getNbNonZero();
+// //        mumps_data.irn = matrix->getIRN().values;
+// //        mumps_data.jcn = matrix->getJCN().values;
+// //      } else {
+// //        mumps_data.nz  = 0;
+// //        mumps_data.irn = NULL;
+// //        mumps_data.jcn = NULL;
+// //        
+// //        icntl(18) = 0; //centralized
+// //        icntl(28) = 0; //sequential analysis
+// //      }
+// //      break;
+// //  }
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::initialize(SolverOptions & options) {
+// //  AKANTU_DEBUG_IN();
+// //  
+// //  mumps_data.par = 1;
+// //  
+// //  if(SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options)) {
+// //    if(opt->parallel_method == SolverMumpsOptions::_master_slave_distributed) {
+// //      mumps_data.par = 0;
+// //    }
+// //  }
+// //  
+// //  mumps_data.sym = 2 * (matrix->getSparseMatrixType() == _symmetric);
+// //  prank = communicator.whoAmI();
+// //#ifdef AKANTU_USE_MPI
+// //  mumps_data.comm_fortran = MPI_Comm_c2f(dynamic_cast<const StaticCommunicatorMPI &>(communicator.getRealStaticCommunicator()).getMPICommunicator());
+// //#endif
+// //  
+// //  if(AKANTU_DEBUG_TEST(dblTrace)) {
+// //    icntl(1) = 2;
+// //    icntl(2) = 2;
+// //    icntl(3) = 2;
+// //    icntl(4) = 4;
+// //  }
+// //  
+// //  mumps_data.job = _smj_initialize; //initialize
+// //  dmumps_c(&mumps_data);
+// //  is_mumps_data_initialized = true;
+// //  
+// //  /* ------------------------------------------------------------------------ */
+// //  UInt size = matrix->getSize();
+// //  
+// //  if(prank == 0) {
+// //    std::stringstream sstr_rhs; sstr_rhs << id << ":rhs";
+// //    rhs = &(alloc<Real>(sstr_rhs.str(), size, 1, REAL_INIT_VALUE));
+// //  } else {
+// //    rhs = NULL;
+// //  }
+// //  
+// //  /// No outputs
+// //  icntl(1) = 0;
+// //  icntl(2) = 0;
+// //  icntl(3) = 0;
+// //  icntl(4) = 0;
+// //  mumps_data.nz_alloc = 0;
+// //  
+// //  if (AKANTU_DEBUG_TEST(dblDump)) icntl(4) = 4;
+// //  
+// //  mumps_data.n   = size;
+// //  
+// //  if(AKANTU_DEBUG_TEST(dblDump)) {
+// //    strcpy(mumps_data.write_problem, "mumps_matrix.mtx");
+// //  }
+// //  
+// //  /* ------------------------------------------------------------------------ */
+// //  // Default Scaling
+// //  icntl(8) = 77;
+// //  
+// //  icntl(5) = 0; // Assembled matrix
+// //  
+// //  SolverMumpsOptions * opt = dynamic_cast<SolverMumpsOptions *>(&options);
+// //  if(opt)
+// //    parallel_method = opt->parallel_method;
+// //  
+// //  initMumpsData(parallel_method);
+// //  
+// //  mumps_data.job = _smj_analyze; //analyze
+// //  dmumps_c(&mumps_data);
+// //  
+// //  AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::setRHS(Array<Real> & rhs) {
+// //  if(prank == 0) {
+// //    matrix->getDOFSynchronizer().gather(rhs, 0, this->rhs);
+// //  } else {
+// //    matrix->getDOFSynchronizer().gather(rhs, 0);
+// //  }
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::solve() {
+// //  AKANTU_DEBUG_IN();
+// //  
+// //  if(parallel_method == SolverMumpsOptions::_fully_distributed)
+// //    mumps_data.a_loc  = matrix->getA().values;
+// //  else
+// //    if(prank == 0) {
+// //      mumps_data.a  = matrix->getA().values;
+// //    }
+// //  
+// //  if(prank == 0) {
+// //    mumps_data.rhs = rhs->values;
+// //  }
+// //  
+// //  /// Default centralized dense second member
+// //  icntl(20) = 0;
+// //  icntl(21) = 0;
+// //  
+// //  mumps_data.job = _smj_factorize_solve; //solve
+// //  dmumps_c(&mumps_data);
+// //  
+// //  AKANTU_DEBUG_ASSERT(info(1) != -10, "Singular matrix");
+// //  AKANTU_DEBUG_ASSERT(info(1) == 0,
+// //                      "Error in mumps during solve process, check mumps user guide INFO(1) ="
+// //                      << info(1));
+// //  
+// //  AKANTU_DEBUG_OUT();
+// //}
+// //
+// ///* -------------------------------------------------------------------------- */
+// //void SolverMumps::solve(Array<Real> & solution) {
+// //  AKANTU_DEBUG_IN();
+// //  
+// //  solve();
+// //  
+// //  if(prank == 0) {
+// //    matrix->getDOFSynchronizer().scatter(solution, 0, this->rhs);
+// //  } else {
+// //    matrix->getDOFSynchronizer().scatter(solution, 0);
+// //  }
+// //  
+// //  AKANTU_DEBUG_OUT();
+// //}
 
 
-__END_AKANTU__
+// __END_AKANTU__
diff --git a/src/solver/solver_petsc.hh b/src/solver/solver_petsc.hh
index f4b7e1c42..352a2db88 100644
--- a/src/solver/solver_petsc.hh
+++ b/src/solver/solver_petsc.hh
@@ -1,273 +1,271 @@
 /**
  * @file   solver_petsc.hh
  *
  # @author Alejandro M. Aragón <alejandro.aragon@epfl.ch>
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date   Mon Dec 13 10:48:06 2010
  *
  * @brief  Solver class implementation for the petsc solver
  *
  * @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_SOLVER_PETSC_HH__
-#define __AKANTU_SOLVER_PETSC_HH__
+// #ifndef __AKANTU_SOLVER_PETSC_HH__
+// #define __AKANTU_SOLVER_PETSC_HH__
 
 
-#include <petscksp.h>
+// #include <petscksp.h>
 
 
-#include "solver.hh"
-#include "static_communicator.hh"
-#include "sparse_matrix.hh"
+// #include "solver.hh"
+// #include "static_communicator.hh"
+// #include "sparse_matrix.hh"
 
-struct Mat;
+// __BEGIN_AKANTU__
 
-__BEGIN_AKANTU__
 
 
-
-struct SolverPETSc : public Solver, public CommunicatorEventHandler {
+// struct SolverPETSc : public Solver, public CommunicatorEventHandler {
   
-  typedef double value_type;
-  typedef sparse_vector<value_type> sparse_vector_type;
-  typedef SparseMatrix sparse_matrix_type;
+//   typedef double value_type;
+//   typedef sparse_vector<value_type> sparse_vector_type;
+//   typedef SparseMatrix sparse_matrix_type;
   
-  Mat A_;                //!< linear system matrix
-  Vec x_;                //!< Solution vector
-  KSP ksp_;              //!< linear solver context
+//   Mat A_;                //!< linear system matrix
+//   Vec x_;                //!< Solution vector
+//   KSP ksp_;              //!< linear solver context
   
-  bool allocated_;
+//   bool allocated_;
   
-  SolverPETSc(int argc, char *argv[]) : allocated_(false) {
+//   SolverPETSc(int argc, char *argv[]) : allocated_(false) {
     
     
-    PetscInitialize(&argc, &argv,NULL,NULL);
-    PetscErrorCode ierr;
+//     PetscInitialize(&argc, &argv,NULL,NULL);
+//     PetscErrorCode ierr;
     
-    // create linear solver context
-    ierr = KSPCreate(PETSC_COMM_WORLD, &ksp_);CHKERRCONTINUE(ierr);
+//     // create linear solver context
+//     ierr = KSPCreate(PETSC_COMM_WORLD, &ksp_);CHKERRCONTINUE(ierr);
     
-    // initial nonzero guess
-    ierr = KSPSetInitialGuessNonzero(ksp_,PETSC_TRUE); CHKERRCONTINUE(ierr);
+//     // initial nonzero guess
+//     ierr = KSPSetInitialGuessNonzero(ksp_,PETSC_TRUE); CHKERRCONTINUE(ierr);
     
-    // set runtime options
-    ierr = KSPSetFromOptions(ksp_);CHKERRCONTINUE(ierr);
+//     // set runtime options
+//     ierr = KSPSetFromOptions(ksp_);CHKERRCONTINUE(ierr);
     
-    /*
-     Set linear solver defaults for this problem (optional).
-     - By extracting the KSP and PC contexts from the KSP context,
-     we can then directly call any KSP and PC routines to set
-     various options.
-     - The following four statements are optional; all of these
-     parameters could alternatively be specified at runtime via
-     KSPSetFromOptions();
-     */
-    //      ierr = KSPGetPC(ksp_,&pc);CHKERRCONTINUE(ierr);
-    //      ierr = PCSetType(pc,PCILU);CHKERRCONTINUE(ierr);
-    //    ierr = PCSetType(pc,PCJACOBI);CHKERRCONTINUE(ierr);
-    ierr = KSPSetTolerances(ksp_,1.e-5,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRCONTINUE(ierr);
-  }
-  
-  //! Overload operator() to solve system of linear equations
-  sparse_vector_type operator()(const sparse_matrix_type& AA, const sparse_vector_type& bb);
-  
-  //! Overload operator() to obtain reaction vector
-  sparse_vector_type operator()(const sparse_matrix_type& Kpf, const sparse_matrix_type& Kpp, const sparse_vector_type& Up);
-  
-  //! Overload operator() to obtain the addition two vectors
-  sparse_vector_type operator()(const sparse_vector_type& aa, const sparse_vector_type& bb);
-  
-  value_type norm(const sparse_matrix_type& aa, Element_insertion_type it = Add_t);
-  
-  value_type norm(const sparse_vector_type& aa, Element_insertion_type it = Add_t);
-  
-  // NOTE: the destructor will return an error if it is called after MPI_Finalize is
-  // called because it uses collect communication to free-up allocated memory.
-  ~SolverPETSc() {
+//     /*
+//      Set linear solver defaults for this problem (optional).
+//      - By extracting the KSP and PC contexts from the KSP context,
+//      we can then directly call any KSP and PC routines to set
+//      various options.
+//      - The following four statements are optional; all of these
+//      parameters could alternatively be specified at runtime via
+//      KSPSetFromOptions();
+//      */
+//     //      ierr = KSPGetPC(ksp_,&pc);CHKERRCONTINUE(ierr);
+//     //      ierr = PCSetType(pc,PCILU);CHKERRCONTINUE(ierr);
+//     //    ierr = PCSetType(pc,PCJACOBI);CHKERRCONTINUE(ierr);
+//     ierr = KSPSetTolerances(ksp_,1.e-5,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRCONTINUE(ierr);
+//   }
+  
+//   //! Overload operator() to solve system of linear equations
+//   sparse_vector_type operator()(const sparse_matrix_type& AA, const sparse_vector_type& bb);
+  
+//   //! Overload operator() to obtain reaction vector
+//   sparse_vector_type operator()(const sparse_matrix_type& Kpf, const sparse_matrix_type& Kpp, const sparse_vector_type& Up);
+  
+//   //! Overload operator() to obtain the addition two vectors
+//   sparse_vector_type operator()(const sparse_vector_type& aa, const sparse_vector_type& bb);
+  
+//   value_type norm(const sparse_matrix_type& aa, Element_insertion_type it = Add_t);
+  
+//   value_type norm(const sparse_vector_type& aa, Element_insertion_type it = Add_t);
+  
+//   // NOTE: the destructor will return an error if it is called after MPI_Finalize is
+//   // called because it uses collect communication to free-up allocated memory.
+//   ~SolverPETSc() {
     
-    static bool exit = false;
-    if (!exit) {
-      // add finalize PETSc function at exit
-      atexit(finalize);
-      exit = true;
-    }
+//     static bool exit = false;
+//     if (!exit) {
+//       // add finalize PETSc function at exit
+//       atexit(finalize);
+//       exit = true;
+//     }
     
-    if (allocated_) {
-      PetscErrorCode ierr = MatDestroy(&A_);CHKERRCONTINUE(ierr);
-      ierr = VecDestroy(&x_);CHKERRCONTINUE(ierr);
-      ierr = KSPDestroy(&ksp_);CHKERRCONTINUE(ierr);
-    }
-  }
-  
-  /* from the PETSc library, these are the options that can be passed
-   to the command line
+//     if (allocated_) {
+//       PetscErrorCode ierr = MatDestroy(&A_);CHKERRCONTINUE(ierr);
+//       ierr = VecDestroy(&x_);CHKERRCONTINUE(ierr);
+//       ierr = KSPDestroy(&ksp_);CHKERRCONTINUE(ierr);
+//     }
+//   }
+  
+//   /* from the PETSc library, these are the options that can be passed
+//    to the command line
    
-   Options Database Keys
+//    Options Database Keys
    
-   -options_table	                - Calls PetscOptionsView()
-   -options_left	                - Prints unused options that remain in the database
-   -objects_left                  - Prints list of all objects that have not been freed
-   -mpidump	                    - Calls PetscMPIDump()
-   -malloc_dump	                - Calls PetscMallocDump()
-   -malloc_info	                - Prints total memory usage
-   -malloc_log	                - Prints summary of memory usage
+//    -options_table	                - Calls PetscOptionsView()
+//    -options_left	                - Prints unused options that remain in the database
+//    -objects_left                  - Prints list of all objects that have not been freed
+//    -mpidump	                    - Calls PetscMPIDump()
+//    -malloc_dump	                - Calls PetscMallocDump()
+//    -malloc_info	                - Prints total memory usage
+//    -malloc_log	                - Prints summary of memory usage
    
-   Options Database Keys for Profiling
+//    Options Database Keys for Profiling
    
-   -log_summary [filename]	    - Prints summary of flop and timing information to screen.
-   If the filename is specified the summary is written to the file. See PetscLogView().
-   -log_summary_python [filename]	- Prints data on of flop and timing usage to a file or screen.
-   -log_all [filename]	        - Logs extensive profiling information See PetscLogDump().
-   -log [filename]	            - Logs basic profiline information See PetscLogDump().
-   -log_sync	                    - Log the synchronization in scatters, inner products and norms
-   -log_mpe [filename]            - Creates a logfile viewable by the utility Upshot/Nupshot (in MPICH distribution)
-   */
-  static void finalize() {
+//    -log_summary [filename]	    - Prints summary of flop and timing information to screen.
+//    If the filename is specified the summary is written to the file. See PetscLogView().
+//    -log_summary_python [filename]	- Prints data on of flop and timing usage to a file or screen.
+//    -log_all [filename]	        - Logs extensive profiling information See PetscLogDump().
+//    -log [filename]	            - Logs basic profiline information See PetscLogDump().
+//    -log_sync	                    - Log the synchronization in scatters, inner products and norms
+//    -log_mpe [filename]            - Creates a logfile viewable by the utility Upshot/Nupshot (in MPICH distribution)
+//    */
+//   static void finalize() {
     
-    static bool finalized = false;
-    if (!finalized) {
+//     static bool finalized = false;
+//     if (!finalized) {
       
-      cout<<"*** INFO *** PETSc is finalizing..."<<endl;
+//       cout<<"*** INFO *** PETSc is finalizing..."<<endl;
       
-      // finalize PETSc
-      PetscErrorCode ierr = PetscFinalize();CHKERRCONTINUE(ierr);
-      finalized = true;
+//       // finalize PETSc
+//       PetscErrorCode ierr = PetscFinalize();CHKERRCONTINUE(ierr);
+//       finalized = true;
       
-      cout<<"*** INFO *** Process "<<Parallel_base::rank_<<" is finalizing..."<<endl;
+//       cout<<"*** INFO *** Process "<<Parallel_base::rank_<<" is finalizing..."<<endl;
       
-      // finalize MPI
-      MPI_Finalize();
-    }
-  }
-};
+//       // finalize MPI
+//       MPI_Finalize();
+//     }
+//   }
+// };
 
 
 
 
-class SolverPETSc : public Solver, public CommunicatorEventHandler {
-  /* ------------------------------------------------------------------------ */
-  /* Constructors/Destructors                                                 */
-  /* ------------------------------------------------------------------------ */
-public:
+// class SolverPETSc : public Solver, public CommunicatorEventHandler {
+//   /* ------------------------------------------------------------------------ */
+//   /* Constructors/Destructors                                                 */
+//   /* ------------------------------------------------------------------------ */
+// public:
   
-  SolverPETSc(SparseMatrix & sparse_matrix,
-              const ID & id = "solver_petsc",
-              const MemoryID & memory_id = 0);
+//   SolverPETSc(SparseMatrix & sparse_matrix,
+//               const ID & id = "solver_petsc",
+//               const MemoryID & memory_id = 0);
   
-  virtual SolverPETSc();
+//   virtual SolverPETSc();
   
-  /* ------------------------------------------------------------------------ */
-  /* Methods                                                                  */
-  /* ------------------------------------------------------------------------ */
-public:
+//   /* ------------------------------------------------------------------------ */
+//   /* Methods                                                                  */
+//   /* ------------------------------------------------------------------------ */
+// public:
   
-  /// build the profile and do the analysis part
-  void initialize(SolverOptions & options = _solver_no_options);
+//   /// build the profile and do the analysis part
+//   void initialize(SolverOptions & options = _solver_no_options);
   
-  void initializeSlave(SolverOptions & options = _solver_no_options);
+//   void initializeSlave(SolverOptions & options = _solver_no_options);
   
   
-  /// factorize and solve the system
-  void solve(Array<Real> & solution);
-  void solve();
+//   /// factorize and solve the system
+//   void solve(Array<Real> & solution);
+//   void solve();
   
-  void solveSlave();
+//   void solveSlave();
   
-  virtual void setRHS(Array<Real> & rhs);
+//   virtual void setRHS(Array<Real> & rhs);
   
-  /// function to print the contain of the class
-  //  virtual void printself(std::ostream & stream, int indent = 0) const;
+//   /// function to print the contain of the class
+//   //  virtual void printself(std::ostream & stream, int indent = 0) const;
   
-  virtual void onCommunicatorFinalize(const StaticCommunicator & communicator);
+//   virtual void onCommunicatorFinalize(const StaticCommunicator & communicator);
   
-private:
+// private:
   
-  void destroyMumpsData();
+//   void destroyMumpsData();
   
-  inline Int & icntl(UInt i) {
-    return mumps_data.icntl[i - 1];
-  }
+//   inline Int & icntl(UInt i) {
+//     return mumps_data.icntl[i - 1];
+//   }
   
-  inline Int & info(UInt i) {
-    return mumps_data.info[i - 1];
-  }
+//   inline Int & info(UInt i) {
+//     return mumps_data.info[i - 1];
+//   }
   
-  void initMumpsData(SolverMumpsOptions::ParallelMethod parallel_method);
+//   void initMumpsData(SolverMumpsOptions::ParallelMethod parallel_method);
   
-  /* ------------------------------------------------------------------------ */
-  /* Accessors                                                                */
-  /* ------------------------------------------------------------------------ */
-public:
+//   /* ------------------------------------------------------------------------ */
+//   /* Accessors                                                                */
+//   /* ------------------------------------------------------------------------ */
+// public:
   
-  /* ------------------------------------------------------------------------ */
-  /* Class Members                                                            */
-  /* ------------------------------------------------------------------------ */
-private:
+//   /* ------------------------------------------------------------------------ */
+//   /* Class Members                                                            */
+//   /* ------------------------------------------------------------------------ */
+// private:
   
-  /// mumps data
-  DMUMPS_STRUC_C mumps_data;
+//   /// mumps data
+//   DMUMPS_STRUC_C mumps_data;
   
-  /// specify if the mumps_data are initialized or not
-  bool is_mumps_data_initialized;
+//   /// specify if the mumps_data are initialized or not
+//   bool is_mumps_data_initialized;
   
-  UInt prank;
+//   UInt prank;
   
-  /* ------------------------------------------------------------------------ */
-  /* Local types                                                              */
-  /* ------------------------------------------------------------------------ */
+//   /* ------------------------------------------------------------------------ */
+//   /* Local types                                                              */
+//   /* ------------------------------------------------------------------------ */
 
-private:
-  SolverMumpsOptions::ParallelMethod parallel_method;
-  
-  bool rhs_is_local;
-  
-  enum SolverMumpsJob {
-    _smj_initialize = -1,
-    _smj_analyze = 1,
-    _smj_factorize = 2,
-    _smj_solve = 3,
-    _smj_analyze_factorize = 4,
-    _smj_factorize_solve = 5,
-    _smj_complete = 6, // analyze, factorize, solve
-    _smj_destroy = -2
-  };
-};
+// private:
+//   SolverMumpsOptions::ParallelMethod parallel_method;
+  
+//   bool rhs_is_local;
+  
+//   enum SolverMumpsJob {
+//     _smj_initialize = -1,
+//     _smj_analyze = 1,
+//     _smj_factorize = 2,
+//     _smj_solve = 3,
+//     _smj_analyze_factorize = 4,
+//     _smj_factorize_solve = 5,
+//     _smj_complete = 6, // analyze, factorize, solve
+//     _smj_destroy = -2
+//   };
+// };
 
 
-/* -------------------------------------------------------------------------- */
-/* inline functions                                                           */
-/* -------------------------------------------------------------------------- */
+// /* -------------------------------------------------------------------------- */
+// /* inline functions                                                           */
+// /* -------------------------------------------------------------------------- */
 
-//#include "solver_mumps_inline_impl.cc"
+// //#include "solver_mumps_inline_impl.cc"
 
-/// standard output stream operator
-// inline std::ostream & operator <<(std::ostream & stream, const SolverMumps & _this)
-// {
-//   _this.printself(stream);
-//   return stream;
-// }
+// /// standard output stream operator
+// // inline std::ostream & operator <<(std::ostream & stream, const SolverMumps & _this)
+// // {
+// //   _this.printself(stream);
+// //   return stream;
+// // }
 
 
-__END_AKANTU__
+// __END_AKANTU__
 
-#endif /* __AKANTU_SOLVER_PETSC_HH__ */
+// #endif /* __AKANTU_SOLVER_PETSC_HH__ */
diff --git a/src/solver/sparse_matrix.hh b/src/solver/sparse_matrix.hh
index 6fed15019..21e06031a 100644
--- a/src/solver/sparse_matrix.hh
+++ b/src/solver/sparse_matrix.hh
@@ -1,253 +1,252 @@
 /**
  * @file   sparse_matrix.hh
  *
  * @author Nicolas Richart <nicolas.richart@epfl.ch>
  *
  * @date creation: Mon Dec 13 2010
  * @date last modification: Mon Sep 15 2014
  *
  * @brief  sparse matrix storage class (distributed assembled matrix)
  * This is a COO format (Coordinate List)
  *
  * @section LICENSE
  *
  * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
  * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
  *
  * Akantu is free  software: you can redistribute it and/or  modify it under the
  * terms  of the  GNU Lesser  General Public  License as  published by  the Free
  * Software Foundation, either version 3 of the License, or (at your option) any
  * later version.
  *
  * Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  * A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
  * details.
  *
  * 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_SPARSE_MATRIX_HH__
 #define __AKANTU_SPARSE_MATRIX_HH__
 
 /* -------------------------------------------------------------------------- */
 #include "aka_common.hh"
 #include "mesh.hh"
 
 /* -------------------------------------------------------------------------- */
 #ifndef __INTEL_COMPILER
 namespace std {
   namespace tr1 {
     template<typename a, typename b>
     struct hash< std::pair<a, b> > {
     private:
       const hash<a> ah;
       const hash<b> bh;
     public:
       hash() : ah(), bh() {}
       size_t operator()(const std::pair<a, b> &p) const {
 	size_t seed = ah(p.first);
 	return bh(p.second) + 0x9e3779b9 + (seed<<6) + (seed>>2);
       }
     };
   }
 } // namespaces
 #endif
 
 __BEGIN_AKANTU__
 
 class DOFSynchronizer;
 
 class SparseMatrix : private Memory {
   /* ------------------------------------------------------------------------ */
   /* Constructors/Destructors                                                 */
   /* ------------------------------------------------------------------------ */
 public:
   SparseMatrix(UInt size,
 	       const SparseMatrixType & sparse_matrix_type,
 	       const ID & id = "sparse_matrix",
 	       const MemoryID & memory_id = 0);
 
   SparseMatrix(const SparseMatrix & matrix,
 	       const ID & id = "sparse_matrix",
 	       const MemoryID & memory_id = 0);
 
   virtual ~SparseMatrix();
 
   typedef std::pair<UInt, UInt> KeyCOO;
   typedef unordered_map<KeyCOO, UInt>::type coordinate_list_map;
 
   /* ------------------------------------------------------------------------ */
   /* Methods                                                                  */
   /* ------------------------------------------------------------------------ */
 public:
   /// remove the existing profile
   inline void clearProfile();
   
   /// add a non-zero element
-  UInt addToProfile(UInt i, UInt j);
+  virtual UInt addToProfile(UInt i, UInt j);
 
   /// set the matrix to 0
   inline void clear();
 
   /// assemble a local matrix in the sparse one
   inline void addToMatrix(UInt i, UInt j, Real value);
 
   /// set the size of the matrix
   void resize(UInt size)
   { this->size = size; }
   
-  /// fill the profil of the matrix
   void buildProfile(const Mesh & mesh, const DOFSynchronizer & dof_synchronizer, UInt nb_degree_of_freedom);
 
   /// modify the matrix to "remove" the blocked dof
-  void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
+  virtual void applyBoundary(const Array<bool> & boundary, Real block_val = 1.);
 
 //  /// modify the matrix to "remove" the blocked dof
 //  void applyBoundaryNormal(Array<bool> & boundary_normal, Array<Real> & EulerAngles, Array<Real> & rhs, const Array<Real> & matrix, Array<Real> & rhs_rotated);
 
   /// modify the matrix to "remove" the blocked dof
-  void removeBoundary(const Array<bool> & boundary);
+  virtual void removeBoundary(const Array<bool> & boundary);
 
   /// restore the profile that was before removing the boundaries
-  void restoreProfile();
+  virtual void restoreProfile();
 
   /// save the profil in a file using the MatrixMarket file format
-  void saveProfile(const std::string & filename) const;
+  virtual void saveProfile(const std::string & filename) const;
 
   /// save the matrix in a file using the MatrixMarket file format
-  void saveMatrix(const std::string & filename) const;
+  virtual void saveMatrix(const std::string & filename) const;
 
   /// copy assuming the profile are the same
-  void copyContent(const SparseMatrix & matrix);
+  virtual void copyContent(const SparseMatrix & matrix);
   
   /// copy profile
 //  void copyProfile(const SparseMatrix & matrix);
 
   /// add matrix assuming the profile are the same
-  void add(const SparseMatrix & matrix, Real alpha);
+  virtual void add(const SparseMatrix & matrix, Real alpha);
 
   /// diagonal lumping
-  void lump(Array<Real> & lumped);
+  virtual void lump(Array<Real> & lumped);
 
   /// function to print the contain of the class
   //virtual void printself(std::ostream & stream, int indent = 0) const;
 
-private:
+protected:
   inline KeyCOO key(UInt i, UInt j) const {
     if(sparse_matrix_type == _symmetric && (i > j))
       return std::make_pair(j, i);
 
     return std::make_pair(i, j);
   }
 
 
   /* ------------------------------------------------------------------------ */
   /* Accessors                                                                */
   /* ------------------------------------------------------------------------ */
 public:
   /// return the values at potition i, j
   inline Real operator()(UInt i, UInt j) const;
   inline Real & operator()(UInt i, UInt j);
 
   AKANTU_GET_MACRO(IRN, irn, const Array<Int> &);
 
   AKANTU_GET_MACRO(JCN, jcn, const Array<Int> &);
 
   AKANTU_GET_MACRO(A, a, const Array<Real> &);
 
   AKANTU_GET_MACRO(NbNonZero, nb_non_zero, UInt);
 
   AKANTU_GET_MACRO(Size, size, UInt);
 
   AKANTU_GET_MACRO(SparseMatrixType, sparse_matrix_type, const SparseMatrixType &);
 
   const DOFSynchronizer & getDOFSynchronizer() const {
     AKANTU_DEBUG_ASSERT(dof_synchronizer != NULL,
 			"DOFSynchronizer not initialized in the SparseMatrix!");
     return *dof_synchronizer;
   }
 
 private:
   AKANTU_GET_MACRO(DOFSynchronizerPointer, dof_synchronizer, DOFSynchronizer *);
 
   friend Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat);
   /* ------------------------------------------------------------------------ */
   /* Class Members                                                            */
   /* ------------------------------------------------------------------------ */
-private:
+protected:
   /// id  of the SparseMatrix
   ID id;
 
   /// sparce matrix type
   SparseMatrixType sparse_matrix_type;
 
   /// Mesh corresponding to the profile
   //  const Mesh * mesh;
 
   /// Size of the matrix
   UInt size;
 
   /// number of processors
   UInt nb_proc;
 
   /// number of non zero element
   UInt nb_non_zero;
 
   /// row indexes
   Array<Int> irn;
 
   /// column indexes
   Array<Int> jcn;
 
   /// values : A[k] = Matrix[irn[k]][jcn[k]]
   Array<Real> a;
 
 
   /// saved row indexes
   Array<Int> * irn_save;
 
   /// saved column indexes
   Array<Int> * jcn_save;
 
   /// saved size
   UInt size_save;
 
   /// information to know where to assemble an element in a global sparse matrix
   //  ElementTypeMapArray<UInt> element_to_sparse_profile;
 
   /* map for  (i,j) ->  k correspondence \warning std::map are slow
    *  \todo improve  with hash_map (non standard in stl) or unordered_map (boost or C++0x)
    */
   coordinate_list_map irn_jcn_k;
 
   DOFSynchronizer * dof_synchronizer;
   //  std::map<std::pair<UInt, UInt>, UInt> * irn_jcn_to_k;
 };
 
 
 /* -------------------------------------------------------------------------- */
 /* inline functions                                                           */
 /* -------------------------------------------------------------------------- */
 
 #if defined (AKANTU_INCLUDE_INLINE_IMPL)
 #  include "sparse_matrix_inline_impl.cc"
 #endif
 
 // /// standard output stream operator
 // inline std::ostream & operator <<(std::ostream & stream, const SparseMatrix & _this)
 // {
 //   _this.printself(stream);
 //   return stream;
 // }
 
 Array<Real> & operator*=(Array<Real> & vect, const SparseMatrix & mat);
 
 
 __END_AKANTU__
 
 #endif /* __AKANTU_SPARSE_MATRIX_HH__ */
diff --git a/src/solver/static_solver.cc b/src/solver/static_solver.cc
new file mode 100644
index 000000000..be55b89b2
--- /dev/null
+++ b/src/solver/static_solver.cc
@@ -0,0 +1,102 @@
+/**
+ * @file   static_solver.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date   Wed Jul 30 15:35:01 2014
+ *
+ * @brief  implementation of the static solver
+ *
+ * @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 "static_solver.hh"
+/* -------------------------------------------------------------------------- */
+#ifdef AKANTU_USE_PETSC
+#include <petscsys.h>
+#endif
+
+/* -------------------------------------------------------------------------- */
+
+__BEGIN_AKANTU__
+
+/* -------------------------------------------------------------------------- */
+StaticSolver::~StaticSolver() {
+  --this->nb_references;
+  if(this->nb_references == 0)
+    delete this->static_solver;
+}
+
+/* -------------------------------------------------------------------------- */
+StaticSolver & StaticSolver::getStaticSolver() {
+  if(nb_references == 0)
+    static_solver = new StaticSolver();
+  
+  ++nb_references;
+  
+  return *static_solver;
+}
+
+#ifdef AKANTU_USE_PETSC
+#if PETSC_VERSION_MAJOR >= 3 && PETSC_VERSION_MINOR >= 5
+static PetscErrorCode PETScErrorHandler(MPI_Comm,
+					int line, const char * dir, const char *file,
+					PetscErrorCode number,
+					PetscErrorType type,
+					const char *message,
+					void *) {
+  AKANTU_DEBUG_ERROR("An error occured in PETSc in file \"" << file << ":" << line << "\" - PetscErrorCode "<< number << " - \""<< message << "\"");
+}
+#else
+static PetscErrorCode PETScErrorHandler(MPI_Comm,
+					int line, const char * func, const char * dir, const char *file,
+					PetscErrorCode number,
+					PetscErrorType type,
+					const char *message,
+					void *) {
+  AKANTU_DEBUG_ERROR("An error occured in PETSc in file \"" << file << ":" << line << "\" - PetscErrorCode "<< number << " - \""<< message << "\"");
+}
+#endif
+#endif
+
+/* -------------------------------------------------------------------------- */
+void StaticSolver::initialize(int & argc, char ** & argv) {
+  AKANTU_DEBUG_ASSERT(this->is_initialized != true, "The static solver has already been initialized");
+#ifdef AKANTU_USE_PETSC
+    PetscErrorCode petsc_error = PetscInitialize(&argc, &argv, NULL, NULL);
+    if(petsc_error != 0) {
+      AKANTU_DEBUG_ERROR("An error occured while initializing Petsc (PetscErrorCode "<< petsc_error << ")");
+    }
+    PetscPushErrorHandler(PETScErrorHandler, NULL);
+#endif
+
+    this->is_initialized = true;
+  }
+
+/* -------------------------------------------------------------------------- */
+void StaticSolver::finalize() {
+  AKANTU_DEBUG_ASSERT(this->is_initialized == true, "The static solver has not been initialized");
+#ifdef AKANTU_USE_PETSC
+  PetscFinalize();
+#endif
+
+  this->is_initialized = false;
+}
+
+__END_AKANTU__
diff --git a/src/solver/static_solver.hh b/src/solver/static_solver.hh
new file mode 100644
index 000000000..add789674
--- /dev/null
+++ b/src/solver/static_solver.hh
@@ -0,0 +1,73 @@
+/**
+ * @file   static_solver.hh
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date   Wed Jul 30 14:44:12 2014
+ *
+ * @brief  Class handeling the initialization of external solvers
+ *
+ * @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"
+
+
+#ifndef __AKANTU_STATIC_SOLVER_HH__
+#define __AKANTU_STATIC_SOLVER_HH__
+
+__BEGIN_AKANTU__
+
+class StaticSolver {
+  /* ------------------------------------------------------------------------ */
+  /* Constructors                                                             */
+  /* ------------------------------------------------------------------------ */
+private:
+  StaticSolver() : is_initialized(false) {};
+
+public:
+  ~StaticSolver();
+
+  /* ------------------------------------------------------------------------ */
+  /// get an instance to the static solver
+  static StaticSolver & getStaticSolver();
+
+  /* ------------------------------------------------------------------------ */
+  /* Methods                                                                  */
+  /* ------------------------------------------------------------------------ */
+public:  
+  /// initialize what is needed for the compiled solver interfaces
+  void initialize(int & argc, char ** & argv);
+
+  /// finalize what is needed for the compiled solver interfaces
+  void finalize();
+
+  /* ------------------------------------------------------------------------ */
+  /* Members                                                                  */
+  /* ------------------------------------------------------------------------ */
+private:
+  bool is_initialized;
+  static UInt nb_references;
+  static StaticSolver * static_solver;
+};
+
+__END_AKANTU__
+
+
+#endif /* __AKANTU_STATIC_SOLVER_HH__ */
diff --git a/test/test_solver/CMakeLists.txt b/test/test_solver/CMakeLists.txt
index 9f4b59df5..42f17633c 100644
--- a/test/test_solver/CMakeLists.txt
+++ b/test/test_solver/CMakeLists.txt
@@ -1,49 +1,54 @@
 #===============================================================================
 # @file   CMakeLists.txt
 #
 # @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
 # @author Nicolas Richart <nicolas.richart@epfl.ch>
 #
 # @date creation: Mon Dec 13 2010
 # @date last modification: Tue Nov 06 2012
 #
 # @brief  configuration for solver tests
 #
 # @section LICENSE
 #
 # Copyright (©) 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne)
 # Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
 #
 # Akantu is free  software: you can redistribute it and/or  modify it under the
 # terms  of the  GNU Lesser  General Public  License as  published by  the Free
 # Software Foundation, either version 3 of the License, or (at your option) any
 # later version.
 #
 # Akantu is  distributed in the  hope that it  will be useful, but  WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 # A  PARTICULAR PURPOSE. See  the GNU  Lesser General  Public License  for more
 # details.
 #
 # 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
 #
 #===============================================================================
 
 add_mesh(test_solver_mesh triangle.geo 2 1)
 
 register_test(test_sparse_matrix_profile
   SOURCES test_sparse_matrix_profile.cc
   DEPENDENCIES test_solver_mesh
   )
 
 register_test(test_sparse_matrix_assemble
   SOURCES test_sparse_matrix_assemble.cc
   DEPENDENCIES test_solver_mesh
   )
 
 register_test(test_sparse_matrix_product
   SOURCES test_sparse_matrix_product.cc
   FILES_TO_COPY bar.msh
   )
+
+register_test(test_petsc_matrix_profile
+  SOURCES test_petsc_matrix_profile.cc
+  DEPENDENCIES test_solver_mesh
+  )
\ No newline at end of file
diff --git a/test/test_solver/test_petsc_matrix_profile.cc b/test/test_solver/test_petsc_matrix_profile.cc
new file mode 100644
index 000000000..22c0e90d6
--- /dev/null
+++ b/test/test_solver/test_petsc_matrix_profile.cc
@@ -0,0 +1,75 @@
+/**
+ * @file   test_petsc_matrix_profile.cc
+ * @author Aurelia Cuba Ramos <aurelia.cubaramos@epfl.ch>
+ * @date   Wed Jul 30 12:34:08 2014
+ *
+ * @brief  test the profile generation of the PETScMatrix 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/>.
+ *
+ */
+
+/* -------------------------------------------------------------------------- */
+#include <cstdlib>
+/* -------------------------------------------------------------------------- */
+#include "static_communicator.hh"
+#include "aka_common.hh"
+#include "mesh.hh"
+#include "mesh_io.hh"
+
+#include "petsc_matrix.hh"
+#include "dof_synchronizer.hh"
+
+#include "mesh_partition_scotch.hh"
+
+using namespace akantu;
+int main(int argc, char *argv[]) {
+
+  initialize(argc, argv);
+  UInt spatial_dimension = 2;
+
+  StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator();
+  Int psize = comm.getNbProc();
+  Int prank = comm.whoAmI();
+
+  /// read the mesh and partition it
+  Mesh mesh(spatial_dimension);
+  akantu::MeshPartition * partition = NULL;
+
+  if(prank == 0) {
+    /// creation mesh
+    mesh.read("triangle.msh");
+    partition = new MeshPartitionScotch(mesh, spatial_dimension);
+    partition->partitionate(psize);
+  }
+
+  
+  DOFSynchronizer dof_synchronizer(mesh, spatial_dimension);
+  UInt nb_global_nodes = mesh.getNbGlobalNodes();
+
+  PETScMatrix petsc_matrix(nb_global_nodes * spatial_dimension, _symmetric);
+  
+  dof_synchronizer.initGlobalDOFEquationNumbers();
+
+  petsc_matrix.resize(dof_synchronizer);
+  petsc_matrix.buildProfile(mesh, dof_synchronizer, spatial_dimension);
+
+  petsc_matrix.saveMatrix("profile.mtx");
+
+}