[getfem] 03/11: New upstream version 5.2+dfsg1

Anton Gladky gladk at moszumanska.debian.org
Mon Aug 14 22:09:49 UTC 2017


This is an automated email from the git hooks/post-receive script.

gladk pushed a commit to annotated tag debian/5.2+dfsg1-1
in repository getfem.

commit 9388eb9aa38f8266907da58f7c5144c30a0cf2d8
Author: Anton Gladky <gladk at debian.org>
Date:   Mon Aug 14 21:25:39 2017 +0200

    New upstream version 5.2+dfsg1
---
 COPYING                                            |    9 +-
 ChangeLog                                          |   21 +
 GNU_FDL_V3                                         |  451 ++
 GNU_GCC_RUNTIME_EXCEPTION                          |   73 +
 GNU_GPL_V3                                         |  674 +++
 GNU_LGPL_V3                                        |  165 +
 INSTALL                                            |   27 +
 Makefile.am                                        |   20 +-
 Makefile.in                                        |   76 +-
 NEWS                                               |   18 +
 README                                             |   28 +
 aclocal.m4                                         |   67 +-
 bin/Makefile.am                                    |   20 +-
 bin/Makefile.in                                    |   44 +-
 bin/ansys2getfem_mesh                              |    4 +-
 bin/createmp                                       |    4 +-
 bin/extract_doc                                    |  715 +--
 bin/fig2eps                                        |    2 +-
 bin/mesh_matlab_to_getfem                          |    4 +-
 bin/split_cmdref                                   |    4 +-
 config.guess                                       |  233 +-
 config.h.in                                        |    6 +-
 config.sub                                         |   60 +-
 configure.ac                                       |  173 +-
 contrib/Makefile.am                                |   19 +-
 contrib/Makefile.in                                |   46 +-
 contrib/aposteriori/Makefile.am                    |   17 +
 contrib/aposteriori/Makefile.in                    |   48 +-
 contrib/aposteriori/aposteriori.cc                 |    5 +-
 contrib/aposteriori/aposteriori.param              |   16 +
 contrib/aposteriori/aposteriori.pl                 |    2 +-
 contrib/aposteriori/aposteriori_laplacian.cc       |    2 +-
 contrib/aposteriori/aposteriori_laplacian.param    |   16 +
 contrib/aposteriori/aposteriori_laplacian.pl       |    2 +-
 contrib/bimaterial_crack_test/Makefile.am          |   17 +
 contrib/bimaterial_crack_test/Makefile.in          |   48 +-
 .../bimaterial_crack_test/bimaterial_crack_test.cc |    2 +-
 .../bimaterial_crack_test.param                    |   16 +
 .../bimaterial_crack_test/bimaterial_crack_test.pl |    2 +-
 contrib/bimaterial_crack_test/crack.cc             |    2 +-
 contrib/bimaterial_crack_test/crack.param          |   16 +
 contrib/bimaterial_crack_test/crack.pl             |    2 +-
 .../bimaterial_crack_test/crack_exact_solution.cc  |    2 +-
 .../bimaterial_crack_test/crack_exact_solution.h   |    2 +-
 contrib/bimaterial_crack_test/getfem_Xfem.cc       |    2 +-
 contrib/bimaterial_crack_test/getfem_Xfem.h        |    2 +-
 contrib/bimaterial_crack_test/getfem_spider_fem.h  |    2 +-
 contrib/crack_plate/Makefile.am                    |   17 +
 contrib/crack_plate/Makefile.in                    |   48 +-
 contrib/crack_plate/crack_bilaplacian.cc           |    2 +-
 contrib/crack_plate/crack_bilaplacian.h            |    2 +-
 contrib/crack_plate/crack_bilaplacian.param        |   16 +
 contrib/crack_plate/crack_bilaplacian_mixed.param  |   16 +
 contrib/crack_plate/crack_bilaplacian_moment.cc    |    5 +-
 contrib/crack_plate/crack_bilaplacian_problem.cc   |   10 +-
 contrib/crack_plate/crack_bilaplacian_sif.cc       |    2 +-
 .../crack_plate/crack_bilaplacian_singularities.cc |    2 +-
 contrib/crack_plate/crack_bilaplacian_tools.cc     |   20 +-
 contrib/crack_plate/crack_mindlin.cc               |   15 +-
 contrib/crack_plate/crack_mindlin.param            |   16 +
 contrib/crack_plate/crack_mindlin.pl               |    2 +-
 contrib/delaminated_crack/Makefile.am              |   17 +
 contrib/delaminated_crack/Makefile.in              |   48 +-
 contrib/delaminated_crack/delaminated_crack.cc     |    2 +-
 contrib/delaminated_crack/delaminated_crack.param  |   16 +
 contrib/delaminated_crack/delaminated_crack.pl     |    2 +-
 contrib/icare/Makefile.am                          |   17 +
 contrib/icare/Makefile.in                          |   48 +-
 contrib/icare/icare.cc                             |    2 +-
 contrib/icare/icare.h                              |    2 +-
 contrib/icare/icare.param                          |   16 +
 contrib/icare/icare.pl                             |    2 +-
 contrib/icare/navier_stokes_cylinder1.mesh         |   16 +
 contrib/icare/navier_stokes_cylinder2.mesh         |   16 +
 contrib/level_set_contact/Makefile.am              |   17 +
 contrib/level_set_contact/Makefile.in              |   48 +-
 contrib/level_set_contact/contact_2D.param         |  118 +-
 contrib/level_set_contact/contact_3D.param         |   16 +
 contrib/level_set_contact/contact_problem.cpp      |  236 +-
 contrib/level_set_contact/contact_problem.h        |   54 +-
 contrib/level_set_contact/contact_problem.pl       |    2 +-
 contrib/level_set_contact/test_contact.cpp         |    2 +-
 contrib/mixed_elastostatic/Makefile.am             |   17 +
 contrib/mixed_elastostatic/Makefile.in             |   48 +-
 contrib/mixed_elastostatic/mixed_elastostatic.cc   |   23 +-
 .../mixed_elastostatic/mixed_elastostatic.param    |   16 +
 contrib/mixed_elastostatic/mixed_elastostatic.pl   |    2 +-
 contrib/opt_assembly/Makefile.am                   |   32 +
 .../Makefile.in                                    |   89 +-
 contrib/opt_assembly/opt_assembly.cc               |  782 ++++
 .../opt_assembly.pl}                               |    2 +-
 contrib/static_contact_gears/Makefile.am           |   17 +
 contrib/static_contact_gears/Makefile.in           |   48 +-
 contrib/static_contact_gears/gear1.msh             |   18 +
 contrib/static_contact_gears/gear1_2D.msh          |   18 +
 contrib/static_contact_gears/gear1_2teeth.msh      |   18 +
 contrib/static_contact_gears/gear2.msh             |   18 +
 contrib/static_contact_gears/gear2_2D.msh          |   18 +
 contrib/static_contact_gears/gear2_2teeth.msh      |   18 +
 .../static_contact_gears/static_contact_gears.cc   |    2 +-
 .../static_contact_gears.param                     |   16 +
 .../static_contact_gears/static_contact_gears.pl   |    2 +-
 .../static_contact_gears_2D.param                  |   16 +
 .../static_contact_gears_2teeth.param              |   16 +
 .../static_contact_gears_u1_u2.cc                  |    2 +-
 .../static_contact_planetary_1.msh                 |   18 +
 .../static_contact_planetary_2.msh                 |   18 +
 .../static_contact_planetary_3.msh                 |   18 +
 .../static_contact_planetary_4.msh                 |   18 +
 .../static_contact_planetary_5.msh                 |   18 +
 contrib/test_plasticity/Makefile.am                |   24 +-
 contrib/test_plasticity/Makefile.in                |   55 +-
 contrib/test_plasticity/test_plasticity.py         |    8 +-
 contrib/xfem_contact/Makefile.am                   |   17 +
 contrib/xfem_contact/Makefile.in                   |   48 +-
 contrib/xfem_contact/xfem_contact.cc               |    2 +-
 contrib/xfem_contact/xfem_contact.param            |   16 +
 contrib/xfem_contact/xfem_contact.pl               |    2 +-
 contrib/xfem_contact/xfem_dirichlet.cc             |    4 +-
 contrib/xfem_contact/xfem_dirichlet.param          |   16 +
 contrib/xfem_contact/xfem_stokes.cc                |    2 +-
 contrib/xfem_contact/xfem_stokes.param             |  166 +-
 contrib/xfem_stab_unilat_contact/Makefile.am       |   17 +
 contrib/xfem_stab_unilat_contact/Makefile.in       |   48 +-
 .../xfem_stab_unilat_contact.cc                    |    2 +-
 .../xfem_stab_unilat_contact.param                 |   16 +
 .../xfem_stab_unilat_contact.pl                    |    2 +-
 cubature/CUBE4D_5.IM                               |   16 +
 cubature/CUBE4D_9.IM                               |   16 +
 cubature/GAUSSLOBATTO1D1.IM                        |   16 +
 cubature/GAUSSLOBATTO1D11.IM                       |   16 +
 cubature/GAUSSLOBATTO1D13.IM                       |   16 +
 cubature/GAUSSLOBATTO1D15.IM                       |   16 +
 cubature/GAUSSLOBATTO1D17.IM                       |   16 +
 cubature/GAUSSLOBATTO1D19.IM                       |   16 +
 cubature/GAUSSLOBATTO1D21.IM                       |   16 +
 cubature/GAUSSLOBATTO1D23.IM                       |   16 +
 cubature/GAUSSLOBATTO1D25.IM                       |   16 +
 cubature/GAUSSLOBATTO1D27.IM                       |   16 +
 cubature/GAUSSLOBATTO1D29.IM                       |   16 +
 cubature/GAUSSLOBATTO1D3.IM                        |   16 +
 cubature/GAUSSLOBATTO1D31.IM                       |   16 +
 cubature/GAUSSLOBATTO1D33.IM                       |   16 +
 cubature/GAUSSLOBATTO1D35.IM                       |   16 +
 cubature/GAUSSLOBATTO1D37.IM                       |   16 +
 cubature/GAUSSLOBATTO1D39.IM                       |   16 +
 cubature/GAUSSLOBATTO1D41.IM                       |   16 +
 cubature/GAUSSLOBATTO1D43.IM                       |   16 +
 cubature/GAUSSLOBATTO1D45.IM                       |   16 +
 cubature/GAUSSLOBATTO1D47.IM                       |   16 +
 cubature/GAUSSLOBATTO1D49.IM                       |   16 +
 cubature/GAUSSLOBATTO1D5.IM                        |   16 +
 cubature/GAUSSLOBATTO1D51.IM                       |   16 +
 cubature/GAUSSLOBATTO1D53.IM                       |   16 +
 cubature/GAUSSLOBATTO1D55.IM                       |   16 +
 cubature/GAUSSLOBATTO1D57.IM                       |   16 +
 cubature/GAUSSLOBATTO1D59.IM                       |   16 +
 cubature/GAUSSLOBATTO1D61.IM                       |   16 +
 cubature/GAUSSLOBATTO1D63.IM                       |   16 +
 cubature/GAUSSLOBATTO1D65.IM                       |   16 +
 cubature/GAUSSLOBATTO1D67.IM                       |   16 +
 cubature/GAUSSLOBATTO1D69.IM                       |   16 +
 cubature/GAUSSLOBATTO1D7.IM                        |   16 +
 cubature/GAUSSLOBATTO1D71.IM                       |   16 +
 cubature/GAUSSLOBATTO1D73.IM                       |   16 +
 cubature/GAUSSLOBATTO1D75.IM                       |   16 +
 cubature/GAUSSLOBATTO1D77.IM                       |   16 +
 cubature/GAUSSLOBATTO1D79.IM                       |   16 +
 cubature/GAUSSLOBATTO1D81.IM                       |   16 +
 cubature/GAUSSLOBATTO1D83.IM                       |   16 +
 cubature/GAUSSLOBATTO1D85.IM                       |   16 +
 cubature/GAUSSLOBATTO1D87.IM                       |   16 +
 cubature/GAUSSLOBATTO1D89.IM                       |   16 +
 cubature/GAUSSLOBATTO1D9.IM                        |   16 +
 cubature/GAUSSLOBATTO1D91.IM                       |   16 +
 cubature/GAUSSLOBATTO1D93.IM                       |   16 +
 cubature/GAUSSLOBATTO1D95.IM                       |   16 +
 cubature/GAUSSLOBATTO1D97.IM                       |   16 +
 cubature/GAUSSLOBATTO1D99.IM                       |   16 +
 cubature/Gauss1D1.IM                               |   16 +
 cubature/Gauss1D11.IM                              |   16 +
 cubature/Gauss1D13.IM                              |   16 +
 cubature/Gauss1D15.IM                              |   16 +
 cubature/Gauss1D17.IM                              |   16 +
 cubature/Gauss1D19.IM                              |   16 +
 cubature/Gauss1D21.IM                              |   16 +
 cubature/Gauss1D23.IM                              |   16 +
 cubature/Gauss1D25.IM                              |   16 +
 cubature/Gauss1D27.IM                              |   16 +
 cubature/Gauss1D29.IM                              |   16 +
 cubature/Gauss1D3.IM                               |   16 +
 cubature/Gauss1D31.IM                              |   16 +
 cubature/Gauss1D33.IM                              |   16 +
 cubature/Gauss1D35.IM                              |   16 +
 cubature/Gauss1D37.IM                              |   16 +
 cubature/Gauss1D39.IM                              |   16 +
 cubature/Gauss1D41.IM                              |   16 +
 cubature/Gauss1D43.IM                              |   16 +
 cubature/Gauss1D45.IM                              |   16 +
 cubature/Gauss1D47.IM                              |   16 +
 cubature/Gauss1D49.IM                              |   16 +
 cubature/Gauss1D5.IM                               |   16 +
 cubature/Gauss1D51.IM                              |   16 +
 cubature/Gauss1D53.IM                              |   16 +
 cubature/Gauss1D55.IM                              |   16 +
 cubature/Gauss1D57.IM                              |   16 +
 cubature/Gauss1D59.IM                              |   16 +
 cubature/Gauss1D61.IM                              |   16 +
 cubature/Gauss1D63.IM                              |   16 +
 cubature/Gauss1D65.IM                              |   16 +
 cubature/Gauss1D67.IM                              |   16 +
 cubature/Gauss1D69.IM                              |   16 +
 cubature/Gauss1D7.IM                               |   16 +
 cubature/Gauss1D71.IM                              |   16 +
 cubature/Gauss1D73.IM                              |   16 +
 cubature/Gauss1D75.IM                              |   16 +
 cubature/Gauss1D77.IM                              |   16 +
 cubature/Gauss1D79.IM                              |   16 +
 cubature/Gauss1D81.IM                              |   16 +
 cubature/Gauss1D83.IM                              |   16 +
 cubature/Gauss1D85.IM                              |   16 +
 cubature/Gauss1D87.IM                              |   16 +
 cubature/Gauss1D89.IM                              |   16 +
 cubature/Gauss1D9.IM                               |   16 +
 cubature/Gauss1D91.IM                              |   16 +
 cubature/Gauss1D93.IM                              |   16 +
 cubature/Gauss1D95.IM                              |   16 +
 cubature/Gauss1D97.IM                              |   16 +
 cubature/Gauss1D99.IM                              |   16 +
 cubature/HEXAHEDRON_11.IM                          |   16 +
 cubature/HEXAHEDRON_5.IM                           |   16 +
 cubature/HEXAHEDRON_9.IM                           |   16 +
 cubature/Makefile.am                               |   16 +
 cubature/Makefile.in                               |   44 +-
 cubature/NC_0_0.IM                                 |   16 +
 cubature/QUAD_17.IM                                |   16 +
 cubature/QUAD_2.IM                                 |   16 +
 cubature/QUAD_3.IM                                 |   16 +
 cubature/QUAD_5.IM                                 |   16 +
 cubature/QUAD_7.IM                                 |   16 +
 cubature/QUAD_9.IM                                 |   16 +
 cubature/SIMPLEX4D_3.IM                            |   16 +
 cubature/TETRA_1.IM                                |   16 +
 cubature/TETRA_2.IM                                |   16 +
 cubature/TETRA_3.IM                                |   16 +
 cubature/TETRA_5.IM                                |   16 +
 cubature/TETRA_6.IM                                |   16 +
 cubature/TETRA_8.IM                                |   16 +
 cubature/TRIANGLE_1.IM                             |   16 +
 cubature/TRIANGLE_10.IM                            |   16 +
 cubature/TRIANGLE_13.IM                            |   16 +
 cubature/TRIANGLE_17.IM                            |   16 +
 cubature/TRIANGLE_19.IM                            |   16 +
 cubature/TRIANGLE_2.IM                             |   16 +
 cubature/TRIANGLE_3.IM                             |   16 +
 cubature/TRIANGLE_4.IM                             |   16 +
 cubature/TRIANGLE_5.IM                             |   16 +
 cubature/TRIANGLE_6.IM                             |   16 +
 cubature/TRIANGLE_7.IM                             |   16 +
 cubature/TRIANGLE_8.IM                             |   16 +
 cubature/TRIANGLE_9.IM                             |   16 +
 cubature/getfem_im_list.h                          |    2 +-
 cubature/make_getfem_im_list                       |   19 +-
 doc/Makefile.am                                    |   18 +
 doc/Makefile.in                                    |   44 +-
 doc/sphinx/Makefile.am                             |   21 +-
 doc/sphinx/Makefile.in                             |   46 +-
 doc/sphinx/source/matlab/images/Makefile           |   19 +-
 doc/sphinx/source/project/images/Makefile          |   24 +-
 doc/sphinx/source/python/images/Makefile           |   19 +-
 doc/sphinx/source/scilab/images/Makefile           |   19 +-
 doc/sphinx/source/userdoc/images/Makefile          |   22 +-
 getfem-config-notinstalled.in                      |   18 +
 getfem-config.in                                   |   25 +
 gmm-config.in                                      |   20 +
 install-sh                                         |  373 +-
 interface/Makefile.am                              |   17 +
 interface/Makefile.in                              |   44 +-
 interface/src/Makefile.am                          |   18 +-
 interface/src/Makefile.in                          |   46 +-
 interface/src/getfem_interface.cc                  |    4 +-
 interface/src/getfem_interface.h                   |    2 +-
 interface/src/getfemint.cc                         |    7 +-
 interface/src/getfemint.h                          |    2 +-
 interface/src/getfemint_gsparse.cc                 |   14 +-
 interface/src/getfemint_gsparse.h                  |    2 +-
 interface/src/getfemint_levelset.cc                |    2 +-
 interface/src/getfemint_levelset.h                 |    2 +-
 interface/src/getfemint_misc.cc                    |   10 +-
 interface/src/getfemint_misc.h                     |    2 +-
 interface/src/getfemint_precond.h                  |    2 +-
 interface/src/getfemint_std.h                      |    2 +-
 interface/src/getfemint_workspace.cc               |    4 +-
 interface/src/getfemint_workspace.h                |    6 +-
 interface/src/gf_asm.cc                            |   36 +-
 interface/src/gf_compute.cc                        |   49 +-
 interface/src/gf_cont_struct.cc                    |    2 +-
 interface/src/gf_cont_struct_get.cc                |    6 +-
 interface/src/gf_cvstruct_get.cc                   |    2 +-
 interface/src/gf_delete.cc                         |    2 +-
 interface/src/gf_eltm.cc                           |    2 +-
 interface/src/gf_fem.cc                            |    4 +-
 interface/src/gf_fem_get.cc                        |    2 +-
 interface/src/gf_geotrans.cc                       |    2 +-
 interface/src/gf_geotrans_get.cc                   |    2 +-
 interface/src/gf_global_function.cc                |    4 +-
 interface/src/gf_global_function_get.cc            |    4 +-
 interface/src/gf_integ.cc                          |    2 +-
 interface/src/gf_integ_get.cc                      |    2 +-
 interface/src/gf_levelset.cc                       |    2 +-
 interface/src/gf_levelset_get.cc                   |    2 +-
 interface/src/gf_levelset_set.cc                   |    2 +-
 interface/src/gf_linsolve.cc                       |    2 +-
 interface/src/gf_mesh.cc                           |   89 +-
 interface/src/gf_mesh_fem.cc                       |    2 +-
 interface/src/gf_mesh_fem_get.cc                   |   53 +-
 interface/src/gf_mesh_fem_set.cc                   |    2 +-
 interface/src/gf_mesh_get.cc                       |    4 +-
 interface/src/gf_mesh_im.cc                        |    2 +-
 interface/src/gf_mesh_im_data.cc                   |    2 +-
 interface/src/gf_mesh_im_data_get.cc               |    2 +-
 interface/src/gf_mesh_im_data_set.cc               |    2 +-
 interface/src/gf_mesh_im_get.cc                    |    4 +-
 interface/src/gf_mesh_im_set.cc                    |    2 +-
 interface/src/gf_mesh_levelset.cc                  |    4 +-
 interface/src/gf_mesh_levelset_get.cc              |    4 +-
 interface/src/gf_mesh_levelset_set.cc              |    4 +-
 interface/src/gf_mesh_set.cc                       |   10 +-
 interface/src/gf_mesher_object.cc                  |    2 +-
 interface/src/gf_mesher_object_get.cc              |    2 +-
 interface/src/gf_model.cc                          |    2 +-
 interface/src/gf_model_get.cc                      |  214 +-
 interface/src/gf_model_set.cc                      |  262 +-
 interface/src/gf_precond.cc                        |    2 +-
 interface/src/gf_precond_get.cc                    |    2 +-
 interface/src/gf_slice.cc                          |    4 +-
 interface/src/gf_slice_get.cc                      |    4 +-
 interface/src/gf_slice_set.cc                      |    2 +-
 interface/src/gf_spmat.cc                          |    2 +-
 interface/src/gf_spmat_get.cc                      |    2 +-
 interface/src/gf_spmat_set.cc                      |    5 +-
 interface/src/gf_util.cc                           |    2 +-
 interface/src/gf_workspace.cc                      |    2 +-
 interface/src/gfi_array.c                          |    2 +-
 interface/src/gfi_array.h                          |    2 +-
 interface/src/gfi_rpc.h                            |    2 +-
 interface/src/gfi_rpc_clnt.c                       |    2 +-
 interface/src/gfi_rpc_server.c                     |    2 +-
 interface/src/gfi_rpc_svc.c                        |    2 +-
 interface/src/gfi_rpc_xdr.c                        |    2 +-
 interface/src/matlab/Makefile.am                   |   31 +-
 interface/src/matlab/Makefile.in                   |   56 +-
 interface/src/matlab/gfObject.m                    |   18 +-
 interface/src/matlab/gf_asm_pdetoolbc.m            |   18 +-
 interface/src/matlab/gf_colormap.m                 |   18 +-
 interface/src/matlab/gf_compute_Q1grid_interp.m    |   20 +-
 interface/src/matlab/gf_mesh_fem_get_eval.m        |   16 +
 interface/src/matlab/gf_plot.m                     |   16 +
 interface/src/matlab/gf_plot_1D.m                  |   16 +
 interface/src/matlab/gf_plot_mesh.m                |   21 +-
 interface/src/matlab/gf_plot_slice.m               |   20 +-
 interface/src/matlab/gfm_common.c                  |   12 +-
 interface/src/matlab/private/Makefile.am           |   17 +
 interface/src/matlab/private/Makefile.in           |   44 +-
 interface/src/matlab/private/getopt.m              |   17 +
 interface/src/python/Makefile.am                   |   24 +-
 interface/src/python/Makefile.in                   |   54 +-
 interface/src/python/__init__.py                   |    2 +-
 interface/src/python/getfem.py                     |  279 +-
 interface/src/python/getfem_python.c               |   89 +-
 interface/src/python/setup.py.in                   |   31 +-
 interface/tests/Makefile.am                        |   17 +
 interface/tests/Makefile.in                        |   44 +-
 interface/tests/matlab/Makefile.am                 |   18 +
 interface/tests/matlab/Makefile.in                 |   48 +-
 interface/tests/matlab/axrot_matrix.m              |    2 +-
 interface/tests/matlab/check_all.m                 |    2 +-
 interface/tests/matlab/check_asm.m                 |    2 +-
 interface/tests/matlab/check_fem.m                 |    2 +-
 interface/tests/matlab/check_geotrans.m            |    2 +-
 interface/tests/matlab/check_integ.m               |    2 +-
 interface/tests/matlab/check_mesh_fem.m            |   14 +-
 interface/tests/matlab/check_oo.m                  |    2 +-
 interface/tests/matlab/check_plasticity.m          |    2 +-
 interface/tests/matlab/check_plot.m                |    2 +-
 interface/tests/matlab/check_slices.m              |    2 +-
 interface/tests/matlab/check_spmat.m               |    5 +-
 interface/tests/matlab/check_workspace.m           |    2 +-
 .../tests/matlab/demo_Mindlin_Reissner_plate.m     |    2 +-
 interface/tests/matlab/demo_Navier_Stokes.m        |    2 +-
 .../tests/matlab/demo_Nitsche_contact_by_hand.m    |    2 +-
 interface/tests/matlab/demo_bilaplacian.m          |    2 +-
 .../demo_contact_fictitious_domain_nitsche.m       |    2 +-
 interface/tests/matlab/demo_continuation.m         |    2 +-
 .../tests/matlab/demo_convection_rotating_cavity.m |    2 +-
 interface/tests/matlab/demo_crack.m                |    2 +-
 interface/tests/matlab/demo_dynamic_plasticity.m   |    2 +-
 interface/tests/matlab/demo_elasticity.m           |    2 +-
 interface/tests/matlab/demo_fictitious_domains.m   |    2 +-
 .../matlab/demo_fictitious_domains_laplacian.m     |   10 +-
 interface/tests/matlab/demo_laplacian.m            |    9 +-
 interface/tests/matlab/demo_laplacian_DG.m         |    2 +-
 interface/tests/matlab/demo_laplacian_pyramid.m    |  155 +
 .../tests/matlab/demo_large_sliding_contact.m      |    2 +-
 interface/tests/matlab/demo_mesh_generation.m      |    2 +-
 interface/tests/matlab/demo_mortar.m               |    2 +-
 interface/tests/matlab/demo_nonlinear_elasticity.m |    2 +-
 .../tests/matlab/demo_nonlinear_elasticity_anim.m  |    2 +-
 interface/tests/matlab/demo_periodic_laplacian.m   |    4 +-
 interface/tests/matlab/demo_plasticity.m           |    2 +-
 interface/tests/matlab/demo_refine.m               |    6 +-
 interface/tests/matlab/demo_static_contact.m       |    4 +-
 interface/tests/matlab/demo_step_by_step.m         |    2 +-
 interface/tests/matlab/demo_stokes_3D_tank.m       |    2 +-
 interface/tests/matlab/demo_stokes_3D_tank_draw.m  |    2 +-
 .../tests/matlab/demo_structural_optimization.m    |    2 +-
 .../demo_thermo_elasticity_electrical_coupling.m   |    2 +-
 .../tests/matlab/demo_topological_optimization.m   |    2 +-
 interface/tests/matlab/demo_tripod.m               |    2 +-
 interface/tests/matlab/demo_tripod_alt.m           |    2 +-
 interface/tests/matlab/demo_tripod_slice_anim.m    |    2 +-
 interface/tests/matlab/demo_wave2D.m               |    2 +-
 interface/tests/matlab/demo_wave2D_alt.m           |    2 +-
 interface/tests/matlab/demo_wave_equation.m        |    2 +-
 interface/tests/matlab/demo_wheel_contact.m        |    2 +-
 interface/tests/matlab/private/Makefile.in         |   27 +-
 interface/tests/matlab/private/asserterr.m         |    2 +-
 interface/tests/matlab/private/gfassert.m          |    2 +-
 interface/tests/matlab/test_argyris.m              |    2 +-
 interface/tests/matlab/tripod_anim.m               |    2 +-
 interface/tests/matlab/tutorial1.m                 |    2 +-
 interface/tests/meshes/Makefile.am                 |   17 +
 interface/tests/meshes/Makefile.in                 |   44 +-
 .../holed_disc_with_quadratic_2D_triangles.msh     |    0
 interface/tests/meshes/tank_quadratic_2500.GiD.msh |    0
 interface/tests/meshes/tripod.GiD.msh              |    0
 interface/tests/meshes/tube_2D_spline.GiD.msh      |    0
 interface/tests/python/Makefile.am                 |   30 +-
 interface/tests/python/Makefile.in                 |   64 +-
 interface/tests/python/check_export.py             |    6 +-
 interface/tests/python/check_global_functions.py   |    4 +-
 interface/tests/python/check_levelset.py           |    6 +-
 .../tests/python/demo_Mindlin_Reissner_plate.py    |    2 +-
 interface/tests/python/demo_crack.py               |   10 +-
 interface/tests/python/demo_fictitious_domains.py  |   16 +-
 interface/tests/python/demo_laplacian.py           |   14 +-
 interface/tests/python/demo_laplacian_DG.py        |   16 +-
 .../tests/python/demo_laplacian_aposteriori.py     |  166 +
 ...demo_laplacian.py => demo_laplacian_pyramid.py} |   64 +-
 interface/tests/python/demo_mortar.py              |    2 +-
 .../tests/python/demo_nonlinear_elasticity.py      |    6 +-
 interface/tests/python/demo_plasticity.py          |   12 +-
 interface/tests/python/demo_plate.py               |   18 +-
 interface/tests/python/demo_static_contact.py      |   14 +-
 interface/tests/python/demo_step_by_step.py        |   23 +-
 interface/tests/python/demo_stokes_3D_tank.py      |   16 +-
 interface/tests/python/demo_stokes_3D_tank_draw.py |   10 +-
 .../demo_thermo_elasticity_electrical_coupling.py  |  462 +-
 interface/tests/python/demo_tripod.py              |   30 +-
 interface/tests/python/demo_tripod_alt.py          |   28 +-
 interface/tests/python/demo_wave.py                |   12 +-
 interface/tests/python/demo_wave_equation.py       |    2 +-
 interface/tests/python/demo_wheel_contact.py       |  336 +-
 interface/tests/python/getfem_tvtk.py              |   18 +-
 m4/Makefile.am                                     |   17 +
 m4/Makefile.in                                     |   44 +-
 m4/ac_python_devel.m4                              |   27 +-
 m4/acx_blas.m4                                     |    4 +
 m4/ax_check_cxx_flag.m4                            |   17 +-
 m4/ax_prefix_config_h.m4                           |    5 +-
 m4/libtool.m4                                      | 2521 +++++------
 m4/ltoptions.m4                                    |  127 +-
 m4/ltsugar.m4                                      |    7 +-
 m4/ltversion.m4                                    |   12 +-
 m4/lt~obsolete.m4                                  |    7 +-
 m4/scilab.m4                                       |   15 +
 mkinstalldirs                                      |    2 +-
 src/Makefile.am                                    |   21 +-
 src/Makefile.in                                    |   64 +-
 src/bgeot_convex_ref.cc                            |  142 +-
 src/bgeot_convex_ref_simplexified.cc               |   18 +-
 src/bgeot_convex_structure.cc                      |  121 +-
 src/bgeot_ftool.cc                                 |    2 +-
 src/bgeot_geometric_trans.cc                       |  554 ++-
 src/bgeot_geotrans_inv.cc                          |   10 +-
 src/bgeot_kdtree.cc                                |    2 +-
 src/bgeot_mesh_structure.cc                        |    2 +-
 src/bgeot_node_tab.cc                              |    5 +-
 src/bgeot_poly.cc                                  |    8 +-
 src/bgeot_poly_composite.cc                        |    8 +-
 src/bgeot_rtree.cc                                 |    5 +-
 src/bgeot_small_vector.cc                          |    2 +-
 src/bgeot_sparse_tensors.cc                        |    8 +-
 src/dal_backtrace.cc                               |    2 +-
 src/dal_bit_vector.cc                              |    5 +-
 src/dal_singleton.cc                               |    2 +-
 src/dal_static_stored_objects.cc                   |   65 +-
 src/getfem/bgeot_comma_init.h                      |    2 +-
 src/getfem/bgeot_config.h                          |    4 +-
 src/getfem/bgeot_convex.h                          |    5 +-
 src/getfem/bgeot_convex_ref.h                      |    6 +-
 src/getfem/bgeot_convex_structure.h                |    7 +-
 src/getfem/bgeot_ftool.h                           |    2 +-
 src/getfem/bgeot_geometric_trans.h                 |  101 +-
 src/getfem/bgeot_geotrans_inv.h                    |    2 +-
 src/getfem/bgeot_kdtree.h                          |    2 +-
 src/getfem/bgeot_mesh.h                            |   45 +-
 src/getfem/bgeot_mesh_structure.h                  |   16 +-
 src/getfem/bgeot_node_tab.h                        |    2 +-
 src/getfem/bgeot_permutations.h                    |    2 +-
 src/getfem/bgeot_poly.h                            |  156 +-
 src/getfem/bgeot_poly_composite.h                  |   13 +-
 src/getfem/bgeot_rtree.h                           |    2 +-
 src/getfem/bgeot_small_vector.h                    |    8 +-
 src/getfem/bgeot_sparse_tensors.h                  |    2 +-
 src/getfem/bgeot_tensor.h                          |  110 +-
 src/getfem/dal_backtrace.h                         |    2 +-
 src/getfem/dal_basic.h                             |    2 +-
 src/getfem/dal_bit_vector.h                        |    2 +-
 src/getfem/dal_config.h                            |    2 +-
 src/getfem/dal_naming_system.h                     |    2 +-
 src/getfem/dal_singleton.h                         |    2 +-
 src/getfem/dal_static_stored_objects.h             |   26 +-
 src/getfem/dal_tas.h                               |    2 +-
 src/getfem/dal_tree_sorted.h                       |   92 +-
 src/getfem/getfem_Navier_Stokes.h                  |    2 +-
 src/getfem/getfem_arch_config.h                    |   14 +-
 src/getfem/getfem_assembling.h                     | 1700 +++----
 src/getfem/getfem_assembling_tensors.h             |    3 +-
 src/getfem/getfem_config.h                         |    4 +-
 src/getfem/getfem_contact_and_friction_common.h    |   72 +-
 src/getfem/getfem_contact_and_friction_integral.h  |    2 +-
 .../getfem_contact_and_friction_large_sliding.h    |   60 +-
 src/getfem/getfem_contact_and_friction_nodal.h     |    2 +-
 src/getfem/getfem_context.h                        |   16 +-
 src/getfem/getfem_continuation.h                   |   74 +-
 src/getfem/getfem_convect.h                        |    2 +-
 src/getfem/getfem_copyable_ptr.h                   |    2 +-
 src/getfem/getfem_crack_sif.h                      |    2 +-
 src/getfem/getfem_deformable_mesh.h                |  289 +-
 src/getfem/getfem_derivatives.h                    |    2 +-
 src/getfem/getfem_error_estimate.h                 |    4 +-
 src/getfem/getfem_export.h                         |   24 +-
 src/getfem/getfem_fem.h                            |  117 +-
 src/getfem/getfem_fem_global_function.h            |   17 +-
 src/getfem/getfem_fem_level_set.h                  |    2 +-
 src/getfem/getfem_fourth_order.h                   |   82 +-
 src/getfem/getfem_generic_assembly.h               |  188 +-
 src/getfem/getfem_global_function.h                |   11 +-
 src/getfem/getfem_im_data.h                        |  774 ++--
 src/getfem/getfem_im_list.h                        |    2 +-
 src/getfem/getfem_import.h                         |   15 +-
 src/getfem/getfem_integration.h                    |    9 +-
 src/getfem/getfem_interpolated_fem.h               |    2 +-
 src/getfem/getfem_interpolation.h                  |   47 +-
 src/getfem/getfem_level_set.h                      |    2 +-
 src/getfem/getfem_level_set_contact.h              |    2 +-
 src/getfem/getfem_linearized_plates.h              |    2 +-
 src/getfem/getfem_mat_elem.h                       |    2 +-
 src/getfem/getfem_mat_elem_type.h                  |    2 +-
 src/getfem/getfem_mesh.h                           |   73 +-
 src/getfem/getfem_mesh_fem.h                       |  107 +-
 src/getfem/getfem_mesh_fem_global_function.h       |    2 +-
 src/getfem/getfem_mesh_fem_level_set.h             |    2 +-
 src/getfem/getfem_mesh_fem_product.h               |    2 +-
 src/getfem/getfem_mesh_fem_sum.h                   |    2 +-
 src/getfem/getfem_mesh_im.h                        |    2 +-
 src/getfem/getfem_mesh_im_level_set.h              |    2 +-
 src/getfem/getfem_mesh_level_set.h                 |    2 +-
 src/getfem/getfem_mesh_region.h                    |   41 +-
 src/getfem/getfem_mesh_slice.h                     |   16 +-
 src/getfem/getfem_mesh_slicers.h                   |    2 +-
 src/getfem/getfem_mesher.h                         |   56 +-
 src/getfem/getfem_model_solvers.h                  |   15 +-
 src/getfem/getfem_models.h                         |  283 +-
 src/getfem/getfem_nonlinear_elasticity.h           |    2 +-
 src/getfem/getfem_omp.h                            |   17 +-
 src/getfem/getfem_partial_mesh_fem.h               |   10 +-
 src/getfem/getfem_plasticity.h                     |    2 +-
 src/getfem/getfem_projected_fem.h                  |    2 +-
 src/getfem/getfem_regular_meshes.h                 |   18 +-
 src/getfem/getfem_superlu.h                        |    2 +-
 src/getfem/getfem_torus.h                          |  232 +-
 src/getfem_assembling_tensors.cc                   |   31 +-
 src/getfem_boost/workaround.hpp                    |    0
 src/getfem_contact_and_friction_common.cc          |  556 ++-
 src/getfem_contact_and_friction_integral.cc        |   14 +-
 src/getfem_contact_and_friction_large_sliding.cc   |  343 +-
 src/getfem_contact_and_friction_nodal.cc           |   18 +-
 src/getfem_context.cc                              |    8 +-
 src/getfem_continuation.cc                         |    4 +-
 src/getfem_error_estimate.cc                       |   10 +-
 src/getfem_export.cc                               |   72 +-
 src/getfem_fem.cc                                  |  442 +-
 src/getfem_fem_composite.cc                        |    9 +-
 src/getfem_fem_global_function.cc                  |  106 +-
 src/getfem_fem_level_set.cc                        |   29 +-
 src/getfem_fourth_order.cc                         |   24 +-
 src/getfem_generic_assembly.cc                     | 4742 +++++++++++++++-----
 src/getfem_global_function.cc                      |   73 +-
 src/getfem_im_data.cc                              |    2 +-
 src/getfem_import.cc                               |  129 +-
 src/getfem_integration.cc                          |  162 +-
 src/getfem_integration_composite.cc                |   36 +-
 src/getfem_interpolated_fem.cc                     |    9 +-
 src/getfem_interpolation.cc                        |    4 +-
 src/getfem_level_set.cc                            |    2 +-
 src/getfem_level_set_contact.cc                    |    2 +-
 src/getfem_linearized_plates.cc                    |    2 +-
 src/getfem_mat_elem.cc                             |   11 +-
 src/getfem_mat_elem_type.cc                        |   11 +-
 src/getfem_mesh.cc                                 |   70 +-
 src/getfem_mesh_fem.cc                             |   88 +-
 src/getfem_mesh_fem_global_function.cc             |    2 +-
 src/getfem_mesh_fem_level_set.cc                   |    2 +-
 src/getfem_mesh_fem_product.cc                     |   11 +-
 src/getfem_mesh_fem_sum.cc                         |   25 +-
 src/getfem_mesh_im.cc                              |    2 +-
 src/getfem_mesh_im_level_set.cc                    |   30 +-
 src/getfem_mesh_level_set.cc                       |    6 +-
 src/getfem_mesh_region.cc                          |  162 +-
 src/getfem_mesh_slice.cc                           |  272 +-
 src/getfem_mesh_slicers.cc                         |   31 +-
 src/getfem_mesher.cc                               |   12 +-
 src/getfem_model_solvers.cc                        |    2 +-
 src/getfem_models.cc                               | 1032 +----
 src/getfem_nonlinear_elasticity.cc                 |   84 +-
 src/getfem_omp.cc                                  |    2 +-
 src/getfem_partial_mesh_fem.cc                     |    4 +-
 src/getfem_plasticity.cc                           |   88 +-
 src/getfem_projected_fem.cc                        |    6 +-
 src/getfem_regular_meshes.cc                       |   55 +-
 src/getfem_superlu.cc                              |    2 +-
 src/getfem_torus.cc                                |  869 ++--
 src/gmm/gmm.h                                      |    2 +-
 src/gmm/gmm_MUMPS_interface.h                      |    2 +-
 src/gmm/gmm_algobase.h                             |    6 +-
 src/gmm/gmm_blas.h                                 |   40 +-
 src/gmm/gmm_blas_interface.h                       |   37 +-
 src/gmm/gmm_condition_number.h                     |    6 +-
 src/gmm/gmm_conjugated.h                           |  138 +-
 src/gmm/gmm_def.h                                  |   29 +-
 src/gmm/gmm_dense_Householder.h                    |   10 +-
 src/gmm/gmm_dense_lu.h                             |    4 +-
 src/gmm/gmm_dense_matrix_functions.h               |    2 +-
 src/gmm/gmm_dense_qr.h                             |    2 +-
 src/gmm/gmm_dense_sylvester.h                      |    2 +-
 src/gmm/gmm_domain_decomp.h                        |    2 +-
 src/gmm/gmm_except.h                               |   19 +-
 src/gmm/gmm_inoutput.h                             |    2 +-
 src/gmm/gmm_interface.h                            |   16 +-
 src/gmm/gmm_interface_bgeot.h                      |    2 +-
 src/gmm/gmm_iter.h                                 |    2 +-
 src/gmm/gmm_iter_solvers.h                         |    5 +-
 src/gmm/gmm_kernel.h                               |    2 +-
 src/gmm/gmm_lapack_interface.h                     |   17 +-
 src/gmm/gmm_least_squares_cg.h                     |    2 +-
 src/gmm/gmm_matrix.h                               |   23 +-
 src/gmm/gmm_modified_gram_schmidt.h                |    2 +-
 src/gmm/gmm_opt.h                                  |    2 +-
 src/gmm/gmm_precond.h                              |    2 +-
 src/gmm/gmm_precond_diagonal.h                     |    2 +-
 src/gmm/gmm_precond_ildlt.h                        |    4 +-
 src/gmm/gmm_precond_ildltt.h                       |    2 +-
 src/gmm/gmm_precond_ilu.h                          |    4 +-
 src/gmm/gmm_precond_ilut.h                         |    2 +-
 src/gmm/gmm_precond_ilutp.h                        |    2 +-
 src/gmm/gmm_precond_mr_approx_inverse.h            |    2 +-
 src/gmm/gmm_range_basis.h                          |    2 +-
 src/gmm/gmm_real_part.h                            |  332 +-
 src/gmm/gmm_ref.h                                  |    2 +-
 src/gmm/gmm_scaled.h                               |  188 +-
 src/gmm/gmm_solver_Schwarz_additive.h              |    2 +-
 src/gmm/gmm_solver_bfgs.h                          |    2 +-
 src/gmm/gmm_solver_bicgstab.h                      |    2 +-
 src/gmm/gmm_solver_cg.h                            |    2 +-
 src/gmm/gmm_solver_constrained_cg.h                |    2 +-
 src/gmm/gmm_solver_gmres.h                         |    2 +-
 src/gmm/gmm_solver_idgmres.h                       |    2 +-
 src/gmm/gmm_solver_qmr.h                           |    2 +-
 src/gmm/gmm_std.h                                  |    8 +-
 src/gmm/gmm_sub_index.h                            |    2 +-
 src/gmm/gmm_sub_matrix.h                           |   16 +-
 src/gmm/gmm_sub_vector.h                           |    2 +-
 src/gmm/gmm_superlu_interface.h                    |    2 +-
 src/gmm/gmm_transposed.h                           |    6 +-
 src/gmm/gmm_tri_solve.h                            |   34 +-
 src/gmm/gmm_vector.h                               |  560 ++-
 src/gmm/gmm_vector_to_matrix.h                     |    2 +-
 superlu/BLAS.c                                     |   40 +-
 superlu/BLAS/License.txt                           |   14 +
 superlu/BLAS/caxpy.f                               |  102 +
 superlu/BLAS/ccopy.f                               |   94 +
 superlu/BLAS/cdotc.f                               |  103 +
 superlu/BLAS/cdotu.f                               |  100 +
 superlu/BLAS/cgbmv.f                               |  390 ++
 superlu/BLAS/cgemm.f                               |  483 ++
 superlu/BLAS/cgemv.f                               |  350 ++
 superlu/BLAS/cgerc.f                               |  227 +
 superlu/BLAS/cgeru.f                               |  227 +
 superlu/BLAS/chbmv.f                               |  380 ++
 superlu/BLAS/chemm.f                               |  371 ++
 superlu/BLAS/chemv.f                               |  337 ++
 superlu/BLAS/cher.f                                |  278 ++
 superlu/BLAS/cher2.f                               |  317 ++
 superlu/BLAS/cher2k.f                              |  442 ++
 superlu/BLAS/cherk.f                               |  396 ++
 superlu/BLAS/chpmv.f                               |  338 ++
 superlu/BLAS/chpr.f                                |  279 ++
 superlu/BLAS/chpr2.f                               |  318 ++
 superlu/BLAS/crotg.f                               |   74 +
 superlu/BLAS/cscal.f                               |   91 +
 superlu/BLAS/csrot.f                               |  153 +
 superlu/BLAS/csscal.f                              |   94 +
 superlu/BLAS/cswap.f                               |   98 +
 superlu/BLAS/csymm.f                               |  369 ++
 superlu/BLAS/csyr2k.f                              |  396 ++
 superlu/BLAS/csyrk.f                               |  363 ++
 superlu/BLAS/ctbmv.f                               |  429 ++
 superlu/BLAS/ctbsv.f                               |  432 ++
 superlu/BLAS/ctpmv.f                               |  388 ++
 superlu/BLAS/ctpsv.f                               |  390 ++
 superlu/BLAS/ctrmm.f                               |  452 ++
 superlu/BLAS/ctrmv.f                               |  373 ++
 superlu/BLAS/ctrsm.f                               |  477 ++
 superlu/BLAS/ctrsv.f                               |  375 ++
 superlu/BLAS/dasum.f                               |  111 +
 superlu/BLAS/daxpy.f                               |  115 +
 superlu/BLAS/dcabs1.f                              |   58 +
 superlu/BLAS/dcopy.f                               |  115 +
 superlu/BLAS/ddot.f                                |  117 +
 superlu/BLAS/dgbmv.f                               |  370 ++
 superlu/BLAS/dgemm.f                               |  384 ++
 superlu/BLAS/dgemv.f                               |  330 ++
 superlu/BLAS/dger.f                                |  227 +
 superlu/BLAS/dnrm2.f                               |  112 +
 superlu/BLAS/drot.f                                |  101 +
 superlu/BLAS/drotg.f                               |   86 +
 superlu/BLAS/drotm.f                               |  202 +
 superlu/BLAS/drotmg.f                              |  251 ++
 superlu/BLAS/dsbmv.f                               |  375 ++
 superlu/BLAS/dscal.f                               |  110 +
 superlu/BLAS/dsdot.f                               |  172 +
 superlu/BLAS/dspmv.f                               |  331 ++
 superlu/BLAS/dspr.f                                |  261 ++
 superlu/BLAS/dspr2.f                               |  296 ++
 superlu/BLAS/dswap.f                               |  122 +
 superlu/BLAS/dsymm.f                               |  367 ++
 superlu/BLAS/dsymv.f                               |  333 ++
 superlu/BLAS/dsyr.f                                |  263 ++
 superlu/BLAS/dsyr2.f                               |  298 ++
 superlu/BLAS/dsyr2k.f                              |  399 ++
 superlu/BLAS/dsyrk.f                               |  364 ++
 superlu/BLAS/dtbmv.f                               |  398 ++
 superlu/BLAS/dtbsv.f                               |  401 ++
 superlu/BLAS/dtpmv.f                               |  352 ++
 superlu/BLAS/dtpsv.f                               |  354 ++
 superlu/BLAS/dtrmm.f                               |  415 ++
 superlu/BLAS/dtrmv.f                               |  342 ++
 superlu/BLAS/dtrsm.f                               |  443 ++
 superlu/BLAS/dtrsv.f                               |  338 ++
 superlu/BLAS/dzasum.f                              |   98 +
 superlu/BLAS/dznrm2.f                              |  119 +
 superlu/BLAS/icamax.f                              |  107 +
 superlu/BLAS/idamax.f                              |  106 +
 superlu/BLAS/isamax.f                              |  106 +
 superlu/BLAS/izamax.f                              |  107 +
 superlu/BLAS/lsame.f                               |  125 +
 superlu/BLAS/sasum.f                               |  112 +
 superlu/BLAS/saxpy.f                               |  115 +
 superlu/BLAS/scabs1.f                              |   57 +
 superlu/BLAS/scasum.f                              |   97 +
 superlu/BLAS/scnrm2.f                              |  119 +
 superlu/BLAS/scopy.f                               |  115 +
 superlu/BLAS/sdot.f                                |  117 +
 superlu/BLAS/sdsdot.f                              |  255 ++
 superlu/BLAS/sgbmv.f                               |  370 ++
 superlu/BLAS/sgemm.f                               |  384 ++
 superlu/BLAS/sgemv.f                               |  330 ++
 superlu/BLAS/sger.f                                |  227 +
 superlu/BLAS/snrm2.f                               |  112 +
 superlu/BLAS/srot.f                                |  101 +
 superlu/BLAS/srotg.f                               |   86 +
 superlu/BLAS/srotm.f                               |  203 +
 superlu/BLAS/srotmg.f                              |  251 ++
 superlu/BLAS/ssbmv.f                               |  375 ++
 superlu/BLAS/sscal.f                               |  110 +
 superlu/BLAS/sspmv.f                               |  331 ++
 superlu/BLAS/sspr.f                                |  261 ++
 superlu/BLAS/sspr2.f                               |  296 ++
 superlu/BLAS/sswap.f                               |  122 +
 superlu/BLAS/ssymm.f                               |  367 ++
 superlu/BLAS/ssymv.f                               |  333 ++
 superlu/BLAS/ssyr.f                                |  263 ++
 superlu/BLAS/ssyr2.f                               |  298 ++
 superlu/BLAS/ssyr2k.f                              |  399 ++
 superlu/BLAS/ssyrk.f                               |  364 ++
 superlu/BLAS/stbmv.f                               |  398 ++
 superlu/BLAS/stbsv.f                               |  401 ++
 superlu/BLAS/stpmv.f                               |  352 ++
 superlu/BLAS/stpsv.f                               |  354 ++
 superlu/BLAS/strmm.f                               |  415 ++
 superlu/BLAS/strmv.f                               |  342 ++
 superlu/BLAS/strsm.f                               |  443 ++
 superlu/BLAS/strsv.f                               |  344 ++
 superlu/BLAS/xerbla.f                              |   89 +
 superlu/BLAS/xerbla_array.f                        |  119 +
 superlu/BLAS/zaxpy.f                               |  102 +
 superlu/BLAS/zcopy.f                               |   94 +
 superlu/BLAS/zdotc.f                               |  103 +
 superlu/BLAS/zdotu.f                               |  100 +
 superlu/BLAS/zdrot.f                               |  153 +
 superlu/BLAS/zdscal.f                              |   94 +
 superlu/BLAS/zgbmv.f                               |  390 ++
 superlu/BLAS/zgemm.f                               |  483 ++
 superlu/BLAS/zgemv.f                               |  350 ++
 superlu/BLAS/zgerc.f                               |  227 +
 superlu/BLAS/zgeru.f                               |  227 +
 superlu/BLAS/zhbmv.f                               |  380 ++
 superlu/BLAS/zhemm.f                               |  371 ++
 superlu/BLAS/zhemv.f                               |  337 ++
 superlu/BLAS/zher.f                                |  278 ++
 superlu/BLAS/zher2.f                               |  317 ++
 superlu/BLAS/zher2k.f                              |  443 ++
 superlu/BLAS/zherk.f                               |  396 ++
 superlu/BLAS/zhpmv.f                               |  338 ++
 superlu/BLAS/zhpr.f                                |  279 ++
 superlu/BLAS/zhpr2.f                               |  318 ++
 superlu/BLAS/zrotg.f                               |   75 +
 superlu/BLAS/zscal.f                               |   91 +
 superlu/BLAS/zswap.f                               |   98 +
 superlu/BLAS/zsymm.f                               |  369 ++
 superlu/BLAS/zsyr2k.f                              |  396 ++
 superlu/BLAS/zsyrk.f                               |  363 ++
 superlu/BLAS/ztbmv.f                               |  429 ++
 superlu/BLAS/ztbsv.f                               |  432 ++
 superlu/BLAS/ztpmv.f                               |  388 ++
 superlu/BLAS/ztpsv.f                               |  390 ++
 superlu/BLAS/ztrmm.f                               |  452 ++
 superlu/BLAS/ztrmv.f                               |  373 ++
 superlu/BLAS/ztrsm.f                               |  477 ++
 superlu/BLAS/ztrsv.f                               |  375 ++
 superlu/BLAS_f2c.h                                 |   19 +
 superlu/Makefile.am                                |  182 +-
 superlu/Makefile.in                                |  212 +-
 superlu/ccolumn_bmod.c                             |   21 +-
 superlu/ccolumn_dfs.c                              |   17 +-
 superlu/ccopy_to_ucol.c                            |   11 +-
 superlu/cgscon.c                                   |   12 +
 superlu/cgsequ.c                                   |   21 +
 superlu/cgsrfs.c                                   |   10 +
 superlu/cgssv.c                                    |   10 +
 superlu/cgssvx.c                                   |   11 +
 superlu/cgstrf.c                                   |   21 +-
 superlu/cgstrs.c                                   |   21 +-
 superlu/clacon.c                                   |   23 +
 superlu/clangs.c                                   |   22 +
 superlu/claqgs.c                                   |   22 +
 superlu/cmemory.c                                  |   11 +
 superlu/cmyblas2.c                                 |   22 +
 superlu/cpanel_bmod.c                              |   20 +-
 superlu/cpanel_dfs.c                               |   11 +-
 superlu/cpivotL.c                                  |   17 +-
 superlu/cpivotgrowth.c                             |   22 +
 superlu/cpruneL.c                                  |   11 +-
 superlu/creadhb.c                                  |   22 +
 superlu/csnode_bmod.c                              |   21 +-
 superlu/csnode_dfs.c                               |   11 +-
 superlu/csp_blas2.c                                |   12 +
 superlu/csp_blas3.c                                |   22 +
 superlu/cutil.c                                    |   19 +-
 superlu/dcolumn_bmod.c                             |   19 +-
 superlu/dcolumn_dfs.c                              |   18 +-
 superlu/dcomplex.c                                 |   10 +
 superlu/dcopy_to_ucol.c                            |   11 +-
 superlu/dgscon.c                                   |   10 +
 superlu/dgsequ.c                                   |   22 +
 superlu/dgsrfs.c                                   |   10 +
 superlu/dgssv.c                                    |   10 +
 superlu/dgssvx.c                                   |   10 +
 superlu/dgstrf.c                                   |   17 +-
 superlu/dgstrs.c                                   |   20 +-
 superlu/dlacon.c                                   |   22 +
 superlu/dlamch.c                                   |   45 +-
 superlu/dlangs.c                                   |   22 +
 superlu/dlaqgs.c                                   |   22 +
 superlu/dmemory.c                                  |   10 +
 superlu/dmyblas2.c                                 |   22 +
 superlu/dpanel_bmod.c                              |   19 +-
 superlu/dpanel_dfs.c                               |   11 +-
 superlu/dpivotL.c                                  |   17 +-
 superlu/dpivotgrowth.c                             |   22 +
 superlu/dpruneL.c                                  |   11 +-
 superlu/dreadhb.c                                  |   22 +
 superlu/dsnode_bmod.c                              |   20 +-
 superlu/dsnode_dfs.c                               |   11 +-
 superlu/dsp_blas2.c                                |   12 +
 superlu/dsp_blas3.c                                |   22 +
 superlu/dutil.c                                    |   20 +-
 superlu/dzsum1.c                                   |   26 +-
 superlu/f2c_lite.c                                 |   15 +
 superlu/get_perm_c.c                               |   22 +
 superlu/heap_relax_snode.c                         |   17 +-
 superlu/icmax1.c                                   |   25 +-
 superlu/izmax1.c                                   |   26 +-
 superlu/lsame.c                                    |   45 +-
 superlu/memory.c                                   |   22 +
 superlu/mmd.c                                      |    9 +
 superlu/relax_snode.c                              |   11 +-
 superlu/scolumn_bmod.c                             |   14 +-
 superlu/scolumn_dfs.c                              |   11 +-
 superlu/scomplex.c                                 |   21 +
 superlu/scopy_to_ucol.c                            |   11 +-
 superlu/scsum1.c                                   |   25 +-
 superlu/sgscon.c                                   |    9 +
 superlu/sgsequ.c                                   |   21 +
 superlu/sgsrfs.c                                   |    9 +
 superlu/sgssv.c                                    |    9 +
 superlu/sgssvx.c                                   |    9 +
 superlu/sgstrf.c                                   |   20 +-
 superlu/sgstrs.c                                   |   19 +-
 superlu/slacon.c                                   |   21 +
 superlu/slamch.c                                   |   45 +-
 superlu/slangs.c                                   |   21 +
 superlu/slaqgs.c                                   |   21 +
 superlu/slu_Cnames.h                               |   21 +
 superlu/slu_cdefs.h                                |    9 +
 superlu/slu_dcomplex.h                             |   21 +
 superlu/slu_ddefs.h                                |    9 +
 superlu/slu_scomplex.h                             |   21 +
 superlu/slu_sdefs.h                                |    9 +
 superlu/slu_util.h                                 |   22 +
 superlu/slu_zdefs.h                                |    9 +
 superlu/smemory.c                                  |    9 +
 superlu/smyblas2.c                                 |   21 +
 superlu/sp_coletree.c                              |   22 +
 superlu/sp_ienv.c                                  |   23 +
 superlu/sp_preorder.c                              |   21 +
 superlu/spanel_bmod.c                              |   14 +-
 superlu/spanel_dfs.c                               |   11 +-
 superlu/spivotL.c                                  |   11 +-
 superlu/spivotgrowth.c                             |   22 +
 superlu/spruneL.c                                  |   11 +-
 superlu/sreadhb.c                                  |   21 +
 superlu/ssnode_bmod.c                              |   19 +-
 superlu/ssnode_dfs.c                               |   11 +-
 superlu/ssp_blas2.c                                |   11 +
 superlu/ssp_blas3.c                                |   21 +
 superlu/superlu_timer.c                            |   21 +
 superlu/supermatrix.h                              |   21 +
 superlu/sutil.c                                    |   19 +-
 superlu/util.c                                     |   17 +-
 superlu/zcolumn_bmod.c                             |   20 +-
 superlu/zcolumn_dfs.c                              |   17 +-
 superlu/zcopy_to_ucol.c                            |   11 +-
 superlu/zgscon.c                                   |    9 +
 superlu/zgsequ.c                                   |   21 +
 superlu/zgsrfs.c                                   |    9 +
 superlu/zgssv.c                                    |    9 +
 superlu/zgssvx.c                                   |    9 +
 superlu/zgstrf.c                                   |   19 +-
 superlu/zgstrs.c                                   |   19 +-
 superlu/zlacon.c                                   |   23 +
 superlu/zlangs.c                                   |   21 +
 superlu/zlaqgs.c                                   |   21 +
 superlu/zmemory.c                                  |    9 +
 superlu/zmyblas2.c                                 |   21 +
 superlu/zpanel_bmod.c                              |   19 +-
 superlu/zpanel_dfs.c                               |   11 +-
 superlu/zpivotL.c                                  |   17 +-
 superlu/zpivotgrowth.c                             |   21 +
 superlu/zpruneL.c                                  |   11 +-
 superlu/zreadhb.c                                  |   21 +
 superlu/zsnode_bmod.c                              |   13 +-
 superlu/zsnode_dfs.c                               |   11 +-
 superlu/zsp_blas2.c                                |   11 +
 superlu/zsp_blas3.c                                |   21 +
 superlu/zutil.c                                    |   19 +-
 tests/Makefile.am                                  |   17 +
 tests/Makefile.in                                  |   48 +-
 tests/bilaplacian.cc                               |   11 +-
 tests/bilaplacian.param                            |   16 +
 tests/bilaplacian.pl                               |    2 +-
 tests/crack.cc                                     |   17 +-
 tests/crack.param                                  |   20 +-
 tests/crack.pl                                     |    2 +-
 tests/cyl_slicer.cc                                |    2 +-
 tests/cyl_slicer.pl                                |    2 +-
 tests/dynamic_array.cc                             |    2 +-
 tests/dynamic_array.pl                             |    2 +-
 tests/dynamic_tas.cc                               |    2 +-
 tests/dynamic_tas.pl                               |    2 +-
 tests/elastostatic.cc                              |    2 +-
 tests/elastostatic.param                           |   16 +
 tests/elastostatic.pl                              |    2 +-
 tests/geo_trans_inv.cc                             |    4 +-
 tests/geo_trans_inv.param                          |   16 +
 tests/geo_trans_inv.pl                             |    2 +-
 tests/gmm_torture01_lusolve.cc                     |    2 +-
 tests/gmm_torture05_mult.cc                        |    2 +-
 tests/gmm_torture06_mat_mult.cc                    |    2 +-
 tests/gmm_torture10_qr.cc                          |    4 +-
 tests/gmm_torture15_sub.cc                         |    2 +-
 tests/gmm_torture20_iterative_solvers.cc           |   16 +-
 tests/heat_equation.cc                             |    2 +-
 tests/heat_equation.param                          |   16 +
 tests/heat_equation.pl                             |    2 +-
 tests/helmholtz.cc                                 |   41 +-
 tests/helmholtz.pl                                 |    2 +-
 tests/integration.cc                               |    9 +-
 tests/integration.pl                               |    2 +-
 tests/laplacian.cc                                 |    4 +-
 tests/laplacian.param                              |   18 +-
 tests/laplacian.pl                                 |    2 +-
 tests/laplacian_with_bricks.cc                     |    2 +-
 tests/laplacian_with_bricks.param                  |   16 +
 tests/laplacian_with_bricks.pl                     |    6 +-
 tests/make_gmm_test.pl                             |    2 +-
 tests/meshes/disc_2D_degree3.mesh                  |   16 +
 tests/meshes/disc_P2_h0_3.mesh                     |   16 +
 tests/meshes/disc_P2_h0_5.mesh                     |   16 +
 tests/meshes/disc_P2_h1.mesh                       |   16 +
 tests/meshes/disc_P2_h10.mesh                      |   16 +
 tests/meshes/disc_P2_h2.mesh                       |   16 +
 tests/meshes/disc_P2_h4.mesh                       |   16 +
 tests/meshes/disc_P2_h6.mesh                       |   16 +
 tests/meshes/disc_P2_h8.mesh                       |   16 +
 tests/meshes/disc_with_a_hole.mesh                 |   16 +
 tests/meshes/donut_regulier_32_elements.mesh       |   16 +
 tests/meshes/donut_regulier_512_elements.mesh      |   16 +
 tests/meshes/donut_regulier_72_elements.mesh       |   16 +
 tests/meshes/donut_regulier_8_elements_288ddl.mesh |   16 +
 tests/meshes/multi_body.mesh                       |   16 +
 tests/meshes/punch2D_1.mesh                        |   16 +
 tests/meshes/punch2D_2.mesh                        |   16 +
 .../sphere_with_quadratic_tetra_16000_elts.mesh    |   16 +
 .../sphere_with_quadratic_tetra_2000_elts.mesh     |   16 +
 .../sphere_with_quadratic_tetra_400_elts.mesh      |   16 +
 .../sphere_with_quadratic_tetra_80_elts.mesh       |   16 +
 .../meshes/sphere_with_quadratic_tetra_8_elts.mesh |   16 +
 tests/nonlinear_elastostatic.cc                    |    2 +-
 tests/nonlinear_elastostatic.param                 |   16 +
 tests/nonlinear_elastostatic.pl                    |    2 +-
 tests/nonlinear_membrane.cc                        |    4 +-
 tests/nonlinear_membrane.param                     |   16 +
 tests/nonlinear_membrane.pl                        |    2 +-
 tests/plasticity.cc                                |    2 +-
 tests/plasticity.param                             |   16 +
 tests/plasticity.pl                                |    2 +-
 tests/plate.cc                                     |    2 +-
 tests/plate.param                                  |   16 +
 tests/plate.pl                                     |    2 +-
 tests/poly.cc                                      |    2 +-
 tests/poly.pl                                      |    2 +-
 tests/schwarz_additive.cc                          |    6 +-
 tests/schwarz_additive.param                       |   16 +
 tests/schwarz_additive.pl                          |    2 +-
 tests/stokes.cc                                    |    2 +-
 tests/stokes.param                                 |   16 +
 tests/stokes.pl                                    |    2 +-
 tests/test_assembly.cc                             |  960 ++--
 tests/test_assembly.pl                             |    2 +-
 tests/test_continuation.cc                         |    6 +-
 tests/test_continuation.param                      |   16 +
 tests/test_continuation.pl                         |   24 +-
 tests/test_gmm_matrix_functions.cc                 |    2 +-
 tests/test_gmm_matrix_functions.pl                 |    2 +-
 tests/test_int_set.cc                              |    2 +-
 tests/test_int_set.pl                              |    2 +-
 tests/test_interpolated_fem.cc                     |    6 +-
 tests/test_interpolated_fem.param                  |   16 +
 tests/test_interpolated_fem.pl                     |    2 +-
 tests/test_interpolation.cc                        |    2 +-
 tests/test_interpolation.pl                        |    2 +-
 tests/test_kdtree.cc                               |    2 +-
 tests/test_kdtree.pl                               |    2 +-
 tests/test_mat_elem.cc                             |    2 +-
 tests/test_mat_elem.pl                             |    2 +-
 tests/test_mesh.cc                                 |    4 +-
 tests/test_mesh.pl                                 |    2 +-
 tests/test_mesh_generation.cc                      |   14 +-
 tests/test_mesh_generation.pl                      |    2 +-
 tests/test_mesh_im_level_set.cc                    |    2 +-
 tests/test_mesh_im_level_set.pl                    |    2 +-
 tests/test_range_basis.cc                          |    2 +-
 tests/test_range_basis.param                       |   16 +
 tests/test_range_basis.pl                          |    2 +-
 tests/test_rtree.cc                                |    2 +-
 tests/test_rtree.pl                                |    2 +-
 tests/test_slice.cc                                |    2 +-
 tests/test_slice.pl                                |    2 +-
 tests/test_small_vector.cc                         |   14 +-
 tests/test_small_vector.pl                         |    2 +-
 tests/test_tree_sorted.cc                          |    2 +-
 tests/test_tree_sorted.pl                          |    2 +-
 tests/thermo_elasticity_electrical_coupling.cc     |    2 +-
 tests/thermo_elasticity_electrical_coupling.param  |   16 +
 tests/thermo_elasticity_electrical_coupling.pl     |    2 +-
 tests/wave_equation.cc                             |    2 +-
 tests/wave_equation.param                          |   16 +
 tests/wave_equation.pl                             |    2 +-
 1101 files changed, 66613 insertions(+), 11641 deletions(-)

diff --git a/COPYING b/COPYING
index 89eb870..65bf0a9 100644
--- a/COPYING
+++ b/COPYING
@@ -1,12 +1,13 @@
 GetFEM++  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 2.1 of the License,  or
-(at your option) any later version along with the GCC Runtime Library
+by  the  Free  Software  Foundation;  either version 3 of the License,  or
+(at your option)  any  later  version  along  with the GCC Runtime Library
 Exception either version 3.1 or (at your option) any later version.
 This program  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 and the GCC Runtime Library Exception for more details.
 You  should  have received a copy of the GNU Lesser General Public License
-along  with  this program;  if not, write to the Free Software Foundation,
-Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
\ No newline at end of file
+along   with    this    program    (see  GNU_GPL_V3,    GNU_LGPL_V3    and
+GNU_GCC_RUNTIME_EXCEPTION files);  if  not,  write  to  the  Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
\ No newline at end of file
diff --git a/ChangeLog b/ChangeLog
index e28f677..a717e10 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+# Copyright (C) 1999-2017 Yves Renard
+#
+# This file is a part of GetFEM++
+# 
+# GetFEM++  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 along with the GCC Runtime Library
+# Exception either version 3.1 or (at your option) any later version.
+# This program  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 and GCC Runtime Library Exception for more details.
+# You  should  have received a copy of the GNU Lesser General Public License
+# along  with  this program;  if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+For the recent Change log, please see use git log
+
+
 2009-04-15 Yves Renard  <Yves.Renard at insa-lyon.fr>
 	* src/getfem/getfem_mesh_fem.h
 	* src/getfem_mesh_fem.cc
diff --git a/GNU_FDL_V3 b/GNU_FDL_V3
new file mode 100644
index 0000000..2f7e03c
--- /dev/null
+++ b/GNU_FDL_V3
@@ -0,0 +1,451 @@
+
+                GNU Free Documentation License
+                 Version 1.3, 3 November 2008
+
+
+ Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+     <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+0. PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document "free" in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of "copyleft", which means that derivative
+works of the document must themselves be free in the same sense.  It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does.  But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book.  We recommend this License
+principally for works whose purpose is instruction or reference.
+
+
+1. APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License.  Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein.  The "Document", below,
+refers to any such manual or work.  Any member of the public is a
+licensee, and is addressed as "you".  You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A "Modified Version" of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A "Secondary Section" is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject.  (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.)  The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The "Invariant Sections" are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License.  If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant.  The Document may contain zero
+Invariant Sections.  If the Document does not identify any Invariant
+Sections then there are none.
+
+The "Cover Texts" are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License.  A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A "Transparent" copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters.  A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text.  A copy that is not "Transparent" is called "Opaque".
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML, PostScript or PDF designed for human modification.  Examples of
+transparent image formats include PNG, XCF and JPG.  Opaque formats
+include proprietary formats that can be read and edited only by
+proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML, PostScript or PDF produced by some word
+processors for output purposes only.
+
+The "Title Page" means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page.  For works in
+formats which do not have any title page as such, "Title Page" means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+The "publisher" means any person or entity that distributes copies of
+the Document to the public.
+
+A section "Entitled XYZ" means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language.  (Here XYZ stands for a
+specific section name mentioned below, such as "Acknowledgements",
+"Dedications", "Endorsements", or "History".)  To "Preserve the Title"
+of such a section when you modify the Document means that it remains a
+section "Entitled XYZ" according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document.  These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+2. VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no
+other conditions whatsoever to those of this License.  You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute.  However, you may accept
+compensation in exchange for copies.  If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+
+3. COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover.  Both covers must also clearly and legibly identify
+you as the publisher of these copies.  The front cover must present
+the full title with all words of the title equally prominent and
+visible.  You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to
+give them a chance to provide you with an updated version of the
+Document.
+
+
+4. MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it.  In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct
+   from that of the Document, and from those of previous versions
+   (which should, if there were any, be listed in the History section
+   of the Document).  You may use the same title as a previous version
+   if the original publisher of that version gives permission.
+B. List on the Title Page, as authors, one or more persons or entities
+   responsible for authorship of the modifications in the Modified
+   Version, together with at least five of the principal authors of the
+   Document (all of its principal authors, if it has fewer than five),
+   unless they release you from this requirement.
+C. State on the Title page the name of the publisher of the
+   Modified Version, as the publisher.
+D. Preserve all the copyright notices of the Document.
+E. Add an appropriate copyright notice for your modifications
+   adjacent to the other copyright notices.
+F. Include, immediately after the copyright notices, a license notice
+   giving the public permission to use the Modified Version under the
+   terms of this License, in the form shown in the Addendum below.
+G. Preserve in that license notice the full lists of Invariant Sections
+   and required Cover Texts given in the Document's license notice.
+H. Include an unaltered copy of this License.
+I. Preserve the section Entitled "History", Preserve its Title, and add
+   to it an item stating at least the title, year, new authors, and
+   publisher of the Modified Version as given on the Title Page.  If
+   there is no section Entitled "History" in the Document, create one
+   stating the title, year, authors, and publisher of the Document as
+   given on its Title Page, then add an item describing the Modified
+   Version as stated in the previous sentence.
+J. Preserve the network location, if any, given in the Document for
+   public access to a Transparent copy of the Document, and likewise
+   the network locations given in the Document for previous versions
+   it was based on.  These may be placed in the "History" section.
+   You may omit a network location for a work that was published at
+   least four years before the Document itself, or if the original
+   publisher of the version it refers to gives permission.
+K. For any section Entitled "Acknowledgements" or "Dedications",
+   Preserve the Title of the section, and preserve in the section all
+   the substance and tone of each of the contributor acknowledgements
+   and/or dedications given therein.
+L. Preserve all the Invariant Sections of the Document,
+   unaltered in their text and in their titles.  Section numbers
+   or the equivalent are not considered part of the section titles.
+M. Delete any section Entitled "Endorsements".  Such a section
+   may not be included in the Modified Version.
+N. Do not retitle any existing section to be Entitled "Endorsements"
+   or to conflict in title with any Invariant Section.
+O. Preserve any Warranty Disclaimers.
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant.  To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled "Endorsements", provided it contains
+nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version.  Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity.  If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+
+5. COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy.  If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled "History"
+in the various original documents, forming one section Entitled
+"History"; likewise combine any sections Entitled "Acknowledgements",
+and any sections Entitled "Dedications".  You must delete all sections
+Entitled "Endorsements".
+
+
+6. COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other
+documents released under this License, and replace the individual
+copies of this License in the various documents with a single copy
+that is included in the collection, provided that you follow the rules
+of this License for verbatim copying of each of the documents in all
+other respects.
+
+You may extract a single document from such a collection, and
+distribute it individually under this License, provided you insert a
+copy of this License into the extracted document, and follow this
+License in all other respects regarding verbatim copying of that
+document.
+
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an "aggregate" if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+
+8. TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections.  You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers.  In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled "Acknowledgements",
+"Dedications", or "History", the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+
+9. TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense, or distribute it is void, and
+will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+
+10. FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions of the
+GNU Free Documentation License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in
+detail to address new problems or concerns.  See
+http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation.  If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.  If the Document
+specifies that a proxy can decide which future versions of this
+License can be used, that proxy's public statement of acceptance of a
+version permanently authorizes you to choose that version for the
+Document.
+
+11. RELICENSING
+
+"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+World Wide Web server that publishes copyrightable works and also
+provides prominent facilities for anybody to edit those works.  A
+public wiki that anybody can edit is an example of such a server.  A
+"Massive Multiauthor Collaboration" (or "MMC") contained in the site
+means any set of copyrightable works thus published on the MMC site.
+
+"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 
+license published by Creative Commons Corporation, a not-for-profit 
+corporation with a principal place of business in San Francisco, 
+California, as well as future copyleft versions of that license 
+published by that same organization.
+
+"Incorporate" means to publish or republish a Document, in whole or in 
+part, as part of another Document.
+
+An MMC is "eligible for relicensing" if it is licensed under this 
+License, and if all works that were first published under this License 
+somewhere other than this MMC, and subsequently incorporated in whole or 
+in part into the MMC, (1) had no cover texts or invariant sections, and 
+(2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+
+ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+    Copyright (c)  YEAR  YOUR NAME.
+    Permission is granted to copy, distribute and/or modify this document
+    under the terms of the GNU Free Documentation License, Version 1.3
+    or any later version published by the Free Software Foundation;
+    with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+    A copy of the license is included in the section entitled "GNU
+    Free Documentation License".
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the "with...Texts." line with this:
+
+    with the Invariant Sections being LIST THEIR TITLES, with the
+    Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
diff --git a/GNU_GCC_RUNTIME_EXCEPTION b/GNU_GCC_RUNTIME_EXCEPTION
new file mode 100644
index 0000000..e1b3c69
--- /dev/null
+++ b/GNU_GCC_RUNTIME_EXCEPTION
@@ -0,0 +1,73 @@
+GCC RUNTIME LIBRARY EXCEPTION
+
+Version 3.1, 31 March 2009
+
+Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+This GCC Runtime Library Exception ("Exception") is an additional
+permission under section 7 of the GNU General Public License, version
+3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
+bears a notice placed by the copyright holder of the file stating that
+the file is governed by GPLv3 along with this Exception.
+
+When you use GCC to compile a program, GCC may combine portions of
+certain GCC header files and runtime libraries with the compiled
+program. The purpose of this Exception is to allow compilation of
+non-GPL (including proprietary) programs to use, in this way, the
+header files and runtime libraries covered by this Exception.
+
+0. Definitions.
+
+A file is an "Independent Module" if it either requires the Runtime
+Library for execution after a Compilation Process, or makes use of an
+interface provided by the Runtime Library, but is not otherwise based
+on the Runtime Library.
+
+"GCC" means a version of the GNU Compiler Collection, with or without
+modifications, governed by version 3 (or a specified later version) of
+the GNU General Public License (GPL) with the option of using any
+subsequent versions published by the FSF.
+
+"GPL-compatible Software" is software whose conditions of propagation,
+modification and use would permit combination with GCC in accord with
+the license of GCC.
+
+"Target Code" refers to output from any compiler for a real or virtual
+target processor architecture, in executable form or suitable for
+input to an assembler, loader, linker and/or execution
+phase. Notwithstanding that, Target Code does not include data in any
+format that is used as a compiler intermediate representation, or used
+for producing a compiler intermediate representation.
+
+The "Compilation Process" transforms code entirely represented in
+non-intermediate languages designed for human-written code, and/or in
+Java Virtual Machine byte code, into Target Code. Thus, for example,
+use of source code generators and preprocessors need not be considered
+part of the Compilation Process, since the Compilation Process can be
+understood as starting with the output of the generators or
+preprocessors.
+
+A Compilation Process is "Eligible" if it is done using GCC, alone or
+with other GPL-compatible software, or if it is done without using any
+work based on GCC. For example, using non-GPL-compatible Software to
+optimize any GCC intermediate representations would not qualify as an
+Eligible Compilation Process.
+
+1. Grant of Additional Permission.
+
+You have permission to propagate a work of Target Code formed by
+combining the Runtime Library with Independent Modules, even if such
+propagation would otherwise violate the terms of GPLv3, provided that
+all Target Code was generated by Eligible Compilation Processes. You
+may then convey such a combination under terms of your choice,
+consistent with the licensing of the Independent Modules.
+
+2. No Weakening of GCC Copyleft.
+
+The availability of this Exception does not imply any general
+presumption that third-party software is unaffected by the copyleft
+requirements of the license of GCC.
+
diff --git a/GNU_GPL_V3 b/GNU_GPL_V3
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/GNU_GPL_V3
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/GNU_LGPL_V3 b/GNU_LGPL_V3
new file mode 100644
index 0000000..65c5ca8
--- /dev/null
+++ b/GNU_LGPL_V3
@@ -0,0 +1,165 @@
+                   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/INSTALL b/INSTALL
index 7650146..0399d17 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,3 +1,30 @@
+#  Copyright (C) 1999-2017 Yves Renard, Julien Pommier
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+=====
+Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
+Inc.
+
+   Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.  This file is offered as-is,
+without warranty of any kind.
+=====
+
+
 Short Installation procedure
 ============================
 
diff --git a/Makefile.am b/Makefile.am
index 3e2124d..83ce920 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,8 +1,26 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
 ACLOCAL_AMFLAGS = -I m4
 
 SUBDIRS = m4 cubature @SUPERLU_SRC@ src tests interface contrib bin doc
 
-EXTRA_DIST =
+EXTRA_DIST = GNU_LGPL_V3 GNU_GPL_V3 GNU_GCC_RUNTIME_EXCEPTION GNU_FDL_V3
 
 CLEANFILES = so_locations _configs.sed
 
diff --git a/Makefile.in b/Makefile.in
index 5a3b6fb..3efe2cd 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,18 +14,25 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,6 +96,15 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = .
+DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
+	$(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(srcdir)/config.h.in mkinstalldirs \
+	$(top_srcdir)/interface/src/scilab/sci_gateway/c/builder_gateway_c.sce.in \
+	$(srcdir)/getfem-config.in \
+	$(srcdir)/getfem-config-notinstalled.in \
+	$(srcdir)/gmm-config.in COPYING compile config.guess \
+	config.sub depcomp install-sh missing py-compile ltmain.sh
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -104,8 +120,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
-	$(am__configure_deps) $(am__DIST_COMMON)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -200,13 +214,6 @@ ETAGS = etags
 CTAGS = ctags
 CSCOPE = cscope
 DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
-	$(srcdir)/getfem-config-notinstalled.in \
-	$(srcdir)/getfem-config.in $(srcdir)/gmm-config.in \
-	$(top_srcdir)/interface/src/scilab/sci_gateway/c/builder_gateway_c.sce.in \
-	AUTHORS COPYING ChangeLog INSTALL NEWS README compile \
-	config.guess config.sub depcomp install-sh ltmain.sh missing \
-	mkinstalldirs py-compile
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -315,7 +322,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -348,8 +354,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -430,7 +438,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -441,7 +448,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 ACLOCAL_AMFLAGS = -I m4
 SUBDIRS = m4 cubature @SUPERLU_SRC@ src tests interface contrib bin doc
-EXTRA_DIST = 
+EXTRA_DIST = GNU_LGPL_V3 GNU_GPL_V3 GNU_GCC_RUNTIME_EXCEPTION GNU_FDL_V3
 CLEANFILES = so_locations _configs.sed
 bin_SCRIPTS = getfem-config
 all: config.h
@@ -463,6 +470,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -736,15 +744,15 @@ dist-xz: distdir
 	$(am__post_remove_distdir)
 
 dist-tarZ: distdir
-	@echo WARNING: "Support for distribution archives compressed with" \
-		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
 	$(am__post_remove_distdir)
 
 dist-shar: distdir
-	@echo WARNING: "Support for shar distribution archives is" \
-	               "deprecated." >&2
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
 	$(am__post_remove_distdir)
@@ -780,17 +788,17 @@ distcheck: dist
 	esac
 	chmod -R a-w $(distdir)
 	chmod u+w $(distdir)
-	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+	mkdir $(distdir)/_build $(distdir)/_inst
 	chmod a-w $(distdir)
 	test -d $(distdir)/_build || exit 0; \
 	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
 	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
 	  && am__cwd=`pwd` \
-	  && $(am__cd) $(distdir)/_build/sub \
-	  && ../../configure \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure \
 	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
-	    --srcdir=../.. --prefix="$$dc_install_base" \
+	    --srcdir=.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
@@ -971,8 +979,6 @@ uninstall-am: uninstall-binSCRIPTS
 	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
 	uninstall-am uninstall-binSCRIPTS
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/NEWS b/NEWS
old mode 100755
new mode 100644
index 86ca821..2305333
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,21 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
 What's new ?
 -----------------
 
diff --git a/README b/README
old mode 100755
new mode 100644
index afeab48..1819332
--- a/README
+++ b/README
@@ -1 +1,29 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 Please read BUGS, INSTALL
+
+
+
+IMAGES and documentation :
+
+#  Permission is granted to copy, distribute and/or modify all
+#  documentations and images included in GetFEM++ package
+#  under the terms of the GNU Free Documentation License, Version 1.3
+#  or any later version published by the Free Software Foundation;
+#  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+#  A copy of the license is included in top directory.
diff --git a/aclocal.m4 b/aclocal.m4
index cf20d6d..76163cc 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.14'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15], [],
+m4_if([$1], [1.14.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -103,14 +103,15 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 # configured tree to be moved without reconfiguration.
 
 AC_DEFUN([AM_AUX_DIR_EXPAND],
-[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
-# Expand $ac_aux_dir to an absolute path.
-am_aux_dir=`cd "$ac_aux_dir" && pwd`
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
 ])
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -141,7 +142,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -332,7 +333,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -408,7 +409,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -498,8 +499,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target (and possibly the TAP driver).  The
-# system "awk" is bad on some platforms.
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
 AC_REQUIRE([AC_PROG_AWK])dnl
 AC_REQUIRE([AC_PROG_MAKE_SET])dnl
 AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -572,11 +573,7 @@ to "yes", and re-run configure.
 END
     AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
   fi
-fi
-dnl The trailing newline in this macro's definition is deliberate, for
-dnl backward compatibility and to allow trailing 'dnl'-style comments
-dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
-])
+fi])
 
 dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
 dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@@ -605,7 +602,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -616,7 +613,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
 # Define $install_sh.
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh+set}" != xset; then
+if test x"${install_sh}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -626,7 +623,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -647,7 +644,7 @@ AC_SUBST([am__leading_dot])])
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -697,7 +694,7 @@ rm -f confinc confmf
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -736,7 +733,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -765,7 +762,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -812,7 +809,7 @@ AC_LANG_POP([C])])
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1047,7 +1044,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
 sys.exit(sys.hexversion < minverhex)"
   AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1066,7 +1063,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1147,7 +1144,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1207,7 +1204,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1235,7 +1232,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1254,7 +1251,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/bin/Makefile.am b/bin/Makefile.am
index 0150b35..13f4411 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -1,3 +1,21 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
 bin_SCRIPTS =
 
-EXTRA_DIST = $(bin_SCRIPTS) createmp extract_doc ansys2getfem_mesh split_cmdref mesh_matlab_to_getfem fig2eps
\ No newline at end of file
+EXTRA_DIST = $(bin_SCRIPTS) createmp extract_doc ansys2getfem_mesh split_cmdref mesh_matlab_to_getfem fig2eps
diff --git a/bin/Makefile.in b/bin/Makefile.in
index e46f037..2b72cce 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,18 +14,25 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,6 +96,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = bin
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -104,7 +113,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -158,7 +166,6 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -226,7 +233,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -259,8 +265,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -341,7 +349,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -367,6 +374,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bin/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu bin/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -580,8 +588,6 @@ uninstall-am: uninstall-binSCRIPTS
 	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
 	uninstall-am uninstall-binSCRIPTS
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/bin/ansys2getfem_mesh b/bin/ansys2getfem_mesh
index 7871f84..5dc207a 100644
--- a/bin/ansys2getfem_mesh
+++ b/bin/ansys2getfem_mesh
@@ -1,13 +1,13 @@
 #!/usr/bin/env python
 # -*- python -*-
 #
-# Copyright (C) 2004-2012 Yves Renard, Konstantinos Poulios.
+# Copyright (C) 2004-2017 Yves Renard, Konstantinos Poulios.
 #                                                       
 # This file is a part of GetFEM++                                         
 #                                                                         
 # GetFEM++  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 2.1 of the License,  or
+# by  the  Free Software Foundation;  either version 3 of the License,  or
 # (at your option) any later version.
 # This program  is  distributed  in  the  hope  that it will be useful,  but
 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
diff --git a/bin/createmp b/bin/createmp
index c0c863f..51fc624 100755
--- a/bin/createmp
+++ b/bin/createmp
@@ -1,10 +1,10 @@
-# Copyright (C) 2001-2015 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
 # GetFEM++  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 2.1 of the License,  or
+# by  the  Free Software Foundation;  either version 3 of the License,  or
 # (at your option) any later version.
 # This program  is  distributed  in  the  hope  that it will be useful,  but
 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
diff --git a/bin/extract_doc b/bin/extract_doc
index b14bdcb..12cf717 100755
--- a/bin/extract_doc
+++ b/bin/extract_doc
@@ -1,13 +1,13 @@
 #!/usr/bin/env python
 # -*- python -*-
 #
-# Copyright (C) 2004-2016 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #                                                       
 # This file is a part of GetFEM++                                         
 #                                                                         
 # GetFEM++  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 2.1 of the License,  or
+# by  the  Free Software Foundation;  either version 3 of the License,  or
 # (at your option) any later version.
 # This program  is  distributed  in  the  hope  that it will be useful,  but
 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -49,7 +49,7 @@ def find_closing_brace(s):
         if (lev == -1):
           return cnt
       cnt += 1
-    raise ParseError, s
+    raise ParseError(s)
 
 
 def find_closing_bracket(s):
@@ -63,7 +63,7 @@ def find_closing_bracket(s):
         if (lev == -1):
           return cnt
       cnt += 1
-    raise ParseError, s
+    raise ParseError(s)
 
 
 def CellToTuples(d):
@@ -197,13 +197,13 @@ def ExtractSubDoc(fl, langage):
             re = re[re.find("=")+1:].strip()
                 
           if (not re.startswith('(') or not re.endswith(')')):
-            raise ParseError, 'Syntax error in function definition ' + l
+            raise ParseError('Syntax error in function definition ' + l)
           re = (re[1:-1]).strip()
           if (not re.startswith("'")):
-            raise ParseError, 'Syntax error in function definition ' + l
+            raise ParseError('Syntax error in function definition ' + l)
           re = re[1:]
           if (re.find("'") == -1):
-            raise ParseError, 'Syntax error in function definition ' + l
+            raise ParseError('Syntax error in function definition ' + l)
           mname = re[:re.find("'")]
           params = re[re.find("'")+1:]
           in_doc = 2
@@ -269,54 +269,54 @@ def FilterDoc(d, langage, objects, commands, set_replace = set()):
     for o in objects:
       [r, I] = StandardObjectName(o)
       # transforme OBJET:INIT en gf_objet
-      d = string.replace(d, o.upper()+':INIT','gf_'+o)
+      d = d.replace(o.upper()+':INIT','gf_'+o)
       # transforme OBJET:GET(...) en gf_objet_get(O, ...)
-      d = string.replace(d, o.upper()+':GET(','gf_'+o+'_get('+o+' '+I+', ')
-      d = string.replace(d, o.upper()+':SET(','gf_'+o+'_set('+o+' '+I+', ')
-      d = string.replace(d, '@t'+o, o)
+      d = d.replace(o.upper()+':GET(','gf_'+o+'_get('+o+' '+I+', ')
+      d = d.replace(o.upper()+':SET(','gf_'+o+'_set('+o+' '+I+', ')
+      d = d.replace('@t'+o, o)
 
     for c in commands:
-      d = string.replace(d, '::'+c.upper(),'gf_'+c)
-
-    d = string.replace(d, '@CELL',   '')
-    d = string.replace(d, '@imat',   'imat')
-    d = string.replace(d, '@ivec',   'ivec')
-    d = string.replace(d, '@cvec',   'vec')
-    d = string.replace(d, '@dcvec',  'vec')
-    d = string.replace(d, '@dvec',   'vec')
-    d = string.replace(d, '@vec',    'vec')
-    d = string.replace(d, '@dmat',   'mat')
-    d = string.replace(d, '@mat',    'mat')
-    d = string.replace(d, '@str',    'string')
-    d = string.replace(d, '@int',    'int')
-    d = string.replace(d, '@bool',   'bool')
-    d = string.replace(d, '@real',   'real')
-    d = string.replace(d, '@scalar', 'scalar')
-    d = string.replace(d, '@list',   'list')
+      d = d.replace('::'+c.upper(),'gf_'+c)
+
+    d = d.replace('@CELL',   '')
+    d = d.replace('@imat',   'imat')
+    d = d.replace('@ivec',   'ivec')
+    d = d.replace('@cvec',   'vec')
+    d = d.replace('@dcvec',  'vec')
+    d = d.replace('@dvec',   'vec')
+    d = d.replace('@vec',    'vec')
+    d = d.replace('@dmat',   'mat')
+    d = d.replace('@mat',    'mat')
+    d = d.replace('@str',    'string')
+    d = d.replace('@int',    'int')
+    d = d.replace('@bool',   'bool')
+    d = d.replace('@real',   'real')
+    d = d.replace('@scalar', 'scalar')
+    d = d.replace('@list',   'list')
 
     # Objects with no mfiles
-    d = string.replace(d, '@tpoly',  'poly')
+    d = d.replace('@tpoly',  'poly')
 
     # Authorized abbreviations
-    d = string.replace(d, '@tcs',    'cont_struct')
-    d = string.replace(d, '@tmf',    'mesh_fem')
-    d = string.replace(d, '@tgt',    'geotrans')
-    d = string.replace(d, '@tgf',    'global_function')
-    d = string.replace(d, '@tmo',    'mesher_object')
-    d = string.replace(d, '@tmls',   'mesh_levelset')
-    d = string.replace(d, '@tmim',   'mesh_im')
-    d = string.replace(d, '@tmimd',  'mesh_im_data')
-    d = string.replace(d, '@tls',    'levelset')
-    d = string.replace(d, '@tsl',    'slice')
-    d = string.replace(d, '@tsp',    'spmat')
-    d = string.replace(d, '@tpre',   'precond')
+    d = d.replace('@tcs',    'cont_struct')
+    d = d.replace('@tmf',    'mesh_fem')
+    d = d.replace('@tgt',    'geotrans')
+    d = d.replace('@tgf',    'global_function')
+    d = d.replace('@tmo',    'mesher_object')
+    d = d.replace('@tmls',   'mesh_levelset')
+    d = d.replace('@tmim',   'mesh_im')
+    d = d.replace('@tmimd',  'mesh_im_data')
+    d = d.replace('@tls',    'levelset')
+    d = d.replace('@tsl',    'slice')
+    d = d.replace('@tsp',    'spmat')
+    d = d.replace('@tpre',   'precond')
 
   elif (langage == 'python'):
-    d = string.replace(d, '\\', '\\\\')
+    d = d.replace('\\', '\\\\')
     for o in objects:
       [oname, I] = StandardObjectName(o)
       # transforme OBJET:INIT en gf_objet
-      d = string.replace(d, o.upper()+':INIT',oname)
+      d = d.replace(o.upper()+':INIT',oname)
       # transforme OBJET:GET(...) en gf_objet_get(O, ...)
       i = d.find(o.upper()+':GET(')
       while (i != -1):
@@ -327,8 +327,8 @@ def FilterDoc(d, langage, objects, commands, set_replace = set()):
         else:
           j = r[1:].find('\'')
           com = r[1:(j+1)]
-          com = string.replace(com, ' ', '_');
-          com = string.replace(com, '-', '_');
+          com = com.replace(' ', '_');
+          com = com.replace('-', '_');
           r = r[j+2:].strip()
           if (r[0] == ','):
             r = r[1:].strip()
@@ -343,8 +343,8 @@ def FilterDoc(d, langage, objects, commands, set_replace = set()):
         else:
           j = r[1:].find('\'')
           com = r[1:(j+1)]
-          com = string.replace(com, ' ', '_');
-          com = string.replace(com, '-', '_');
+          com = com.replace(' ', '_');
+          com = com.replace('-', '_');
           r = r[j+2:].strip()
           if (r[0] == ','):
             r = r[1:].strip()
@@ -355,43 +355,43 @@ def FilterDoc(d, langage, objects, commands, set_replace = set()):
         i = d.find(o.upper()+':SET(')
       
       
-      d = string.replace(d, '@t'+o, oname)
+      d = d.replace('@t'+o, oname)
 
     for c in commands:
-      d = string.replace(d, '::'+c.upper(),'gf_'+c)
+      d = d.replace('::'+c.upper(),'gf_'+c)
 
     d = CellToTuples(d);
-    d = string.replace(d, '@imat',   'imat')
-    d = string.replace(d, '@ivec',   'ivec')
-    d = string.replace(d, '@cvec',   'vec')
-    d = string.replace(d, '@dcvec',  'vec')
-    d = string.replace(d, '@dvec',   'vec')
-    d = string.replace(d, '@vec',    'vec')
-    d = string.replace(d, '@dmat',   'mat')
-    d = string.replace(d, '@mat',    'mat')
-    d = string.replace(d, '@str',    'string')
-    d = string.replace(d, '@int',    'int')
-    d = string.replace(d, '@bool',   'bool')
-    d = string.replace(d, '@real',   'real')
-    d = string.replace(d, '@scalar', 'scalar')
-    d = string.replace(d, '@list',   'list')
+    d = d.replace('@imat',   'imat')
+    d = d.replace('@ivec',   'ivec')
+    d = d.replace('@cvec',   'vec')
+    d = d.replace('@dcvec',  'vec')
+    d = d.replace('@dvec',   'vec')
+    d = d.replace('@vec',    'vec')
+    d = d.replace('@dmat',   'mat')
+    d = d.replace('@mat',    'mat')
+    d = d.replace('@str',    'string')
+    d = d.replace('@int',    'int')
+    d = d.replace('@bool',   'bool')
+    d = d.replace('@real',   'real')
+    d = d.replace('@scalar', 'scalar')
+    d = d.replace('@list',   'list')
 
     # Objects with no mfiles
-    d = string.replace(d, '@tpoly',  'poly')
+    d = d.replace('@tpoly',  'poly')
 
     # Authorized abbreviations
-    d = string.replace(d, '@tcs',    'ContStruct')
-    d = string.replace(d, '@tmf',    'MeshFem')
-    d = string.replace(d, '@tgt',    'GeoTrans')
-    d = string.replace(d, '@tgf',    'GlobalFunction')
-    d = string.replace(d, '@tmo',    'MesherObject')
-    d = string.replace(d, '@tmls',   'MeshLevelSet')
-    d = string.replace(d, '@tmim',   'MeshIm')
-    d = string.replace(d, '@tmimd',  'MeshImData')
-    d = string.replace(d, '@tls',    'LevelSet')
-    d = string.replace(d, '@tsl',    'Slice')
-    d = string.replace(d, '@tsp',    'SpMat')
-    d = string.replace(d, '@tpre',   'Mrecond')
+    d = d.replace('@tcs',    'ContStruct')
+    d = d.replace('@tmf',    'MeshFem')
+    d = d.replace('@tgt',    'GeoTrans')
+    d = d.replace('@tgf',    'GlobalFunction')
+    d = d.replace('@tmo',    'MesherObject')
+    d = d.replace('@tmls',   'MeshLevelSet')
+    d = d.replace('@tmim',   'MeshIm')
+    d = d.replace('@tmimd',  'MeshImData')
+    d = d.replace('@tls',    'LevelSet')
+    d = d.replace('@tsl',    'Slice')
+    d = d.replace('@tsp',    'SpMat')
+    d = d.replace('@tpre',   'Mrecond')
 
   return d
 
@@ -440,7 +440,24 @@ def SynopsisToPythonArgs(s0):
       args += ['*args']
     return args
 
- 
+def cmp_to_key(mycmp):
+    'Convert a cmp= function into a key= function'
+    class K:
+        def __init__(self, obj, *args):
+            self.obj = obj
+        def __lt__(self, other):
+            return mycmp(self.obj, other.obj) < 0
+        def __gt__(self, other):
+            return mycmp(self.obj, other.obj) > 0
+        def __eq__(self, other):
+            return mycmp(self.obj, other.obj) == 0
+        def __le__(self, other):
+            return mycmp(self.obj, other.obj) <= 0
+        def __ge__(self, other):
+            return mycmp(self.obj, other.obj) >= 0
+        def __ne__(self, other):
+            return mycmp(self.obj, other.obj) != 0
+    return K
 
 #######################################################################
 #
@@ -456,7 +473,7 @@ def SynopsisToPythonArgs(s0):
 valid_options = 'matlab-com, matlab-doc, scilab-com, scilab-doc, python-com, python-doc'
 
 if (len(sys.argv) != 3):
-    raise SystemExit, 'Format : extract_doc directory option'
+    raise SystemExit('Format : extract_doc directory option')
 
 directory = sys.argv[1]
 option = sys.argv[2]
@@ -466,9 +483,15 @@ option = sys.argv[2]
 # List the filenames and extract object and command names.
 #
 
-fl = os.popen('(cd ' + directory + ' ; ls gf_*.cc)');
+fl = os.popen('(cd ' + directory + '; ls gf_*.cc)');
 lines = fl.readlines();
-fl.close()
+a = fl.close()
+if (a) : # Windows
+    fl = os.popen('((cd ' + directory + ') & (ls gf_*.cc))');
+    lines = fl.readlines();
+    a = fl.close()
+
+
 objects = set()
 objects.add('eltm');
 commands = set()
@@ -491,8 +514,8 @@ def cmpobj(x, y):
 set_objects = objects
 set_commands = commands
 
-objects = sorted(objects, cmpobj)
-commands = sorted(commands, cmpobj)
+objects = sorted(objects, key=cmp_to_key(cmpobj))
+commands = sorted(commands, key=cmp_to_key(cmpobj))
 
 if (option == 'pseudo_loc'):
 
@@ -634,8 +657,8 @@ elif (option == 'matlab-com'):
         fl = open(src_dir)
         [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
         while (ok):
-          mname = string.replace(mname, ' ', '_');
-          mname = string.replace(mname, '-', '_');
+          mname = mname.replace(' ', '_');
+          mname = mname.replace('-', '_');
           if (mname in sub_com or mname=='classical_fem' or mname=='classical_discontinuous_fem'):
             set_replace.add(oname+'::'+mname)
           sub_com.add(mname)
@@ -743,8 +766,8 @@ elif (option == 'matlab-com'):
       doc = '';
       [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
       while (ok):
-        mname = string.replace(mname, ' ', '_');
-        mname = string.replace(mname, '-', '_');
+        mname = mname.replace(' ', '_');
+        mname = mname.replace('-', '_');
         if (oname[2:]+'::'+mname in set_replace):
           mfile.write('        case \'set_' + mname + '\'\n')
         else:
@@ -848,67 +871,67 @@ elif (option == 'matlab-doc'):
 
   langage = 'matlab'
   
-  print '.. Automatically generated file, do not edit it.'
-  print '.. If some modification are necessary, please modify'
-  print '.. the corresponding C++ source or the python program extract_doc'
-  print ''
-  print ''
-  print '.. include:: ../replaces.txt'
-  print ''
-  print '.. highlightlang:: matlab'
-  print ''
-  print '.. _mlab-cmdref:'
-  print ''
-  print 'Command reference'
-  print '================='
-  print ''
-  print 'Please remember that this documentation is not self contained.'
-  print 'You should in particular refer to the `user documentation`_ '
-  print 'to have a more extensive description of the structures algorithms '
-  print 'and concepts used.'
-  print ''
-  # print 'Types'
-  # print '-----'
-  print ''
-  print 'The expected type of each function argument is indicated in this '
-  print 'reference. Here is a list of these types:'
-  print ''
-  print '=====================  =================================================='
-  print '`int`                  integer value'
-  print '`hobj`                 a handle for any GetFEM++ object'
-  print '`scalar`               scalar value'
-  print '`string`               string'
-  print '`ivec`                 vector of integer values'
-  print '`vec`                  vector'
-  print '`imat`                 matrix of integer values'
-  print '`mat`                  matrix'
-  print '`spmat`                sparse matrix (both matlab native sparse'
-  print '                       matrices, and GetFEM sparse matrices)'
-  print '`precond`              GetFEM preconditioner object'
-  print '`mesh mesh`            object descriptor (or gfMesh object)'
-  print '`mesh_fem`             mesh fem object descriptor (or gfMeshFem object)'
-  print '`mesh_im`              mesh im object descriptor (or gfMeshIm object)'
-  print '`mesh_im_data`         mesh im data object descriptor (or gfMeshImData object)'
-  print '`mesh_slice`           mesh slice object descriptor (or gfSlice object)'
-  print '`cvstruct`             convex structure descriptor (or gfCvStruct object)'
-  print '`geotrans`             geometric transformation descriptor (or '
-  print '                       gfGeoTrans object)'
-  print '`fem`                  fem descriptor (or gfFem object)'
-  print '`eltm`                 elementary matrix descriptor (or gfEltm object)'
-  print '`integ`                integration method descriptor (or gfInteg object)'
-  print '`model`                model descriptor (or gfModel object)'
-  print '`global_function`      global function descriptor'
-  print '`mesher_object`        mesher object descriptor'
-  print '`cont_struct`          continuation-structure descriptor'
-  print '=====================  =================================================='
-  print ''  
-  print 'Arguments listed between square brackets are optional. Lists between braces indicate that the argument must match one of the elements of the list. For example::'
-  print ''
-  print '  >> [X,Y]=dummy(int i, \'foo\' | \'bar\' [,vec v])'
-  print ''
-  print 'means that the dummy function takes two or three arguments, its first being an integer value, the second a string which is either \'foo\' or \'bar\', and a third optional argument. It returns two values (with the usual matlab meaning, i.e. the caller can always choose to ignore them).'
-  print ''
-  print ''
+  print('.. Automatically generated file, do not edit it.')
+  print('.. If some modification are necessary, please modify')
+  print('.. the corresponding C++ source or the python program extract_doc')
+  print('')
+  print('')
+  print('.. include:: ../replaces.txt')
+  print('')
+  print('.. highlightlang:: matlab')
+  print('')
+  print('.. _mlab-cmdref:')
+  print('')
+  print('Command reference')
+  print('=================')
+  print('')
+  print('Please remember that this documentation is not self contained.')
+  print('You should in particular refer to the `user documentation`_ ')
+  print('to have a more extensive description of the structures algorithms ')
+  print('and concepts used.')
+  print('')
+  # print('Types')
+  # print('-----')
+  print('')
+  print('The expected type of each function argument is indicated in this ')
+  print('reference. Here is a list of these types:')
+  print('')
+  print('=====================  ==================================================')
+  print('`int`                  integer value')
+  print('`hobj`                 a handle for any GetFEM++ object')
+  print('`scalar`               scalar value')
+  print('`string`               string')
+  print('`ivec`                 vector of integer values')
+  print('`vec`                  vector')
+  print('`imat`                 matrix of integer values')
+  print('`mat`                  matrix')
+  print('`spmat`                sparse matrix (both matlab native sparse')
+  print('                       matrices, and GetFEM sparse matrices)')
+  print('`precond`              GetFEM preconditioner object')
+  print('`mesh mesh`            object descriptor (or gfMesh object)')
+  print('`mesh_fem`             mesh fem object descriptor (or gfMeshFem object)')
+  print('`mesh_im`              mesh im object descriptor (or gfMeshIm object)')
+  print('`mesh_im_data`         mesh im data object descriptor (or gfMeshImData object)')
+  print('`mesh_slice`           mesh slice object descriptor (or gfSlice object)')
+  print('`cvstruct`             convex structure descriptor (or gfCvStruct object)')
+  print('`geotrans`             geometric transformation descriptor (or ')
+  print('                       gfGeoTrans object)')
+  print('`fem`                  fem descriptor (or gfFem object)')
+  print('`eltm`                 elementary matrix descriptor (or gfEltm object)')
+  print('`integ`                integration method descriptor (or gfInteg object)')
+  print('`model`                model descriptor (or gfModel object)')
+  print('`global_function`      global function descriptor')
+  print('`mesher_object`        mesher object descriptor')
+  print('`cont_struct`          continuation-structure descriptor')
+  print('=====================  ==================================================')
+  print('') 
+  print('Arguments listed between square brackets are optional. Lists between braces indicate that the argument must match one of the elements of the list. For example::')
+  print('')
+  print('  >> [X,Y]=dummy(int i, \'foo\' | \'bar\' [,vec v])')
+  print('')
+  print('means that the dummy function takes two or three arguments, its first being an integer value, the second a string which is either \'foo\' or \'bar\', and a third optional argument. It returns two values (with the usual matlab meaning, i.e. the caller can always choose to ignore them).')
+  print('')
+  print('')
   allc = sorted(objects+commands)
   for o in allc:
     for ext in ['', '_get', '_set']:
@@ -916,13 +939,13 @@ elif (option == 'matlab-doc'):
       [r, initiale] = StandardObjectName(o)
       if (os.path.exists(src_dir) and os.path.isfile(src_dir)):
         
-        print 'gf_' + o + ext
-        print '-------------------------------------------'
-        print ''
-        print '**Synopsis**'
-        print ''
-        print '::'
-        print ''
+        print('gf_' + o + ext)
+        print('-------------------------------------------')
+        print('')
+        print('**Synopsis**')
+        print('')
+        print('::')
+        print('')
         [gdoc, args] = ExtractGlobalDoc(src_dir);
         if (args != ''):
           args = FilterDoc(args, langage, objects, commands) + ', '
@@ -947,18 +970,18 @@ elif (option == 'matlab-doc'):
           [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
 
         fl.close()
-        print ''
-        print '**Description :**'
-        print ''
-        print ''
+        print('')
+        print('**Description :**')
+        print('')
+        print('')
         if ((o in set_objects) and (ext == '')):
-          print 'General constructor for ' + o + ' objects.\n'
+          print('General constructor for ' + o + ' objects.\n')
         gdoc = FilterDoc(gdoc, langage, objects, commands)
-        print gdoc
-        print ''
-        print '**Command list :**'
-        print ''
-        print ''
+        print(gdoc)
+        print('')
+        print('**Command list :**')
+        print('')
+        print('')
         fl = open(src_dir)
         doc = '';
         [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
@@ -972,9 +995,9 @@ elif (option == 'matlab-doc'):
           else:
             mname = ''
             params = params[1:].strip()
-          print ''
+          print('')
           print('  ``' + ret + 'gf_'+o+ext+firstarg+mname + params+')``')
-          print ''
+          print('')
           doc = FilterDoc(doc, langage, objects, commands)
           nbspace = -1; util_pos = -1; nbsp = -1
           for l in doc.split('\n'):
@@ -1002,12 +1025,12 @@ elif (option == 'matlab-doc'):
               
             if (nbsp > nbspace):
                 for i in range (nbsp-nbspace):
-                    print '',
+                    print(''),
             
             if (nbspace >= 0):
                 print('    '+l)
                 
-          print ''
+          print('')
           [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
     
         fl.close()
@@ -1370,67 +1393,67 @@ elif (option == 'scilab-doc-rst'):
 
   langage = 'scilab'
   
-  print '.. Automatically generated file, do not edit it.'
-  print '.. If some modification are necessary, please modify'
-  print '.. the corresponding C++ source or the python program extract_doc'
-  print ''
-  print ''
-  print '.. include:: ../replaces.txt'
-  print ''
-  print '.. highlightlang:: matlab'
-  print ''
-  print '.. _scilab-cmdref:'
-  print ''
-  print 'Command reference'
-  print '================='
-  print ''
-  print 'Please remember that this documentation is not self contained.'
-  print 'You should in particular refer to the `user documentation`_ '
-  print 'to have a more extensive description of the structures algorithms '
-  print 'and concepts used.'
-  print ''
-  # print 'Types'
-  # print '-----'
-  print ''
-  print 'The expected type of each function argument is indicated in this '
-  print 'reference. Here is a list of these types:'
-  print ''
-  print '=====================  =================================================='
-  print '`int`                  integer value'
-  print '`hobj`                 a handle for any GetFEM++ object'
-  print '`scalar`               scalar value'
-  print '`string`               string'
-  print '`ivec`                 vector of integer values'
-  print '`vec`                  vector'
-  print '`imat`                 matrix of integer values'
-  print '`mat`                  matrix'
-  print '`spmat`                sparse matrix (both matlab native sparse'
-  print '                       matrices, and GetFEM sparse matrices)'
-  print '`precond`              GetFEM preconditioner object'
-  print '`mesh mesh`            object descriptor (or gfMesh object)'
-  print '`mesh_fem`             mesh fem object descriptor (or gfMeshFem object)'
-  print '`mesh_im`              mesh im object descriptor (or gfMeshIm object)'
-  print '`mesh_im_data`         mesh im data object descriptor (or gfMeshImData object)'
-  print '`mesh_slice`           mesh slice object descriptor (or gfSlice object)'
-  print '`cvstruct`             convex structure descriptor (or gfCvStruct object)'
-  print '`geotrans`             geometric transformation descriptor (or '
-  print '                       gfGeoTrans object)'
-  print '`fem`                  fem descriptor (or gfFem object)'
-  print '`eltm`                 elementary matrix descriptor (or gfEltm object)'
-  print '`integ`                integration method descriptor (or gfInteg object)'
-  print '`model`                model descriptor (or gfModel object)'
-  print '`global_function`      global function descriptor'
-  print '`mesher_object`        mesher object descriptor'
-  print '`cont_struct`          continuation-structure descriptor'
-  print '=====================  =================================================='
-  print ''  
-  print 'Arguments listed between square brackets are optional. Lists between braces indicate that the argument must match one of the elements of the list. For example::'
-  print ''
-  print '  >> [X,Y]=dummy(int i, \'foo\' | \'bar\' [,vec v])'
-  print ''
-  print 'means that the dummy function takes two or three arguments, its first being an integer value, the second a string which is either \'foo\' or \'bar\', and a third optional argument. It returns two values (with the usual matlab meaning, i.e. the caller can always choose to ignore them).'
-  print ''
-  print ''
+  print('.. Automatically generated file, do not edit it.')
+  print('.. If some modification are necessary, please modify')
+  print('.. the corresponding C++ source or the python program extract_doc')
+  print('')
+  print('')
+  print('.. include:: ../replaces.txt')
+  print('')
+  print('.. highlightlang:: matlab')
+  print('')
+  print('.. _scilab-cmdref:')
+  print('')
+  print('Command reference')
+  print('=================')
+  print('')
+  print('Please remember that this documentation is not self contained.')
+  print('You should in particular refer to the `user documentation`_ ')
+  print('to have a more extensive description of the structures algorithms ')
+  print('and concepts used.')
+  print('')
+  # print('Types')
+  # print('-----')
+  print('')
+  print('The expected type of each function argument is indicated in this ')
+  print('reference. Here is a list of these types:')
+  print('')
+  print('=====================  ==================================================')
+  print('`int`                  integer value')
+  print('`hobj`                 a handle for any GetFEM++ object')
+  print('`scalar`               scalar value')
+  print('`string`               string')
+  print('`ivec`                 vector of integer values')
+  print('`vec`                  vector')
+  print('`imat`                 matrix of integer values')
+  print('`mat`                  matrix')
+  print('`spmat`                sparse matrix (both matlab native sparse')
+  print('                       matrices, and GetFEM sparse matrices)')
+  print('`precond`              GetFEM preconditioner object')
+  print('`mesh mesh`            object descriptor (or gfMesh object)')
+  print('`mesh_fem`             mesh fem object descriptor (or gfMeshFem object)')
+  print('`mesh_im`              mesh im object descriptor (or gfMeshIm object)')
+  print('`mesh_im_data`         mesh im data object descriptor (or gfMeshImData object)')
+  print('`mesh_slice`           mesh slice object descriptor (or gfSlice object)')
+  print('`cvstruct`             convex structure descriptor (or gfCvStruct object)')
+  print('`geotrans`             geometric transformation descriptor (or ')
+  print('                       gfGeoTrans object)')
+  print('`fem`                  fem descriptor (or gfFem object)')
+  print('`eltm`                 elementary matrix descriptor (or gfEltm object)')
+  print('`integ`                integration method descriptor (or gfInteg object)')
+  print('`model`                model descriptor (or gfModel object)')
+  print('`global_function`      global function descriptor')
+  print('`mesher_object`        mesher object descriptor')
+  print('`cont_struct`          continuation-structure descriptor')
+  print('=====================  ==================================================')
+  print('')
+  print('Arguments listed between square brackets are optional. Lists between braces indicate that the argument must match one of the elements of the list. For example::')
+  print('')
+  print('  >> [X,Y]=dummy(int i, \'foo\' | \'bar\' [,vec v])')
+  print('')
+  print('means that the dummy function takes two or three arguments, its first being an integer value, the second a string which is either \'foo\' or \'bar\', and a third optional argument. It returns two values (with the usual matlab meaning, i.e. the caller can always choose to ignore them).')
+  print('')
+  print('')
   allc = sorted(objects+commands)
   for o in allc:
     for ext in ['', '_get', '_set']:
@@ -1438,13 +1461,13 @@ elif (option == 'scilab-doc-rst'):
       [r, initiale] = StandardObjectName(o)
       if (os.path.exists(src_dir) and os.path.isfile(src_dir)):
         
-        print 'gf_' + o + ext
-        print '-------------------------------------------'
-        print ''
-        print '**Synopsis**'
-        print ''
-        print '::'
-        print ''
+        print('gf_' + o + ext)
+        print('-------------------------------------------')
+        print('')
+        print('**Synopsis**')
+        print('')
+        print('::')
+        print('')
         [gdoc, args] = ExtractGlobalDoc(src_dir);
         if (args != ''):
           args = FilterDoc(args, langage, objects, commands) + ', '
@@ -1469,18 +1492,18 @@ elif (option == 'scilab-doc-rst'):
           [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
 
         fl.close()
-        print ''
-        print '**Description :**'
-        print ''
-        print ''
+        print('')
+        print('**Description :**')
+        print('')
+        print('')
         if ((o in set_objects) and (ext == '')):
-          print 'General constructor for ' + o + ' objects.\n'
+          print('General constructor for ' + o + ' objects.\n')
         gdoc = FilterDoc(gdoc, langage, objects, commands)
-        print gdoc
-        print ''
-        print '**Command list :**'
-        print ''
-        print ''
+        print(gdoc)
+        print('')
+        print('**Command list :**')
+        print('')
+        print('')
         fl = open(src_dir)
         doc = '';
         [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
@@ -1494,9 +1517,9 @@ elif (option == 'scilab-doc-rst'):
           else:
             mname = ''
             params = params[1:].strip()
-          print ''
+          print('')
           print('  ``' + ret + 'gf_'+o+ext+firstarg+mname + params+')``')
-          print ''
+          print('')
           doc = FilterDoc(doc, langage, objects, commands)
           nbspace = -1; util_pos = -1; nbsp = -1
           for l in doc.split('\n'):
@@ -1524,12 +1547,12 @@ elif (option == 'scilab-doc-rst'):
               
             if (nbsp > nbspace):
                 for i in range (nbsp-nbspace):
-                    print '',
+                    print (''),
             
             if (nbspace >= 0):
                 print('    '+l)
 
-          print ''
+          print('')
           [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
     
         fl.close()
@@ -1551,7 +1574,7 @@ elif (option == 'scilab-doc-rst'):
 elif (option == 'python-com' or option == 'python-com-par'):
   langage = 'python'
 
-  print """#!/usr/bin/env python
+  print("""#!/usr/bin/env python
 # -*- coding: iso-8859-1 -*-
 #
 # Python GetFEM++ interface
@@ -1582,14 +1605,14 @@ elif (option == 'python-com' or option == 'python-com-par'):
 
 import sys
 import numpy
-"""
+""")
   if (option == 'python-com-par'):
-      print "import mpi4py.MPI as mpi"
-      print "getfem_python_par=True"
+      print("import mpi4py.MPI as mpi")
+      print("getfem_python_par=True")
   else:
-      print "getfem_python_par=False"
+      print("getfem_python_par=False")
 
-  print """
+  print("""
 
 try:
   import numbers
@@ -1605,12 +1628,12 @@ getfem('workspace', 'clear all')
 
 def generic_constructor(self, clname, *args):
     \"\"\"Internal function -- acts as a constructor for all GetFEM objects.\"\"\"
-    #print 'generic_constructor.'+clname+'('+str(args)+')'
+    #print('generic_constructor.'+clname+'('+str(args)+')')
     if (len(args)==1 and type(args[0]) is GetfemObject):
       if hasattr(self,'id'):
-        print \"warning: hasattr(self,'id')!\"
-        print \"self.id: \",self.id
-        print \"args[0]: \",args[0]
+        print(\"warning: hasattr(self,'id')!\")
+        print(\"self.id: \",self.id)
+        print(\"args[0]: \",args[0])
       else:
         self.id = args[0]
         #if obj_count.get(self.id,0)==0:
@@ -1623,14 +1646,14 @@ def generic_destructor(self, destructible=True):
     \"\"\"Internal function -- acts as a destructor for all GetFEM objects.\"\"\"
     if (not hasattr(self,'id')):
       return
-    #print \"Mesh.__del__       \",self.id,'count=',obj_count[self.id]
-    if (obj_count.has_key(self.id)):
+    #print(\"Mesh.__del__       \",self.id,'count=',obj_count[self.id])
+    if (self.id in obj_count):
       obj_count[self.id] = obj_count[self.id]-1
       if (destructible and obj_count[self.id] == 0):
         getfem('delete',self.id)
-        #print \"effective deletion\"
+        #print(\"effective deletion\")
 
-"""
+""")
 
   # one pass to find the set methods having identical name with a get method
   # in that case 'set_' is added to the set method.
@@ -1647,8 +1670,8 @@ def generic_destructor(self, destructible=True):
         fl = open(src_dir)
         [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
         while (ok):
-          mname = string.replace(mname, ' ', '_');
-          mname = string.replace(mname, '-', '_');
+          mname = mname.replace(' ', '_');
+          mname = mname.replace('-', '_');
           if (mname in sub_com or mname=='classical_fem' or mname=='classical_discontinuous_fem'):
             set_replace.add(oname+'::'+mname)
           sub_com.add(mname)
@@ -1679,14 +1702,14 @@ def generic_destructor(self, destructible=True):
     firstarg = '(' + args
 
 
-    print '\n#\n# GetFEM class ' + oname + ' definition.\n#\n'
-    print 'class ' + oname + ':'
-    print '  """GetFEM ' + oname + ' object\n'
+    print('\n#\n# GetFEM class ' + oname + ' definition.\n#\n')
+    print('class ' + oname + ':')
+    print('  """GeFEM ' + oname + ' object\n')
     gdoc = FilterDoc(gdoc, langage, objects, commands, set_replace)
-    print gdoc
-    print '  """'
-    print '  def __init__(self, *args):'
-    print '    """General constructor for ' + oname + " objects\n"
+    print(gdoc)
+    print('  """')
+    print('  def __init__(self, *args):')
+    print('    """General constructor for ' + oname + " objects\n")
     # documentation for constructors
     if (os.path.exists(src_dir) and os.path.isfile(src_dir)):
       fl = open(src_dir)
@@ -1729,37 +1752,37 @@ def generic_destructor(self, destructible=True):
 
           if (nbsp > nbspace):
               for i in range (nbsp-nbspace):
-                  print '',
+                  print(''),
 
           if (nbspace >= 0):
               print('    '+l)
               
-        print ''
+        print('')
         [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
 
       fl.close()
-    print '    """'
-    print '    generic_constructor(self,\'' + o + '\',*args)'
-    print '  def __del__(self):'
+    print('    """')
+    print('    generic_constructor(self,\'' + o + '\',*args)')
+    print('  def __del__(self):')
     if (o in non_destructible_objects):
-      print '    generic_destructor(self, destructible=False)'
+      print('    generic_destructor(self, destructible=False)')
     else:
-      print '    generic_destructor(self, destructible=True)'
+      print('    generic_destructor(self, destructible=True)')
     if (os.path.exists(directory + '/gf_' + o + '_get.cc')):
-      print '  def get(self, *args):'
-      print '    return getfem(\''+o+'_get\',self.id, *args)'
-      print '  def __repr__(self):'
-      print '    getfem(\''+o+'_get\',self.id, \'display\')'
-      print '    return \'\''
+      print('  def get(self, *args):')
+      print('    return getfem(\''+o+'_get\',self.id, *args)')
+      print('  def __repr__(self):')
+      print('    getfem(\''+o+'_get\',self.id, \'display\')')
+      print('    return \'\'')
     if (os.path.exists(directory + '/gf_' + o + '_set.cc')):
-      print '  def set(self, *args):'
-      print '    return getfem(\''+o+'_set\',self.id, *args)'
-    print '  def __str__(self):'
-    print '    return self.char()'
+      print('  def set(self, *args):')
+      print('    return getfem(\''+o+'_set\',self.id, *args)')
+    print('  def __str__(self):')
+    print('    return self.char()')
     if (os.path.exists(src_dir) and os.path.isfile(src_dir)):
       pythonext = ExtractExt(src_dir, langage);
       if (pythonext != ''):
-        print '\n' + pythonext
+        print('\n' + pythonext)
     # add the list of get and set methods
     sub_com = set()
     for ext in ['_get', '_set']:
@@ -1777,15 +1800,15 @@ def generic_destructor(self, destructible=True):
         doc = '';
         [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
         while (ok):
-          mname = string.replace(mname, ' ', '_');
-          mname = string.replace(mname, '-', '_');
+          mname = mname.replace(' ', '_');
+          mname = mname.replace('-', '_');
           set_extend = False
           if ((ext == '_set') and (oname+'::'+mname in set_replace)):
             set_extend = True
           sub_com.add(mname)
           mparams = FilterDoc(params, langage, objects, commands)
           params = SynopsisToPythonArgs(params)
-          print ''
+          print('')
           sys.stdout.write('  def ')
           mmname = mname
           if (set_extend): mmname = 'set_' + mname
@@ -1834,7 +1857,7 @@ def generic_destructor(self, destructible=True):
               if (nbspace >= 0):
                   sys.stdout.write('    ' + l)
                   
-          print '"""'
+          print('"""')
           sys.stdout.write('    return self.' + ext[1:] + '("' + mname + '"')
           for p in params:
             sys.stdout.write(', ' + p.split('=')[0])
@@ -1844,7 +1867,7 @@ def generic_destructor(self, destructible=True):
         fl.close()
         pythonext = ExtractExt(src_dir, langage);
         if (pythonext != ''):
-          print '\n' + pythonext
+          print('\n' + pythonext)
 
 
 
@@ -1852,7 +1875,7 @@ def generic_destructor(self, destructible=True):
   for c in co:
     src_dir = directory + '/gf_' + c + '.cc'
     if (c != 'workspace' and os.path.exists(src_dir) and os.path.isfile(src_dir)):
-      print '#\n# ' + c + ' module\n#\n'
+      print('#\n# ' + c + ' module\n#\n')
       [gdoc, args] = ExtractGlobalDoc(src_dir);
       margs = FilterDoc(args, langage, objects, commands).strip()
       args = SynopsisToPythonArgs(args)
@@ -1860,11 +1883,11 @@ def generic_destructor(self, destructible=True):
       doc = '';
       [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
       while (ok):
-        mname = string.replace(mname, ' ', '_');
-        mname = string.replace(mname, '-', '_');
+        mname = mname.replace(' ', '_');
+        mname = mname.replace('-', '_');
         mparams = FilterDoc(params, langage, objects, commands).strip()
         params = SynopsisToPythonArgs(params)
-        print ''
+        print('')
         if (mname[0] == '.'):
           sys.stdout.write('def ' + c + '(')
         else:
@@ -1924,7 +1947,7 @@ def generic_destructor(self, destructible=True):
             if (nbspace >= 0):
                 sys.stdout.write('  ' + l)
 
-        print '"""'
+        print('"""')
         sys.stdout.write('  return getfem(\'' + c + '\'')
         for p in args:
           sys.stdout.write(', ' + p.split('=')[0])
@@ -1938,30 +1961,30 @@ def generic_destructor(self, destructible=True):
       fl.close()
       pythonext = ExtractExt(src_dir, langage);
       if (pythonext != ''):
-        print '\n' + pythonext
+        print('\n' + pythonext)
 
 
 
 
-  print '\ndef memstats():'
-  print '  print "*** GetFEM view of the workspace:"'
-  print '  getfem(\'workspace\',\'stats\')'
-  print '  print "*** Python view of the workspace:"'
-  print '  for id,c in obj_count.iteritems():'
-  print '    if (c):'
-  print '      name=str(factory(id).__class__)'
-  print '      print "%s class %d, id %d : instances=%d" % (name,id.classid,id.objid,c)\n'
+  print('\ndef memstats():')
+  print('  print("*** GetFEM view of the workspace:")')
+  print('  getfem(\'workspace\',\'stats\')')
+  print('  print("*** Python view of the workspace:")')
+  print('  for id,c in obj_count.items():')
+  print('    if (c):')
+  print('      name=str(factory(id).__class__)')
+  print('      print("%s class %d, id %d : instances=%d" % (name,id.classid,id.objid,c))\n')
 
-  print 'def linsolve(what, *args):'
-  print '  return getfem(\'linsolve\', what, *args)'
-  print 'def compute(mf, U, what, *args):'
-  print '  return getfem(\'compute\', mf, U, what, *args)'
-  print 'def asm(what, *args):'
-  print '  return getfem(\'asm\', what, *args)'
-  print 'def util(what, *args):'
-  print '  return getfem(\'util\', what, *args)\n'
+  print('def linsolve(what, *args):')
+  print('  return getfem(\'linsolve\', what, *args)')
+  print('def compute(mf, U, what, *args):')
+  print('  return getfem(\'compute\', mf, U, what, *args)')
+  print('def asm(what, *args):')
+  print('  return getfem(\'asm\', what, *args)')
+  print('def util(what, *args):')
+  print('  return getfem(\'util\', what, *args)\n')
 
-  print '\ndef factory(id):'
+  print('\ndef factory(id):')
   sys.stdout.write('  t = ( ')
   ob = sorted(objects)
   first = True
@@ -1970,9 +1993,9 @@ def generic_destructor(self, destructible=True):
     if (not first): sys.stdout.write(',\n        ')
     sys.stdout.write(oname)
     first = False
-  print ')[id.classid]'
-  print '  return t(id)\n'
-  print 'register_python_factory(factory)'
+  print(')[id.classid]')
+  print('  return t(id)\n')
+  print('register_python_factory(factory)')
 
 
 
@@ -1992,17 +2015,17 @@ elif (option == 'python-doc'):
 
   langage = 'python'
 
-  print ".. Autogenerated by interface/bin/extract_doc. Do not edit it.\n"
-  print ".. include:: ../replaces.txt\n"
-  print ".. _api:\n"
-  print "API reference"
-  print "=============\n"
-  print ''
-  print 'Please remember that this documentation is not self contained.'
-  print 'You should in particular refer to the `user documentation`_ '
-  print 'to have a more extensive description of the structures algorithms '
-  print 'and concepts used.'
-  print ''
+  print(".. Autogenerated by interface/bin/extract_doc. Do not edit it.\n")
+  print(".. include:: ../replaces.txt\n")
+  print(".. _api:\n")
+  print("API reference")
+  print("=============\n")
+  print('')
+  print('Please remember that this documentation is not self contained.')
+  print('You should in particular refer to the `user documentation`_ ')
+  print('to have a more extensive description of the structures algorithms ')
+  print('and concepts used.')
+  print('')
 
   # one pass to find the set methods having identical name with a get method
   # in that case 'set_' is added to the set method.
@@ -2019,8 +2042,8 @@ elif (option == 'python-doc'):
         fl = open(src_dir)
         [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
         while (ok):
-          mname = string.replace(mname, ' ', '_');
-          mname = string.replace(mname, '-', '_');
+          mname = mname.replace(' ', '_');
+          mname = mname.replace('-', '_');
           if (mname in sub_com or mname=='classical_fem' or mname=='classical_discontinuous_fem'):
             set_replace.add(oname+'::'+mname)
           sub_com.add(mname)
@@ -2032,18 +2055,18 @@ elif (option == 'python-doc'):
   for o in ob:
     src_dir = directory + '/gf_' + o + '.cc'
     [oname, initiale] = StandardObjectName(o)
-    print ''
-    print oname
-    print '------------------------'
-    print '.. autoclass:: getfem.' + oname
-    print '  :members:\n'
+    print('')
+    print(oname)
+    print('------------------------')
+    print('.. autoclass:: getfem.' + oname)
+    print('  :members:\n')
     
   co = sorted(commands)
   for c in co:
     src_dir = directory + '/gf_' + c + '.cc'
     if (c != 'workspace' and os.path.exists(src_dir) and os.path.isfile(src_dir)):
-      print '\nModule ' + c
-      print '--------------------------\n'
+      print('\nModule ' + c)
+      print('--------------------------\n')
       [gdoc, args] = ExtractGlobalDoc(src_dir);
       gdoc = FilterDoc(gdoc, langage, objects, commands, set_replace)
       nbspace = -1; util_pos = -1; nbsp = -1
@@ -2078,14 +2101,14 @@ elif (option == 'python-doc'):
           if (nbspace >= 0):
               sys.stdout.write('  ' + l)
               
-      print ''
+      print('')
       fl = open(src_dir)
       doc = '';
       [ok, doc, dtype, mname, params, ret] = ExtractSubDoc(fl, langage)
       while (ok):
-        mname = string.replace(mname, ' ', '_');
-        mname = string.replace(mname, '-', '_');
-        print ''
+        mname = mname.replace(' ', '_');
+        mname = mname.replace('-', '_');
+        print('')
         if (mname[0] == '.'):
           print('.. autofunction:: getfem.' + c)
         else:
@@ -2096,4 +2119,4 @@ elif (option == 'python-doc'):
 
 
 else:
-    print 'Unrecognized option. Valid options are ' + valid_options
+    print('Unrecognized option. Valid options are ' + valid_options)
diff --git a/bin/fig2eps b/bin/fig2eps
index 6bd8c38..2c5f5ce 100755
--- a/bin/fig2eps
+++ b/bin/fig2eps
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# Copyright (C) 1998-2015 Yves Renard
+# Copyright (C) 1998-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/bin/mesh_matlab_to_getfem b/bin/mesh_matlab_to_getfem
index 1a38e9a..0f5b47c 100755
--- a/bin/mesh_matlab_to_getfem
+++ b/bin/mesh_matlab_to_getfem
@@ -1,11 +1,11 @@
 #!/usr/bin/perl
-# Copyright (C) 1998-2009 Yves Renard
+# Copyright (C) 1998-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
 # GetFEM++  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 2.1 of the License,  or
+# by  the  Free Software Foundation;  either version 3 of the License,  or
 # (at your option) any later version.
 # This program  is  distributed  in  the  hope  that it will be useful,  but
 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
diff --git a/bin/split_cmdref b/bin/split_cmdref
index 238e65e..3eaaa3b 100755
--- a/bin/split_cmdref
+++ b/bin/split_cmdref
@@ -1,13 +1,13 @@
 #!/usr/bin/env python
 # -*- python -*-
 #
-# Copyright (C) 2004-2015 Yves Renard.
+# Copyright (C) 2004-2017 Yves Renard.
 #                                                       
 # This file is a part of GetFEM++                                         
 #                                                                         
 # GetFEM++  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 2.1 of the License,  or
+# by  the  Free Software Foundation;  either version 3 of the License,  or
 # (at your option) any later version.
 # This program  is  distributed  in  the  hope  that it will be useful,  but
 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
diff --git a/config.guess b/config.guess
index 1659250..b79252d 100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2013-06-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -24,12 +24,12 @@ timestamp='2015-08-20'
 # program.  This Exception is an additional permission under section 7
 # of the GNU General Public License, version 3 ("GPLv3").
 #
-# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+# Originally written by Per Bothner.
 #
 # You can get the latest version of this script from:
 # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 #
-# Please send patches to <config-patches at gnu.org>.
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
 
 
 me=`echo "$0" | sed -e 's,.*/,,'`
@@ -50,7 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -149,7 +149,7 @@ Linux|GNU|GNU/*)
 	LIBC=gnu
 	#endif
 	EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
 	;;
 esac
 
@@ -168,27 +168,20 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
 	sysctl="sysctl -n hw.machine_arch"
-	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
-	    /sbin/$sysctl 2>/dev/null || \
-	    /usr/sbin/$sysctl 2>/dev/null || \
-	    echo unknown)`
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
 	case "${UNAME_MACHINE_ARCH}" in
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
 	    sh5el) machine=sh5le-unknown ;;
-	    earmv*)
-		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
-		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
-		machine=${arch}${endian}-unknown
-		;;
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
 	# to ELF recently, or will in the future.
 	case "${UNAME_MACHINE_ARCH}" in
-	    arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
@@ -204,13 +197,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		os=netbsd
 		;;
 	esac
-	# Determine ABI tags.
-	case "${UNAME_MACHINE_ARCH}" in
-	    earm*)
-		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
-		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
-		;;
-	esac
 	# The OS release
 	# Debian GNU/NetBSD machines have a different userland, and
 	# thus, need a distinct triplet. However, they do not need
@@ -221,13 +207,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		release='-gnu'
 		;;
 	    *)
-		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
 		;;
 	esac
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "${machine}-${os}${release}${abi}"
+	echo "${machine}-${os}${release}"
 	exit ;;
     *:Bitrig:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@@ -249,9 +235,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:MirBSD:*:*)
 	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
 	exit ;;
-    *:Sortix:*:*)
-	echo ${UNAME_MACHINE}-unknown-sortix
-	exit ;;
     alpha:OSF1:*:*)
 	case $UNAME_RELEASE in
 	*4.0)
@@ -596,9 +579,8 @@ EOF
 	else
 		IBM_ARCH=powerpc
 	fi
-	if [ -x /usr/bin/lslpp ] ; then
-		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
-			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
 	else
 		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
@@ -844,7 +826,7 @@ EOF
     *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
-    *:MSYS*:*)
+    i*:MSYS*:*)
 	echo ${UNAME_MACHINE}-pc-msys
 	exit ;;
     i*:windows32*:*)
@@ -950,9 +932,6 @@ EOF
     crisv32:Linux:*:*)
 	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
 	exit ;;
-    e2k:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
-	exit ;;
     frv:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
@@ -990,10 +969,10 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
-    openrisc*:Linux:*:*)
-	echo or1k-unknown-linux-${LIBC}
+    or1k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
-    or32:Linux:*:* | or1k*:Linux:*:*)
+    or32:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     padre:Linux:*:*)
@@ -1041,7 +1020,7 @@ EOF
 	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
 	exit ;;
     x86_64:Linux:*:*)
-	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     xtensa*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
@@ -1281,26 +1260,16 @@ EOF
 	if test "$UNAME_PROCESSOR" = unknown ; then
 	    UNAME_PROCESSOR=powerpc
 	fi
-	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		    grep IS_64BIT_ARCH >/dev/null
-		then
-		    case $UNAME_PROCESSOR in
-			i386) UNAME_PROCESSOR=x86_64 ;;
-			powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		    esac
-		fi
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		case $UNAME_PROCESSOR in
+		    i386) UNAME_PROCESSOR=x86_64 ;;
+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		esac
 	    fi
-	elif test "$UNAME_PROCESSOR" = i386 ; then
-	    # Avoid executing cc on OS X 10.9, as it ships with a stub
-	    # that puts up a graphical alert prompting to install
-	    # developer tools.  Any system running Mac OS X 10.7 or
-	    # later (Darwin 11 and later) is required to have a 64-bit
-	    # processor. This is not true of the ARM version of Darwin
-	    # that Apple uses in portable devices.
-	    UNAME_PROCESSOR=x86_64
 	fi
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
 	exit ;;
@@ -1392,6 +1361,154 @@ EOF
 	exit ;;
 esac
 
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+	"4"
+#else
+	""
+#endif
+	); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
 cat >&2 <<EOF
 $0: unable to guess system type
 
diff --git a/config.h.in b/config.h.in
index 97c2ec4..24ea795 100644
--- a/config.h.in
+++ b/config.h.in
@@ -40,9 +40,6 @@
 /* Define to 1 if you have the `mpi_cxx' library (-lmpi_cxx). */
 #undef HAVE_LIBMPI_CXX
 
-/* Define to 1 if you have the `qhull' library (-lqhull). */
-#undef HAVE_LIBQHULL
-
 /* Define to 1 if you have the <libqhull/qhull_a.h> header file. */
 #undef HAVE_LIBQHULL_QHULL_A_H
 
@@ -127,7 +124,8 @@
 /* Define to 1 if you have the <zmumps_c.h> header file. */
 #undef HAVE_ZMUMPS_C_H
 
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
 #undef LT_OBJDIR
 
 /* Name of package */
diff --git a/config.sub b/config.sub
index 1acc966..9633db7 100755
--- a/config.sub
+++ b/config.sub
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2013-08-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@ timestamp='2015-08-20'
 # of the GNU General Public License, version 3 ("GPLv3").
 
 
-# Please send patches to <config-patches at gnu.org>.
+# Please send patches with a ChangeLog entry to config-patches at gnu.org.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches at gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2013 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
   kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
@@ -255,18 +255,16 @@ case $basic_machine in
 	| arc | arceb \
 	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
 	| avr | avr32 \
-	| ba \
 	| be32 | be64 \
 	| bfin \
 	| c4x | c8051 | clipper \
 	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
+	| epiphany \
+	| fido | fr30 | frv \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| hexagon \
 	| i370 | i860 | i960 | ia64 \
 	| ip2k | iq2000 \
-	| k1om \
 	| le32 | le64 \
 	| lm32 \
 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -284,10 +282,8 @@ case $basic_machine in
 	| mips64vr5900 | mips64vr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
 	| mipsisa64 | mipsisa64el \
 	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipsr5900 | mipsr5900el \
@@ -299,14 +295,14 @@ case $basic_machine in
 	| nds32 | nds32le | nds32be \
 	| nios | nios2 | nios2eb | nios2el \
 	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
+	| open8 \
+	| or1k | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
-	| riscv32 | riscv64 \
 	| rl78 | rx \
 	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 	| sh64 | sh64le \
 	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
 	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -314,7 +310,6 @@ case $basic_machine in
 	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
 	| ubicom32 \
 	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
 	| we32k \
 	| x86 | xc16x | xstormy16 | xtensa \
 	| z8k | z80)
@@ -329,10 +324,7 @@ case $basic_machine in
 	c6x)
 		basic_machine=tic6x-unknown
 		;;
-	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
-		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
@@ -377,20 +369,18 @@ case $basic_machine in
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 	| avr-* | avr32-* \
-	| ba-* \
 	| be32-* | be64-* \
 	| bfin-* | bs2000-* \
 	| c[123]* | c30-* | [cjt]90-* | c4x-* \
 	| c8051-* | clipper-* | craynv-* | cydra-* \
 	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
+	| elxsi-* \
 	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| hexagon-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
 	| ip2k-* | iq2000-* \
-	| k1om-* \
 	| le32-* | le64-* \
 	| lm32-* \
 	| m32c-* | m32r-* | m32rle-* \
@@ -410,10 +400,8 @@ case $basic_machine in
 	| mips64vr5900-* | mips64vr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
 	| mipsisa64-* | mipsisa64el-* \
 	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipsr5900-* | mipsr5900el-* \
@@ -425,18 +413,16 @@ case $basic_machine in
 	| nios-* | nios2-* | nios2eb-* | nios2el-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
 	| open8-* \
-	| or1k*-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
 	| pyramid-* \
-	| riscv32-* | riscv64-* \
 	| rl78-* | romp-* | rs6000-* | rx-* \
 	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
 	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
 	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
 	| tahoe-* \
 	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 	| tile*-* \
@@ -444,7 +430,6 @@ case $basic_machine in
 	| ubicom32-* \
 	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
 	| vax-* \
-	| visium-* \
 	| we32k-* \
 	| x86-* | x86_64-* | xc16x-* | xps100-* \
 	| xstormy16-* | xtensa*-* \
@@ -521,9 +506,6 @@ case $basic_machine in
 		basic_machine=i386-pc
 		os=-aros
 		;;
-        asmjs)
-		basic_machine=asmjs-unknown
-		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -785,9 +767,6 @@ case $basic_machine in
 		basic_machine=m68k-isi
 		os=-sysv
 		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
-		;;
 	m68knommu)
 		basic_machine=m68k-unknown
 		os=-linux
@@ -843,10 +822,6 @@ case $basic_machine in
 		basic_machine=powerpc-unknown
 		os=-morphos
 		;;
-	moxiebox)
-		basic_machine=moxie-unknown
-		os=-moxiebox
-		;;
 	msdos)
 		basic_machine=i386-pc
 		os=-msdos
@@ -1379,7 +1354,7 @@ case $os in
 	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
 	      | -sym* | -kopensolaris* | -plan9* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* | -cloudabi* | -sortix* \
+	      | -aos* | -aros* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
@@ -1392,14 +1367,14 @@ case $os in
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1617,6 +1592,9 @@ case $basic_machine in
 	mips*-*)
 		os=-elf
 		;;
+	or1k-*)
+		os=-elf
+		;;
 	or32-*)
 		os=-coff
 		;;
diff --git a/configure.ac b/configure.ac
index 1f74ed8..1dd5cb4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,3 +1,22 @@
+dnl  Copyright (C) 1999-2017 Yves Renard
+dnl
+dnl  This file is a part of GetFEM++
+dnl
+dnl  GetFEM++  is  free software;  you  can  redistribute  it  and/or modify it
+dnl  under  the  terms  of the  GNU  Lesser General Public License as published
+dnl  by  the  Free Software Foundation;  either version 3 of the License,  or
+dnl  (at your option) any later version along with the GCC Runtime Library
+dnl  Exception either version 3.1 or (at your option) any later version.
+dnl  This program  is  distributed  in  the  hope  that it will be useful,  but
+dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl  or  FITNESS  FOR  A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+dnl  License and GCC Runtime Library Exception for more details.
+dnl  You  should  have received a copy of the GNU Lesser General Public License
+dnl  along  with  this program;  if not, write to the Free Software Foundation,
+dnl  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+
 dnl Process this file with autoconf to produce a configure script.
 dnl ------------------------------------------------------------------------
 dnl initialisation
@@ -8,9 +27,9 @@ dnl thus, updating cache ./config.cache avoided.
 define([AC_CACHE_LOAD], )dnl
 define([AC_CACHE_SAVE], )dnl
 
-AC_INIT(getfem, 5.1)
+AC_INIT(getfem, 5.2)
 MAJOR_VERSION="5"
-MINOR_VERSION="1"
+MINOR_VERSION="2"
 PATCH_VERSION=""
 
 AC_CONFIG_SRCDIR([install-sh])
@@ -126,11 +145,14 @@ case $CXX in
 	AC_CHECK_CXX_FLAG([$with_optimization],CXXFLAGS)
 	AC_CHECK_CXX_FLAG([-Wall -W],CXXFLAGS)
 	AC_CHECK_CXX_FLAG([-fmessage-length=0],CXXFLAGS)
+	AC_CHECK_CXX_FLAG([-fvisibility-inlines-hidden],CXXFLAGS)
 	AC_CHECK_CXX_FLAG([-ftemplate-depth-100],CXXFLAGS)
 	AC_CHECK_CXX_FLAG([-std=c++11], CXXFLAGS,[AC_CHECK_CXX_FLAG([-std=c++0x],CXXFLAGS,[AC_MSG_ERROR([g++ do not support option -std=c++11. Update g++ to at least release 4.8.1.])] )])
 	AC_CHECK_CXX_FLAG([-fPIC],CXXFLAGS)
 	AC_CHECK_CXX_FLAG([-pedantic],CXXFLAGS)
 	AC_CHECK_CXX_FLAG([-Wshadow],CXXFLAGS)
+	AC_CHECK_CXX_FLAG([-Wno-terminate],CXXFLAGS)
+	AC_CHECK_CXX_FLAG([-Wno-implicit-fallthrough],CXXFLAGS)
 	AC_CHECK_CXX_FLAG([-Wno-unknown-pragmas],CXXFLAGS)
 	AC_CHECK_CXX_FLAG([-Wno-variadic-macros],CXXFLAGS)
 	AC_CHECK_CXX_FLAG([-Wno-unused-but-set-variable],CXXFLAGS)
@@ -172,6 +194,7 @@ dnl option pic-only is not working: a libtool bug ...
 LT_INIT([pic-only disable-shared])
 AC_SUBST([LIBTOOL_DEPS])
 
+
 dnl -------------------------------BLAS----------------------------------
 
 dnl why I hate autoconf: if the code below is put into a separate file,
@@ -309,6 +332,39 @@ dnl ACX_BLAS([ echo "OK, You have working BLAS libs !"; HAVE_VENDOR_BLAS=1 ], [e
 LIBS="$LIBS $BLAS_LIBS"
 CPPFLAGS="$CPPFLAGS -DGMM_USES_BLAS"
 
+useblasinterface=NO
+AC_ARG_ENABLE(blas_interface,
+ [AS_HELP_STRING([--enable-blas-interface],[enable the use of the blas call for basic algebra routines.])],
+ [case $enableval in
+   yes | "") useblasinterface=YES ;;
+   no) useblasinterface=NO ;;
+  esac],
+ [useblasinterface=YES]
+)
+
+if test x$useblasinterface = xYES; then
+  CPPFLAGS="$CPPFLAGS -DGMM_USES_BLAS_INTERFACE"
+fi
+
+dnl ------------------------------LAPACK TEST--------------------------------
+
+if test x"$acx_blas_ok" = xyes; then
+  if test x"$FC" = "x"; then
+    dgetrf=dgetrf_
+  else
+    AC_FC_FUNC(dgetrf)
+  fi;
+
+  AC_CHECK_LIB(lapack, dgetrf_, [acx_lapack_ok=yes; LAPACK_LIBS="-llapack "])
+
+  if test x"$acx_lapack_ok" = xyes; then
+     CPPFLAGS="$CPPFLAGS -DGMM_USES_LAPACK"
+     LIBS="$LAPACK_LIBS $LIBS"
+  fi
+fi
+
+dnl -----------------------------END OF LAPACK TEST--------------------------
+
 
 dnl ---------------------------OPENMP------------------------------
 useopenmp=0
@@ -379,6 +435,9 @@ if test x$usesuperlu = xYES; then
     *apple*)
         SUPERLU_LIBS="../$SUPERLU_SRC/libsuperlu.la"
         ;;
+    *mingw*)
+        SUPERLU_LIBS="../$SUPERLU_SRC/.libs/libsuperlu.a"
+        ;;
     *)
         SUPERLU_LIBS="`readlink -f .`/$SUPERLU_SRC/libsuperlu.la"
         ;;
@@ -401,7 +460,7 @@ else
   ])
 
   SUPERLU_LIBS="-lsuperlu"
-  LIBS="$LIBS $SUPERLU_LIBS"
+  LIBS="$SUPERLU_LIBS $LIBS"
 fi
 
 AC_SUBST([SUPERLU_CPPFLAGS])
@@ -474,11 +533,15 @@ AC_ARG_ENABLE(qhull,
  [AS_HELP_STRING([--enable-qhull],[enable the use of the qhull library (required for generation of non regular meshes)])],
  [ if   test "x$enableval" = "xyes" ; then useQHULL="yes"; fi], [useQHULL="test"])
 QHULL_LIBS=""
+save_LIBS="$LIBS";
 
 if test "x$useQHULL" = "xno"; then
   echo "Building with libqhull explicitly disabled";
 else
-  AC_CHECK_LIB(qhull, qh_new_qhull)
+  AC_CHECK_LIB(qhull, qh_new_qhull, [QHULL_LIBS="-lqhull"],
+  [
+    AC_CHECK_LIB(qhullstatic, qh_new_qhull,[QHULL_LIBS="-lqhullstatic"],[QHULL_LIBS=""])
+  ])
   AC_CHECK_HEADERS(libqhull/qhull_a.h,[useQHULL="yes"],
   [
     if test "x$useQHULL" = "xyes"; then
@@ -486,13 +549,11 @@ else
       useQHULL="no"
     fi;
   ])
-  if test "x$useQHULL" = "xyes"; then
-    QHULL_LIBS="-lqhull"
-  fi;
   echo "Building with libqhull (use --enable-qhull=no to disable it)"
 fi;
 AM_CONDITIONAL(QHULL, test x$useQHULL = xyes)
 
+LIBS="$QHULL_LIBS $save_LIBS"
 AC_SUBST([QHULL_LIBS])
 echo "Configuration of qhull done"
 dnl -----------------------------END OF QHULL TEST---------------------------
@@ -510,15 +571,26 @@ AC_ARG_WITH(mumps-include-dir,
 CPPFLAGS="$CPPFLAGS $MUMPSINC"
 
 MUMPS_LIBS=""
+case $host in
+    *mingw*)
+        MUMPS_SEQ_LIBS="-lsmumps -ldmumps -lcmumps -lzmumps -lmumps_common -lmpiseq -lpord"
+        ;;
+    *apple*)
+        MUMPS_SEQ_LIBS="-lsmumps -ldmumps -lcmumps -lzmumps -lmumps_common -lmpiseq -lpord"
+        ;;
+    *)
+        MUMPS_SEQ_LIBS="-lsmumps_seq -ldmumps_seq -lcmumps_seq -lzmumps_seq"
+        ;;
+esac
 acx_mumps_ok="no"
 usemumps="no"
 AC_ARG_ENABLE(mumps,
  [AS_HELP_STRING([--enable-mumps],[enable the use of the (sequential) MUMPS library. A direct solver for large sparse linear systems.])],
  [case $enableval in
-   yes | "") usemumps="yes"; acx_mumps_ok="yes"; MUMPS_LIBS="-lsmumps_seq -ldmumps_seq -lcmumps_seq -lzmumps_seq";;
+   yes | "") usemumps="yes"; acx_mumps_ok="yes"; MUMPS_LIBS="$MUMPS_SEQ_LIBS";;
    no) usemumps="no";;
   esac],
- [usemumps="test"; acx_mumps_ok="test"; MUMPS_LIBS="-lsmumps_seq -ldmumps_seq -lcmumps_seq -lzmumps_seq"]
+ [usemumps="test"; acx_mumps_ok="test"; MUMPS_LIBS="$MUMPS_SEQ_LIBS"]
 )
 
 AC_ARG_ENABLE(par-mumps,
@@ -542,7 +614,7 @@ AC_ARG_WITH(mumps,
   esac]
 )
 
-
+save_LIBS="$LIBS";
 if test "x$usemumps" = "xno" -o "x$acx_mumps_ok" = "xno"; then
   echo "Building with MUMPS explicitly disabled";
 else
@@ -584,8 +656,10 @@ else
 
  if test "x$usemumps" = "xyes"; then
    echo "Building with MUMPS (use --enable-mumps=no to disable it)"
+   LIBS="$MUMPS_LIBS $save_LIBS"
  else
    MUMPS_LIBS=""
+   LIBS="$save_LIBS"
  fi;
 fi;
 
@@ -645,26 +719,6 @@ AC_SUBST([METIS_LIBS])
 dnl ---------------------------END OF METIS--------------------------
 
 
-dnl ------------------------------LAPACK TEST--------------------------------
-
-if test x"$acx_blas_ok" = xyes; then
-  if test x"$FC" = "x"; then
-    dgetrf=dgetrf_
-  else
-    AC_FC_FUNC(dgetrf)
-  fi;
-
-  AC_CHECK_LIB(lapack, dgetrf_, [acx_lapack_ok=yes; LAPACK_LIBS="-llapack "])
-
-  if test x"$acx_lapack_ok" = xyes; then
-     CPPFLAGS="$CPPFLAGS -DGMM_USES_LAPACK"
-     LIBS="$LIBS $LAPACK_LIBS"
-  fi
-fi
-
-dnl -----------------------------END OF LAPACK TEST--------------------------
-
-
 AC_CHECK_HEADERS(sys/times.h,[],[SUPERLU_CPPFLAGS="$SUPERLU_CPPFLAGS -DNO_TIMER"])
 AC_CHECK_HEADERS(cxxabi.h)
 dnl ---------------------------- CHECK FOR __PRETTY_FUNCTION__ MACRO --------
@@ -781,14 +835,6 @@ AC_ARG_WITH(matlab-toolbox-dir,
             TOOLBOXDIR="$withval",TOOLBOXDIR="$GFPREFIX/getfem_toolbox")
 AC_SUBST(TOOLBOXDIR)
 
-AC_ARG_ENABLE(python,
- [AS_HELP_STRING([--enable-python],[turn on/off python support])],
- [case "${enableval}" in
-   yes) usepython=YES ;;
-   no)  usepython=NO ;;
-   *) AC_MSG_ERROR([bad value ${enableval} for --enable-python]) ;;
- esac],[usepython=YES])
-
 if test "$usematlab" != NO; then
   AC_CHECK_PROGS(MEX, mex)
   if test x"$MEX" = x""; then
@@ -824,8 +870,8 @@ if test "$usematlab" != NO; then
      if $(echo "" | $MEX 2>&1 | grep 'This is .*TeX'); then
 	  AC_MSG_ERROR([the mex binary which is in the PATH appears to be part of LaTeX, not matlab !! run ./configure MEX=/path/to/matlab/mex]);
      fi;
-     MATLAB_ROOT=`$MEX -v 2>&1 | grep "MATLAB " | awk '{print $4}'|sed -e '2,$d'`
-     MATLAB_INC_DIR=$MATLAB_ROOT/extern/include
+     MATLAB_ROOT=`$MEX -v 2>&1 | grep "MATLAB  " | awk '{print $4}'|sed -e '2,$d'`
+     Matlab_INC_DIR=$MATLAB_ROOT/extern/include
      echo "checking for matlab path... " $MATLAB_ROOT
      MATLAB_COM_EXT=`$MEX -v 2>&1 | grep "LDEXTENSION " | awk '{print $3}'`
      echo "checking for mex extension... " $MATLAB_COM_EXT
@@ -836,8 +882,6 @@ if test "$usematlab" != NO; then
 fi
 AM_CONDITIONAL(BUILDMEX, test x$usematlab = xYES)
 
-
-
 AC_SUBST(MATLAB_ROOT)
 AC_SUBST(MATLAB_INC_DIR)
 AC_SUBST(MATLAB_RELEASE)
@@ -932,25 +976,55 @@ dnl ----------------------------------------------
 dnl python 
 dnl ----------------------------------------------
 
-if test x$usepython = xYES; then
-  AM_PATH_PYTHON(2.2, usepython=YES, usepython=NO)
+AC_ARG_ENABLE(python,
+ [AS_HELP_STRING([--enable-python],[turn on/off python support])],
+ [case "${enableval}" in
+   yes) usepython=YES ;;
+   no)  usepython=NO ;;
+   *) AC_MSG_ERROR([bad value ${enableval} for --enable-python]) ;;
+ esac],[usepython=YES])
+
+AC_ARG_ENABLE(python3,
+ [AS_HELP_STRING([--enable-python3],[turn on/off python3 (instead of python2) support])],
+ [case "${enableval}" in
+   yes) usepython3=YES ;;
+   no)  usepython3=NO ;;
+   *) AC_MSG_ERROR([bad value ${enableval} for --enable-python3]) ;;
+ esac],[usepython3=NO])
+
+if test x$usepython3 = xYES; then
+  AM_PATH_PYTHON(3.4, usepython=YES, usepython=NO)
+elif test x$usepython = xYES; then
+  AM_PATH_PYTHON(2.7, usepython=YES, usepython=NO)
 fi
-echo $PYTHON
 
+case $host in
+    *mingw*)
+        PYTHON_CC_ARG="--compiler=mingw32"
+	PYTHON_EXTRA_EXT_PARAM="extra_compile_args=[['-D MS_WIN64']]"
+        ;;
+    *)
+        PYTHON_CC_ARG=""
+	PYTHON_EXTRA_EXT_PARAM=""
+        ;;
+esac
+
+AC_SUBST(PYTHON_CC_ARG)
+AC_SUBST(PYTHON_EXTRA_EXT_PARAM)
 
 if test "x$usepython" = "xYES"; then
-  echo "Building with python support (use --enable-python=no to disable it)"
+  echo "Building with python ($PYTHON) support (use --enable-python=no to disable it) "
   echo "You will need the python-numpy and python-scipy packages."
 dnl  AM_PATH_PYTHON(2.2)
   AC_PYTHON_DEVEL
-  ac_python_numpy=`$PYTHON -c 'import numpy; print "YES"' 2>/dev/null`
+  ac_python_numpy=`$PYTHON -c 'import numpy; print("YES")' 2>/dev/null`
   if  test "x$ac_python_numpy" != "xYES"; then
     usepython=NO
     MSG="PYTHON DISABLED: numpy not found. You need to install the python-numpy package."
     echo $MSG
     WARNING_MSG="$WARNING_MSG\n$MSG"
   fi
-  ac_python_scipy=`$PYTHON -c 'import scipy; print "YES"' 2>/dev/null`
+  ac_python_scipy=`$PYTHON -c 'import scipy; print("YES")' 2>/dev/null`
   if  test "x$ac_python_scipy" != "xYES"; then
     usepython=NO
     MSG="PYTHON DISABLED: scipy not found. You need to install the python-scipy package."
@@ -958,7 +1032,7 @@ dnl  AM_PATH_PYTHON(2.2)
     WARNING_MSG="$WARNING_MSG\n$MSG"
   fi
   if  test $paralevel -ge 1; then
-    ac_python_mpi4py=`$PYTHON -c 'import mpi4py; print "YES"' 2>/dev/null`
+    ac_python_mpi4py=`$PYTHON -c 'import mpi4py; print("YES")' 2>/dev/null`
     if test "x$ac_python_mpi4py" != "xYES"; then
       usepython=NO
       MSG="PARALLEL PYTHON DISABLED: mpi4py not found. You need to install the python-mpi4py package."
@@ -1040,6 +1114,7 @@ contrib/aposteriori/Makefile                                            \
 contrib/level_set_contact/Makefile                                      \
 contrib/static_contact_gears/Makefile                                   \
 contrib/test_plasticity/Makefile                                        \
+contrib/opt_assembly/Makefile                                           \
 bin/Makefile                                                            \
 interface/Makefile                                                      \
 interface/src/Makefile                                                  \
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index 63a75c3..2d1b6b6 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 SUBDIRS = icare delaminated_crack aposteriori xfem_stab_unilat_contact      \
 	  bimaterial_crack_test mixed_elastostatic xfem_contact crack_plate \
-	  static_contact_gears level_set_contact test_plasticity
+	  static_contact_gears level_set_contact test_plasticity opt_assembly
diff --git a/contrib/Makefile.in b/contrib/Makefile.in
index 954873b..122aeb1 100644
--- a/contrib/Makefile.in
+++ b/contrib/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -88,6 +95,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = contrib
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -103,7 +112,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -163,7 +171,6 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -256,7 +263,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -289,8 +295,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -371,7 +379,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -382,7 +389,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 SUBDIRS = icare delaminated_crack aposteriori xfem_stab_unilat_contact      \
 	  bimaterial_crack_test mixed_elastostatic xfem_contact crack_plate \
-	  static_contact_gears level_set_contact test_plasticity
+	  static_contact_gears level_set_contact test_plasticity opt_assembly
 
 all: all-recursive
 
@@ -399,6 +406,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -693,8 +701,6 @@ uninstall-am:
 	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
 	ps ps-am tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/aposteriori/Makefile.am b/contrib/aposteriori/Makefile.am
index d5b0da3..da5a1fd 100644
--- a/contrib/aposteriori/Makefile.am
+++ b/contrib/aposteriori/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 
 check_PROGRAMS = aposteriori aposteriori_laplacian
diff --git a/contrib/aposteriori/Makefile.in b/contrib/aposteriori/Makefile.in
index f20ab95..2138b14 100644
--- a/contrib/aposteriori/Makefile.in
+++ b/contrib/aposteriori/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,9 @@ build_triplet = @build@
 host_triplet = @host@
 check_PROGRAMS = aposteriori$(EXEEXT) aposteriori_laplacian$(EXEEXT)
 subdir = contrib/aposteriori
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +116,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -387,8 +396,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -456,7 +463,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -489,8 +495,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -571,7 +579,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -611,6 +618,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/aposteriori/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/aposteriori/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -764,7 +772,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1061,8 +1069,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/aposteriori/aposteriori.cc b/contrib/aposteriori/aposteriori.cc
index 7b768f3..94e8bf1 100644
--- a/contrib/aposteriori/aposteriori.cc
+++ b/contrib/aposteriori/aposteriori.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Vanessa Lleras, Yves Renard.
+ Copyright (C) 2002-2017 Vanessa Lleras, Yves Renard.
 
  This file is a part of GetFEM++
 
@@ -40,7 +40,8 @@
 
 using std::endl; using std::cout; using std::cerr;
 using std::ends; using std::cin;
-
+template <typename T> std::ostream &operator <<
+  (std::ostream &o, const std::vector<T>& m) { gmm::write(o,m); return o; }
 
 /* some GetFEM++ types that we will be using */
 using bgeot::base_small_vector; /* special class for small (dim<16) vectors */
diff --git a/contrib/aposteriori/aposteriori.param b/contrib/aposteriori/aposteriori.param
index 2b429a1..2e396df 100644
--- a/contrib/aposteriori/aposteriori.param
+++ b/contrib/aposteriori/aposteriori.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program crack                                            %
diff --git a/contrib/aposteriori/aposteriori.pl b/contrib/aposteriori/aposteriori.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/aposteriori/aposteriori.pl
+++ b/contrib/aposteriori/aposteriori.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/aposteriori/aposteriori_laplacian.cc b/contrib/aposteriori/aposteriori_laplacian.cc
index d9cb021..89dee93 100644
--- a/contrib/aposteriori/aposteriori_laplacian.cc
+++ b/contrib/aposteriori/aposteriori_laplacian.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Vanessa Lleras, Yves Renard.
+ Copyright (C) 2002-2017 Vanessa Lleras, Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/aposteriori/aposteriori_laplacian.param b/contrib/aposteriori/aposteriori_laplacian.param
old mode 100755
new mode 100644
index 78afe92..66ce7e6
--- a/contrib/aposteriori/aposteriori_laplacian.param
+++ b/contrib/aposteriori/aposteriori_laplacian.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program crack                                            %
diff --git a/contrib/aposteriori/aposteriori_laplacian.pl b/contrib/aposteriori/aposteriori_laplacian.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/aposteriori/aposteriori_laplacian.pl
+++ b/contrib/aposteriori/aposteriori_laplacian.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/bimaterial_crack_test/Makefile.am b/contrib/bimaterial_crack_test/Makefile.am
index 4faf6e2..395ea4c 100644
--- a/contrib/bimaterial_crack_test/Makefile.am
+++ b/contrib/bimaterial_crack_test/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 
 check_PROGRAMS =                 \
diff --git a/contrib/bimaterial_crack_test/Makefile.in b/contrib/bimaterial_crack_test/Makefile.in
index 992cdbf..ec70a56 100644
--- a/contrib/bimaterial_crack_test/Makefile.in
+++ b/contrib/bimaterial_crack_test/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,9 @@ build_triplet = @build@
 host_triplet = @host@
 check_PROGRAMS = bimaterial_crack_test$(EXEEXT) crack$(EXEEXT)
 subdir = contrib/bimaterial_crack_test
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +116,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -407,8 +416,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -476,7 +483,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -509,8 +515,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -591,7 +599,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -631,6 +638,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/bimaterial_crack_test/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/bimaterial_crack_test/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -786,7 +794,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1083,8 +1091,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/bimaterial_crack_test/bimaterial_crack_test.cc b/contrib/bimaterial_crack_test/bimaterial_crack_test.cc
index c2d7898..4118e3a 100644
--- a/contrib/bimaterial_crack_test/bimaterial_crack_test.cc
+++ b/contrib/bimaterial_crack_test/bimaterial_crack_test.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/bimaterial_crack_test/bimaterial_crack_test.param b/contrib/bimaterial_crack_test/bimaterial_crack_test.param
index 56c815f..161eb0f 100644
--- a/contrib/bimaterial_crack_test/bimaterial_crack_test.param
+++ b/contrib/bimaterial_crack_test/bimaterial_crack_test.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program crack                                            %
diff --git a/contrib/bimaterial_crack_test/bimaterial_crack_test.pl b/contrib/bimaterial_crack_test/bimaterial_crack_test.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/bimaterial_crack_test/bimaterial_crack_test.pl
+++ b/contrib/bimaterial_crack_test/bimaterial_crack_test.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/bimaterial_crack_test/crack.cc b/contrib/bimaterial_crack_test/crack.cc
index c4905e4..649171f 100644
--- a/contrib/bimaterial_crack_test/crack.cc
+++ b/contrib/bimaterial_crack_test/crack.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/bimaterial_crack_test/crack.param b/contrib/bimaterial_crack_test/crack.param
old mode 100755
new mode 100644
index 14049d4..9c97a2c
--- a/contrib/bimaterial_crack_test/crack.param
+++ b/contrib/bimaterial_crack_test/crack.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- mat-lab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program crack                                            %
diff --git a/contrib/bimaterial_crack_test/crack.pl b/contrib/bimaterial_crack_test/crack.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/bimaterial_crack_test/crack.pl
+++ b/contrib/bimaterial_crack_test/crack.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/bimaterial_crack_test/crack_exact_solution.cc b/contrib/bimaterial_crack_test/crack_exact_solution.cc
index 674a7f8..2c2f995 100644
--- a/contrib/bimaterial_crack_test/crack_exact_solution.cc
+++ b/contrib/bimaterial_crack_test/crack_exact_solution.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/bimaterial_crack_test/crack_exact_solution.h b/contrib/bimaterial_crack_test/crack_exact_solution.h
index 0aad64b..1ce5132 100644
--- a/contrib/bimaterial_crack_test/crack_exact_solution.h
+++ b/contrib/bimaterial_crack_test/crack_exact_solution.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/bimaterial_crack_test/getfem_Xfem.cc b/contrib/bimaterial_crack_test/getfem_Xfem.cc
index 4089762..639477c 100644
--- a/contrib/bimaterial_crack_test/getfem_Xfem.cc
+++ b/contrib/bimaterial_crack_test/getfem_Xfem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/contrib/bimaterial_crack_test/getfem_Xfem.h b/contrib/bimaterial_crack_test/getfem_Xfem.h
index e475039..da17ec3 100644
--- a/contrib/bimaterial_crack_test/getfem_Xfem.h
+++ b/contrib/bimaterial_crack_test/getfem_Xfem.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/contrib/bimaterial_crack_test/getfem_spider_fem.h b/contrib/bimaterial_crack_test/getfem_spider_fem.h
index 86dcb48..797c839 100644
--- a/contrib/bimaterial_crack_test/getfem_spider_fem.h
+++ b/contrib/bimaterial_crack_test/getfem_spider_fem.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/contrib/crack_plate/Makefile.am b/contrib/crack_plate/Makefile.am
index 3d82c31..bb63180 100644
--- a/contrib/crack_plate/Makefile.am
+++ b/contrib/crack_plate/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 
 if QHULL
diff --git a/contrib/crack_plate/Makefile.in b/contrib/crack_plate/Makefile.in
index f5a7afd..37d6551 100644
--- a/contrib/crack_plate/Makefile.in
+++ b/contrib/crack_plate/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -93,6 +100,9 @@ host_triplet = @host@
 @QHULL_TRUE@	crack_bilaplacian$(EXEEXT)
 @QHULL_TRUE at TESTS = crack_mindlin.pl
 subdir = contrib/crack_plate
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -108,7 +118,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -420,8 +429,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -489,7 +496,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -522,8 +528,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -604,7 +612,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -645,6 +652,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/crack_plate/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/crack_plate/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -803,7 +811,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1093,8 +1101,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/crack_plate/crack_bilaplacian.cc b/contrib/crack_plate/crack_bilaplacian.cc
index 809e86d..30e5fed 100644
--- a/contrib/crack_plate/crack_bilaplacian.cc
+++ b/contrib/crack_plate/crack_bilaplacian.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier, Jeremie Lasry.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier, Jeremie Lasry.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/crack_plate/crack_bilaplacian.h b/contrib/crack_plate/crack_bilaplacian.h
index 36ccc02..ba3ce10 100644
--- a/contrib/crack_plate/crack_bilaplacian.h
+++ b/contrib/crack_plate/crack_bilaplacian.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/crack_plate/crack_bilaplacian.param b/contrib/crack_plate/crack_bilaplacian.param
index 25c9df5..88d121a 100644
--- a/contrib/crack_plate/crack_bilaplacian.param
+++ b/contrib/crack_plate/crack_bilaplacian.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program bilaplacian                      %
diff --git a/contrib/crack_plate/crack_bilaplacian_mixed.param b/contrib/crack_plate/crack_bilaplacian_mixed.param
index 374259e..fc5d36e 100644
--- a/contrib/crack_plate/crack_bilaplacian_mixed.param
+++ b/contrib/crack_plate/crack_bilaplacian_mixed.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program bilaplacian                      %
diff --git a/contrib/crack_plate/crack_bilaplacian_moment.cc b/contrib/crack_plate/crack_bilaplacian_moment.cc
index 77a5423..769e3aa 100644
--- a/contrib/crack_plate/crack_bilaplacian_moment.cc
+++ b/contrib/crack_plate/crack_bilaplacian_moment.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier, Jeremie Lasry.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier, Jeremie Lasry.
 
  This file is a part of GetFEM++
 
@@ -140,7 +140,8 @@ bool bilaplacian_crack_problem::solve_moment(plain_vector &U) {
 	 if (gmm::sqr(mesh.points_of_convex(i)[j][0]) + 
 	     gmm::sqr(mesh.points_of_convex(i)[j][1]) > 
 	     gmm::sqr(enr_area_radius)) 
-	   pm_convexes.sup(i); break;
+	   pm_convexes.sup(i);
+	 break;
        }
      }
       
diff --git a/contrib/crack_plate/crack_bilaplacian_problem.cc b/contrib/crack_plate/crack_bilaplacian_problem.cc
index 697b3d0..e27c660 100644
--- a/contrib/crack_plate/crack_bilaplacian_problem.cc
+++ b/contrib/crack_plate/crack_bilaplacian_problem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier, Jeremie Lasry.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier, Jeremie Lasry.
 
  This file is a part of GetFEM++
 
@@ -28,6 +28,8 @@
 
 using std::endl; using std::cout; using std::cerr;
 using std::ends; using std::cin;
+template <typename T> std::ostream &operator <<
+  (std::ostream &o, const std::vector<T>& m) { gmm::write(o,m); return o; }
 
 size_type is_global_dof_type_bis(getfem::pdof_description dof){
 size_type global_dof = 0 ;
@@ -600,7 +602,8 @@ void bilaplacian_crack_problem::compute_error(plain_vector &U) {
 	  if (gmm::sqr(mesh.points_of_convex(cv)[j][0] ) + 
 	      gmm::sqr(mesh.points_of_convex(cv)[j][1] ) > 
 	      gmm::sqr(radius_split_domain)) 
-	    in_area = false; break; 
+	    in_area = false;
+	  break; 
 	}
 	  if (in_area) r_center.add(cv) ;
 	  else r_ext.add(cv) ;
@@ -740,7 +743,8 @@ bool bilaplacian_crack_problem::solve(plain_vector &U) {
 	 if (gmm::sqr(mesh.points_of_convex(i)[j][0]) + 
 	     gmm::sqr(mesh.points_of_convex(i)[j][1]) > 
 	     gmm::sqr(enr_area_radius)) 
-	   pm_convexes.sup(i); break;
+	   pm_convexes.sup(i);
+	 break;
        }
      }
       
diff --git a/contrib/crack_plate/crack_bilaplacian_sif.cc b/contrib/crack_plate/crack_bilaplacian_sif.cc
index 59bc72a..4102fe1 100644
--- a/contrib/crack_plate/crack_bilaplacian_sif.cc
+++ b/contrib/crack_plate/crack_bilaplacian_sif.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard,  Julien Pommier
+ Copyright (C) 2007-2017 Yves Renard,  Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/contrib/crack_plate/crack_bilaplacian_singularities.cc b/contrib/crack_plate/crack_bilaplacian_singularities.cc
index 972179a..5acc183 100644
--- a/contrib/crack_plate/crack_bilaplacian_singularities.cc
+++ b/contrib/crack_plate/crack_bilaplacian_singularities.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/crack_plate/crack_bilaplacian_tools.cc b/contrib/crack_plate/crack_bilaplacian_tools.cc
index 0c72ff5..1d69af4 100644
--- a/contrib/crack_plate/crack_bilaplacian_tools.cc
+++ b/contrib/crack_plate/crack_bilaplacian_tools.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier, Jeremie Lasry.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier, Jeremie Lasry.
 
  This file is a part of GetFEM++
 
@@ -79,9 +79,11 @@ void asm_normal_derivative_dirichlet_constraints_bis
     if (!R_must_be_derivated) {
       asm_normal_source_term(R, mim, mf_mult, mf_r, r_data, rg);
     } else {
-      asm_real_or_complex_1_param
-        (R, mim, mf_mult, mf_r, r_data, rg,
-         "R=data(#2); V(#1)+=comp(Grad(#1).Normal().Grad(#2).Normal())(i,j,k,k).R(j)");
+      asm_real_or_complex_1_param_vec
+	(R, mim, mf_mult, &mf_r, r_data, rg, "(Grad_A.Normal)*(Grad_Test_u.Normal)");
+      // asm_real_or_complex_1_param
+      //   (R, mim, mf_mult, mf_r, r_data, rg,
+      //    "R=data(#2); V(#1)+=comp(Grad(#1).Normal().Grad(#2).Normal())(:,i,i,j,k,k).R(j)");
     }
   }
 }
@@ -1089,14 +1091,14 @@ void bilaplacian_crack_problem::export_solution(const plain_vector &U){
       assert(pts.size() == 1);
       size_type j=pts[0].i;
       scalar_type x3 = P[2];
-      assert(finite(VTHETA[2*j]));
-      //assert(finite(VT[2*j]));
+      assert(std::isfinite(VTHETA[2*j]));
+      //assert(std::isfinite(VT[2*j]));
       V[3*i+0] = - x3 * VTHETA[2*j+0]; //V[3*i+0] = VT[2*j+0] + x3 * VTHETA.at(2*j+0);
       V[3*i+1] = - x3 * VTHETA[2*j+1]; //V[3*i+1] = VT[2*j+1] + x3 * VTHETA[2*j+1];
       V[3*i+2] = V3[j];
-      assert(finite(V[3*i]));
-      assert(finite(V[3*i+1]));
-      assert(finite(V[3*i+2]));
+      assert(std::isfinite(V[3*i]));
+      assert(std::isfinite(V[3*i+1]));
+      assert(std::isfinite(V[3*i+2]));
     }
     
     cout << "export to " << datafilename + "_3d.dx" << "..\n";
diff --git a/contrib/crack_plate/crack_mindlin.cc b/contrib/crack_plate/crack_mindlin.cc
index 246eb67..89cf7cf 100644
--- a/contrib/crack_plate/crack_mindlin.cc
+++ b/contrib/crack_plate/crack_mindlin.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -42,7 +42,8 @@
 
 using std::endl; using std::cout; using std::cerr;
 using std::ends; using std::cin;
-
+template <typename T> std::ostream &operator <<
+  (std::ostream &o, const std::vector<T>& m) { gmm::write(o,m); return o; }
 
 /* some GetFEM++ types that we will be using */
 using bgeot::base_small_vector; /* special class for small (dim<16) vectors */
@@ -1032,14 +1033,14 @@ int main(int argc, char *argv[]) {
       assert(pts.size() == 1);
       size_type j=pts[0].i;
       scalar_type x3 = P[2];
-      assert(finite(VTHETA[2*j]));
-      assert(finite(VT[2*j]));
+      assert(std::isfinite(VTHETA[2*j]));
+      assert(std::isfinite(VT[2*j]));
       V[3*i+0] = VT[2*j+0] + x3 * VTHETA.at(2*j+0);
       V[3*i+1] = VT[2*j+1] + x3 * VTHETA[2*j+1];
       V[3*i+2] = V3[j];
-      assert(finite(V[3*i]));
-      assert(finite(V[3*i+1]));
-      assert(finite(V[3*i+2]));
+      assert(std::isfinite(V[3*i]));
+      assert(std::isfinite(V[3*i+1]));
+      assert(std::isfinite(V[3*i+2]));
     }
 
     
diff --git a/contrib/crack_plate/crack_mindlin.param b/contrib/crack_plate/crack_mindlin.param
index 0515386..0831b3e 100644
--- a/contrib/crack_plate/crack_mindlin.param
+++ b/contrib/crack_plate/crack_mindlin.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program crackPlate    
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
diff --git a/contrib/crack_plate/crack_mindlin.pl b/contrib/crack_plate/crack_mindlin.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/crack_plate/crack_mindlin.pl
+++ b/contrib/crack_plate/crack_mindlin.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/delaminated_crack/Makefile.am b/contrib/delaminated_crack/Makefile.am
index b83200c..8274dc3 100644
--- a/contrib/delaminated_crack/Makefile.am
+++ b/contrib/delaminated_crack/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 
 check_PROGRAMS =                 \
diff --git a/contrib/delaminated_crack/Makefile.in b/contrib/delaminated_crack/Makefile.in
index e80a9a2..3e808a4 100644
--- a/contrib/delaminated_crack/Makefile.in
+++ b/contrib/delaminated_crack/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,9 @@ build_triplet = @build@
 host_triplet = @host@
 check_PROGRAMS = delaminated_crack$(EXEEXT)
 subdir = contrib/delaminated_crack
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +116,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -383,8 +392,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -452,7 +459,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -485,8 +491,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -567,7 +575,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -602,6 +609,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/delaminated_crack/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/delaminated_crack/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -750,7 +758,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1040,8 +1048,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/delaminated_crack/delaminated_crack.cc b/contrib/delaminated_crack/delaminated_crack.cc
index b470602..1ce172b 100644
--- a/contrib/delaminated_crack/delaminated_crack.cc
+++ b/contrib/delaminated_crack/delaminated_crack.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/delaminated_crack/delaminated_crack.param b/contrib/delaminated_crack/delaminated_crack.param
old mode 100755
new mode 100644
index 374e892..8633ca1
--- a/contrib/delaminated_crack/delaminated_crack.param
+++ b/contrib/delaminated_crack/delaminated_crack.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program crack                                            %
diff --git a/contrib/delaminated_crack/delaminated_crack.pl b/contrib/delaminated_crack/delaminated_crack.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/delaminated_crack/delaminated_crack.pl
+++ b/contrib/delaminated_crack/delaminated_crack.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/icare/Makefile.am b/contrib/icare/Makefile.am
index 2207980..2f171b8 100644
--- a/contrib/icare/Makefile.am
+++ b/contrib/icare/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 
 check_PROGRAMS =                 \
diff --git a/contrib/icare/Makefile.in b/contrib/icare/Makefile.in
index 6ff778b..6b9e1bb 100644
--- a/contrib/icare/Makefile.in
+++ b/contrib/icare/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,9 @@ build_triplet = @build@
 host_triplet = @host@
 check_PROGRAMS = icare$(EXEEXT)
 subdir = contrib/icare
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +116,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -402,8 +411,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -471,7 +478,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -504,8 +510,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -586,7 +594,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -624,6 +631,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/icare/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/icare/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -772,7 +780,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1062,8 +1070,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/icare/icare.cc b/contrib/icare/icare.cc
index 7261785..a2b5176 100644
--- a/contrib/icare/icare.cc
+++ b/contrib/icare/icare.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Michel Fourni�, Julien Pommier,
+ Copyright (C) 2002-2017 Michel Fourni�, Julien Pommier,
 
  This file is a part of GetFEM++
 
diff --git a/contrib/icare/icare.h b/contrib/icare/icare.h
index 2ec8313..f94889d 100644
--- a/contrib/icare/icare.h
+++ b/contrib/icare/icare.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Michel Fourni�, Julien Pommier,
+ Copyright (C) 2002-2017 Michel Fourni�, Julien Pommier,
 
  This file is a part of GetFEM++
 
diff --git a/contrib/icare/icare.param b/contrib/icare/icare.param
index b1a25bf..87994d2 100644
--- a/contrib/icare/icare.param
+++ b/contrib/icare/icare.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program stokes                                           %
diff --git a/contrib/icare/icare.pl b/contrib/icare/icare.pl
index 5222509..bbb943c 100755
--- a/contrib/icare/icare.pl
+++ b/contrib/icare/icare.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/icare/navier_stokes_cylinder1.mesh b/contrib/icare/navier_stokes_cylinder1.mesh
old mode 100755
new mode 100644
index 5cba6dc..7a06687
--- a/contrib/icare/navier_stokes_cylinder1.mesh
+++ b/contrib/icare/navier_stokes_cylinder1.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 2.0-20050211
 
diff --git a/contrib/icare/navier_stokes_cylinder2.mesh b/contrib/icare/navier_stokes_cylinder2.mesh
old mode 100755
new mode 100644
index 86a3d28..edbce98
--- a/contrib/icare/navier_stokes_cylinder2.mesh
+++ b/contrib/icare/navier_stokes_cylinder2.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 2.0
 
diff --git a/contrib/level_set_contact/Makefile.am b/contrib/level_set_contact/Makefile.am
index 1b6c0c2..33935eb 100755
--- a/contrib/level_set_contact/Makefile.am
+++ b/contrib/level_set_contact/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 
 check_PROGRAMS =                 \
diff --git a/contrib/level_set_contact/Makefile.in b/contrib/level_set_contact/Makefile.in
index 81dbbd2..21fb692 100644
--- a/contrib/level_set_contact/Makefile.in
+++ b/contrib/level_set_contact/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,9 @@ build_triplet = @build@
 host_triplet = @host@
 check_PROGRAMS = test_contact$(EXEEXT)
 subdir = contrib/level_set_contact
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +116,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -402,8 +411,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -471,7 +478,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -504,8 +510,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -586,7 +594,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -625,6 +632,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/level_set_contact/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/level_set_contact/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -774,7 +782,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1064,8 +1072,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/level_set_contact/contact_2D.param b/contrib/level_set_contact/contact_2D.param
index d61e75a..d15ea9d 100644
--- a/contrib/level_set_contact/contact_2D.param
+++ b/contrib/level_set_contact/contact_2D.param
@@ -1,53 +1,69 @@
-% This program (test_contact) is used for as a demo of
-% Level set contact functionality in Getfem
-% It simulates a contact betwen a maste and a slave
-% the contact itself occures between the master surface
-% and zero contour of level set function, defined on the slave
+% Copyright (C) 2017-2017 Yves Renard.
 %
-RESIDUAL = 1e-8;
-
-N = 2;
-
-NSTEP = 500;
-
-APPLIED_DISP = -1;
-LS_OFFSET = -0.12;
+% This file is a part of GetFEM++
 %
-%
-% Master contact body
-DIVxM = 4;
-DIVyM = 8;
-DIVzM = 1;
-
-xM = 0.3;
-yM = 0.92;
-zM = 0.1;
-LxM = 0.4;
-LyM = 0.5;
-LzM = 0.1;
-APPROX_ORDER_MASTER = 1;
-LM_INT_TYPE = 'IM_STRUCTURED_COMPOSITE(IM_GAUSS1D(2),4)';
-INT_ORDER_MASTER = 2;
-MESH_TYPE_MASTER = 'QK';
-LAMBDA_MASTER = 110.0;
-MU_MASTER = 70.0;
-%
-%
-% Slave contact body
-DIVxS = 20;
-DIVyS = 
-20;
-DIVzS = 4;
-
-xS = 0;
-yS = 0;
-zS = 0;
-LxS = 1;
-LyS = 1;
-LzS = 0.3;
-APPROX_ORDER_SLAVE = 1;
-INT_ORDER_SLAVE = 2;
-MESH_TYPE_SLAVE = 'QK';
-LAMBDA_SLAVE = 0;
-MU_SLAVE = 7;
-
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+% This program (test_contact) is used for as a demo of
+% Level set contact functionality in Getfem
+% It simulates a contact betwen a maste and a slave
+% the contact itself occures between the master surface
+% and zero contour of level set function, defined on the slave
+%
+RESIDUAL = 1e-8;
+
+N = 2;
+
+NSTEP = 500;
+
+APPLIED_DISP = -1;
+LS_OFFSET = -0.12;
+%
+%
+% Master contact body
+DIVxM = 4;
+DIVyM = 8;
+DIVzM = 1;
+
+xM = 0.3;
+yM = 0.92;
+zM = 0.1;
+LxM = 0.4;
+LyM = 0.5;
+LzM = 0.1;
+APPROX_ORDER_MASTER = 1;
+LM_INT_TYPE = 'IM_STRUCTURED_COMPOSITE(IM_GAUSS1D(2),4)';
+INT_ORDER_MASTER = 2;
+MESH_TYPE_MASTER = 'QK';
+LAMBDA_MASTER = 110.0;
+MU_MASTER = 70.0;
+%
+%
+% Slave contact body
+DIVxS = 20;
+DIVyS = 
+20;
+DIVzS = 4;
+
+xS = 0;
+yS = 0;
+zS = 0;
+LxS = 1;
+LyS = 1;
+LzS = 0.3;
+APPROX_ORDER_SLAVE = 1;
+INT_ORDER_SLAVE = 2;
+MESH_TYPE_SLAVE = 'QK';
+LAMBDA_SLAVE = 0;
+MU_SLAVE = 7;
+
diff --git a/contrib/level_set_contact/contact_3D.param b/contrib/level_set_contact/contact_3D.param
index 4d0bf2d..bcde3a2 100644
--- a/contrib/level_set_contact/contact_3D.param
+++ b/contrib/level_set_contact/contact_3D.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % This program (test_contact) is used for as a demo of
 % Level set contact functionality in Getfem
 % It simulates a contact betwen a maste and a slave
diff --git a/contrib/level_set_contact/contact_problem.cpp b/contrib/level_set_contact/contact_problem.cpp
index c7418b9..ba23049 100644
--- a/contrib/level_set_contact/contact_problem.cpp
+++ b/contrib/level_set_contact/contact_problem.cpp
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2011-2016 Andriy Andreykiv.
+ Copyright (C) 2011-2017 Andriy Andreykiv.
 
  This file is a part of GetFEM++
 
@@ -19,120 +19,120 @@
 
 ===========================================================================*/
 
-#include "contact_problem.h"
-#include "contact_problem.h"
-#include <getfem/getfem_regular_meshes.h>
-
-contact_problem::contact_problem(int argc, char *argv[])
-{
-	std::cout<<"-- reading parameter file"<<std::endl;
-	PARAM.read_command_line(argc,argv);
-	tol_newton = PARAM.real_value("RESIDUAL"); 
-	model_dim = PARAM.int_value("N","Dimension of the model");
-	nstep = PARAM.int_value("NSTEP","Number of steps in the analysis");
-	applied_disp = PARAM.real_value("APPLIED_DISP","Final value of the applied displacement");
-	ls_offset = PARAM.real_value("LS_OFFSET","Adding a value to all LS nodes");
-
-	//Master contact body
-	size_type div_x_M = PARAM.int_value("DIVxM","Mesh division");
-	size_type div_y_M = PARAM.int_value("DIVyM","Mesh division");
-	size_type div_z_M = PARAM.int_value("DIVzM","Mesh di vision");
-	scalar_type x_M = PARAM.real_value("xM","Origin x master");
-	scalar_type y_M = PARAM.real_value("yM","Origin y master");
-	scalar_type z_M = PARAM.real_value("zM","Origin z master");
-	scalar_type L_x_M = PARAM.real_value("LxM","size X master");
-	scalar_type L_y_M = PARAM.real_value("LyM","size Y master");
-	scalar_type L_z_M = PARAM.real_value("LzM","size Z master");
-	app_order_master = PARAM.int_value("APPROX_ORDER_MASTER","Aproximation order master");
-	int_order_master = PARAM.int_value("INT_ORDER_MASTER","Intergration order master");
-	std::string MESH_TYPE_PREFIX_MASTER = PARAM.string_value("MESH_TYPE_MASTER","mesh type");
-	LM_INT_TYPE = PARAM.string_value("LM_INT_TYPE", "integration method for the contact surface");
-	mu_master = PARAM.real_value("MU_MASTER", "First Elastic coefficient");
-	lambda_master = PARAM.real_value("LAMBDA_MASTER", "Second Elastic coefficient");
-	//
-	std::cout<<"--generating the master mesh"<<std::endl;
-	std::stringstream buf1;
-	buf1<<"GT_"<<MESH_TYPE_PREFIX_MASTER<<"("<<model_dim<<","<<app_order_master<<")";
-	std::string MESH_TYPE_MASTER=buf1.str();
-	std::vector<size_type> nsubdiv_master(model_dim);
-	nsubdiv_master[0] = div_x_M; if(model_dim>1) nsubdiv_master[1] = div_y_M; if(model_dim==3) nsubdiv_master[2] = div_z_M; 
-	getfem::regular_unit_mesh(mesh_master, nsubdiv_master, bgeot::geometric_trans_descriptor(MESH_TYPE_MASTER));
-	base_matrix M_m(model_dim,model_dim);
-	bgeot::base_small_vector Origin_master(model_dim);
-	Origin_master[0] = x_M;if(model_dim>1) Origin_master[1] = y_M; if(model_dim>2) Origin_master[2] = z_M;
-	M_m(0,0) = L_x_M; if(model_dim>1) M_m(1,1) = L_y_M; if(model_dim==3) M_m(2,2) = L_z_M;
-	mesh_master.transformation(M_m);
-	mesh_master.translation(Origin_master);
-
-
-	//Slave mesh
-	size_type div_x_S = PARAM.int_value("DIVxS","Mesh division");
-	size_type div_y_S = PARAM.int_value("DIVyS","Mesh division");
-	size_type div_z_S = PARAM.int_value("DIVzS","Mesh di vision");
-	scalar_type x_S = PARAM.real_value("xS","Origin x slave");
-	scalar_type y_S = PARAM.real_value("yS","Origin y slave");
-	scalar_type z_S = PARAM.real_value("zS","Origin z slave");
-	scalar_type L_x_S = PARAM.real_value("LxS","size X slave");
-	scalar_type L_y_S = PARAM.real_value("LyS","size Y slave");
-	scalar_type L_z_S = PARAM.real_value("LzS","size Z slave");
-	app_order_slave = PARAM.int_value("APPROX_ORDER_SLAVE","Aproximation order slave");
-	int_order_slave = PARAM.int_value("INT_ORDER_SLAVE","Intergration order slave");
-	std::string MESH_TYPE_PREFIX_SLAVE = PARAM.string_value("MESH_TYPE_SLAVE","mesh type");
-	mu_slave = PARAM.real_value("MU_SLAVE", "First Elastic coefficient");
-	lambda_slave = PARAM.real_value("LAMBDA_SLAVE", "Second Elastic coefficient");
-	//
-	std::cout<<"--generating the slave mesh"<<std::endl;
-	std::stringstream buf2;
-	buf2<<"GT_"<<MESH_TYPE_PREFIX_SLAVE<<"("<<model_dim<<","<<app_order_slave<<")";
-	std::string MESH_TYPE_SLAVE=buf2.str();
-	std::vector<size_type> nsubdiv_slave(model_dim);
-	nsubdiv_slave[0] = div_x_S; if(model_dim>1) nsubdiv_slave[1] = div_y_S; if(model_dim==3) nsubdiv_slave[2] = div_z_S; 
-	getfem::regular_unit_mesh(mesh_slave, nsubdiv_slave, bgeot::geometric_trans_descriptor(MESH_TYPE_SLAVE));
-	base_matrix M_s(model_dim,model_dim);
-	bgeot::base_small_vector Origin_slave(model_dim);
-	Origin_slave[0] = x_S;if(model_dim>1) Origin_slave[1] = y_S; if(model_dim>2) Origin_slave[2] = z_S;
-	M_s(0,0) = L_x_S; if(model_dim>1) M_s(1,1) = L_y_S; if(model_dim==3) M_s(2,2) = L_z_S;
-	mesh_slave.transformation(M_s);
-	mesh_slave.translation(Origin_slave);
-
-	// define boundary regions
-	std::cout<<"Building boundary regions for the master"<<std::endl;
-	mark_boundary(mesh_master);
-	std::cout<<"Building boundary regions for the slave"<<std::endl;
-	mark_boundary(mesh_slave);
-}
-
-void mark_boundary(getfem::mesh& mesh)
-{
-	//	Create mesh regions for boundary 
-	getfem::mesh_region border_faces;
-	getfem::outer_faces_of_mesh(mesh, border_faces); 
-	for (getfem::mr_visitor i(border_faces); !i.finished(); ++i) {
-		bgeot::base_node un = mesh.normal_of_face_of_convex(i.cv(), i.f());
-		un/= gmm::vect_norm2(un);
-		if (gmm::abs(un[1] - 1.0) < 1.0E-7) { // Top face
-			mesh.region(NORTH).add(i.cv(), i.f());
-		} 
-		if (gmm::abs(un[1] + 1.0) < 1.0E-7) {  // Bottom face
-			mesh.region(SOUTH).add(i.cv(), i.f());}
-		if (gmm::abs(un[0] - 1.0) < 1.0E-7) { // Right face
-			mesh.region(EAST).add(i.cv(), i.f());} 
-		if (gmm::abs(un[0] + 1.0) < 1.0E-7) { // Left face
-			mesh.region(WEST).add(i.cv(), i.f());}
-		if (mesh.dim()==3) 
-		{
-			if (gmm::abs(un[2] + 1.0) < 1.0E-7) { // front face
-				mesh.region(FRONT).add(i.cv(), i.f());}
-			if (gmm::abs(un[2] - 1.0) < 1.0E-7) { // back face
-				mesh.region(BACK).add(i.cv(), i.f());}
-		}
-	}
-	GMM_ASSERT1(mesh.region(NORTH).index().card()>0,"Region North is empty");
-	GMM_ASSERT1(mesh.region(SOUTH).index().card()>0,"Region South is empty");
-	GMM_ASSERT1(mesh.region(EAST).index().card()>0, "Region East is empty");
-	GMM_ASSERT1(mesh.region(WEST).index().card()>0, "Region West is empty");
-	if (mesh.dim()==3) {
-          GMM_ASSERT1(mesh.region(FRONT).index().card()>0,"Region Front is empty");
-          GMM_ASSERT1(mesh.region(BACK).index().card()>0, "Region Back is empty");
-	}
-}
+#include "contact_problem.h"
+#include "contact_problem.h"
+#include <getfem/getfem_regular_meshes.h>
+
+contact_problem::contact_problem(int argc, char *argv[])
+{
+	std::cout<<"-- reading parameter file"<<std::endl;
+	PARAM.read_command_line(argc,argv);
+	tol_newton = PARAM.real_value("RESIDUAL"); 
+	model_dim = PARAM.int_value("N","Dimension of the model");
+	nstep = PARAM.int_value("NSTEP","Number of steps in the analysis");
+	applied_disp = PARAM.real_value("APPLIED_DISP","Final value of the applied displacement");
+	ls_offset = PARAM.real_value("LS_OFFSET","Adding a value to all LS nodes");
+
+	//Master contact body
+	size_type div_x_M = PARAM.int_value("DIVxM","Mesh division");
+	size_type div_y_M = PARAM.int_value("DIVyM","Mesh division");
+	size_type div_z_M = PARAM.int_value("DIVzM","Mesh di vision");
+	scalar_type x_M = PARAM.real_value("xM","Origin x master");
+	scalar_type y_M = PARAM.real_value("yM","Origin y master");
+	scalar_type z_M = PARAM.real_value("zM","Origin z master");
+	scalar_type L_x_M = PARAM.real_value("LxM","size X master");
+	scalar_type L_y_M = PARAM.real_value("LyM","size Y master");
+	scalar_type L_z_M = PARAM.real_value("LzM","size Z master");
+	app_order_master = PARAM.int_value("APPROX_ORDER_MASTER","Aproximation order master");
+	int_order_master = PARAM.int_value("INT_ORDER_MASTER","Intergration order master");
+	std::string MESH_TYPE_PREFIX_MASTER = PARAM.string_value("MESH_TYPE_MASTER","mesh type");
+	LM_INT_TYPE = PARAM.string_value("LM_INT_TYPE", "integration method for the contact surface");
+	mu_master = PARAM.real_value("MU_MASTER", "First Elastic coefficient");
+	lambda_master = PARAM.real_value("LAMBDA_MASTER", "Second Elastic coefficient");
+	//
+	std::cout<<"--generating the master mesh"<<std::endl;
+	std::stringstream buf1;
+	buf1<<"GT_"<<MESH_TYPE_PREFIX_MASTER<<"("<<model_dim<<","<<app_order_master<<")";
+	std::string MESH_TYPE_MASTER=buf1.str();
+	std::vector<size_type> nsubdiv_master(model_dim);
+	nsubdiv_master[0] = div_x_M; if(model_dim>1) nsubdiv_master[1] = div_y_M; if(model_dim==3) nsubdiv_master[2] = div_z_M; 
+	getfem::regular_unit_mesh(mesh_master, nsubdiv_master, bgeot::geometric_trans_descriptor(MESH_TYPE_MASTER));
+	base_matrix M_m(model_dim,model_dim);
+	bgeot::base_small_vector Origin_master(model_dim);
+	Origin_master[0] = x_M;if(model_dim>1) Origin_master[1] = y_M; if(model_dim>2) Origin_master[2] = z_M;
+	M_m(0,0) = L_x_M; if(model_dim>1) M_m(1,1) = L_y_M; if(model_dim==3) M_m(2,2) = L_z_M;
+	mesh_master.transformation(M_m);
+	mesh_master.translation(Origin_master);
+
+
+	//Slave mesh
+	size_type div_x_S = PARAM.int_value("DIVxS","Mesh division");
+	size_type div_y_S = PARAM.int_value("DIVyS","Mesh division");
+	size_type div_z_S = PARAM.int_value("DIVzS","Mesh di vision");
+	scalar_type x_S = PARAM.real_value("xS","Origin x slave");
+	scalar_type y_S = PARAM.real_value("yS","Origin y slave");
+	scalar_type z_S = PARAM.real_value("zS","Origin z slave");
+	scalar_type L_x_S = PARAM.real_value("LxS","size X slave");
+	scalar_type L_y_S = PARAM.real_value("LyS","size Y slave");
+	scalar_type L_z_S = PARAM.real_value("LzS","size Z slave");
+	app_order_slave = PARAM.int_value("APPROX_ORDER_SLAVE","Aproximation order slave");
+	int_order_slave = PARAM.int_value("INT_ORDER_SLAVE","Intergration order slave");
+	std::string MESH_TYPE_PREFIX_SLAVE = PARAM.string_value("MESH_TYPE_SLAVE","mesh type");
+	mu_slave = PARAM.real_value("MU_SLAVE", "First Elastic coefficient");
+	lambda_slave = PARAM.real_value("LAMBDA_SLAVE", "Second Elastic coefficient");
+	//
+	std::cout<<"--generating the slave mesh"<<std::endl;
+	std::stringstream buf2;
+	buf2<<"GT_"<<MESH_TYPE_PREFIX_SLAVE<<"("<<model_dim<<","<<app_order_slave<<")";
+	std::string MESH_TYPE_SLAVE=buf2.str();
+	std::vector<size_type> nsubdiv_slave(model_dim);
+	nsubdiv_slave[0] = div_x_S; if(model_dim>1) nsubdiv_slave[1] = div_y_S; if(model_dim==3) nsubdiv_slave[2] = div_z_S; 
+	getfem::regular_unit_mesh(mesh_slave, nsubdiv_slave, bgeot::geometric_trans_descriptor(MESH_TYPE_SLAVE));
+	base_matrix M_s(model_dim,model_dim);
+	bgeot::base_small_vector Origin_slave(model_dim);
+	Origin_slave[0] = x_S;if(model_dim>1) Origin_slave[1] = y_S; if(model_dim>2) Origin_slave[2] = z_S;
+	M_s(0,0) = L_x_S; if(model_dim>1) M_s(1,1) = L_y_S; if(model_dim==3) M_s(2,2) = L_z_S;
+	mesh_slave.transformation(M_s);
+	mesh_slave.translation(Origin_slave);
+
+	// define boundary regions
+	std::cout<<"Building boundary regions for the master"<<std::endl;
+	mark_boundary(mesh_master);
+	std::cout<<"Building boundary regions for the slave"<<std::endl;
+	mark_boundary(mesh_slave);
+}
+
+void mark_boundary(getfem::mesh& mesh)
+{
+	//	Create mesh regions for boundary 
+	getfem::mesh_region border_faces;
+	getfem::outer_faces_of_mesh(mesh, border_faces); 
+	for (getfem::mr_visitor i(border_faces); !i.finished(); ++i) {
+		bgeot::base_node un = mesh.normal_of_face_of_convex(i.cv(), i.f());
+		un/= gmm::vect_norm2(un);
+		if (gmm::abs(un[1] - 1.0) < 1.0E-7) { // Top face
+			mesh.region(NORTH).add(i.cv(), i.f());
+		} 
+		if (gmm::abs(un[1] + 1.0) < 1.0E-7) {  // Bottom face
+			mesh.region(SOUTH).add(i.cv(), i.f());}
+		if (gmm::abs(un[0] - 1.0) < 1.0E-7) { // Right face
+			mesh.region(EAST).add(i.cv(), i.f());} 
+		if (gmm::abs(un[0] + 1.0) < 1.0E-7) { // Left face
+			mesh.region(WEST).add(i.cv(), i.f());}
+		if (mesh.dim()==3) 
+		{
+			if (gmm::abs(un[2] + 1.0) < 1.0E-7) { // front face
+				mesh.region(FRONT).add(i.cv(), i.f());}
+			if (gmm::abs(un[2] - 1.0) < 1.0E-7) { // back face
+				mesh.region(BACK).add(i.cv(), i.f());}
+		}
+	}
+	GMM_ASSERT1(mesh.region(NORTH).index().card()>0,"Region North is empty");
+	GMM_ASSERT1(mesh.region(SOUTH).index().card()>0,"Region South is empty");
+	GMM_ASSERT1(mesh.region(EAST).index().card()>0, "Region East is empty");
+	GMM_ASSERT1(mesh.region(WEST).index().card()>0, "Region West is empty");
+	if (mesh.dim()==3) {
+          GMM_ASSERT1(mesh.region(FRONT).index().card()>0,"Region Front is empty");
+          GMM_ASSERT1(mesh.region(BACK).index().card()>0, "Region Back is empty");
+	}
+}
diff --git a/contrib/level_set_contact/contact_problem.h b/contrib/level_set_contact/contact_problem.h
index f0790d8..4323c76 100644
--- a/contrib/level_set_contact/contact_problem.h
+++ b/contrib/level_set_contact/contact_problem.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2011-2016 Andriy Andreykiv.
+ Copyright (C) 2011-2017 Andriy Andreykiv.
 
  This file is a part of GetFEM++
 
@@ -29,29 +29,29 @@
 
 ===========================================================================*/
 
-#pragma once
-#pragma once
-#include <getfem/getfem_deformable_mesh.h>
-#include <getfem/getfem_models.h>
-
-using getfem::size_type;
-using getfem::scalar_type;
-using bgeot::base_matrix;
-typedef getfem::model_real_plain_vector  plain_vector;
-
-enum  { NORTH = 1, EAST = 2, WEST = 3, SOUTH = 4, FRONT = 5, BACK = 6};
-
-struct contact_problem{
-	getfem::mesh mesh_master, mesh_slave;
-	bgeot::md_param PARAM;
-	scalar_type tol_newton,applied_disp;
-	size_type model_dim, nstep;
-	size_type app_order_master, app_order_slave;
-	size_type int_order_master, int_order_slave;
-	scalar_type ls_offset;
-	scalar_type mu_master, lambda_master, mu_slave, lambda_slave;
-	std::string LM_INT_TYPE; 
-	contact_problem(int argc, char *argv[]);
-};
-
-void mark_boundary(getfem::mesh& m);
+#pragma once
+#pragma once
+#include <getfem/getfem_deformable_mesh.h>
+#include <getfem/getfem_models.h>
+
+using getfem::size_type;
+using getfem::scalar_type;
+using bgeot::base_matrix;
+typedef getfem::model_real_plain_vector  plain_vector;
+
+enum  { NORTH = 1, EAST = 2, WEST = 3, SOUTH = 4, FRONT = 5, BACK = 6};
+
+struct contact_problem{
+	getfem::mesh mesh_master, mesh_slave;
+	bgeot::md_param PARAM;
+	scalar_type tol_newton,applied_disp;
+	size_type model_dim, nstep;
+	size_type app_order_master, app_order_slave;
+	size_type int_order_master, int_order_slave;
+	scalar_type ls_offset;
+	scalar_type mu_master, lambda_master, mu_slave, lambda_slave;
+	std::string LM_INT_TYPE; 
+	contact_problem(int argc, char *argv[]);
+};
+
+void mark_boundary(getfem::mesh& m);
diff --git a/contrib/level_set_contact/contact_problem.pl b/contrib/level_set_contact/contact_problem.pl
index 3cdf991..05f3f89 100755
--- a/contrib/level_set_contact/contact_problem.pl
+++ b/contrib/level_set_contact/contact_problem.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2016 Yves Renard
+# Copyright (C) 2012-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/level_set_contact/test_contact.cpp b/contrib/level_set_contact/test_contact.cpp
index 360586d..e9ef9db 100644
--- a/contrib/level_set_contact/test_contact.cpp
+++ b/contrib/level_set_contact/test_contact.cpp
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2011-2016 Andriy Andreykiv.
+ Copyright (C) 2011-2017 Andriy Andreykiv.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/mixed_elastostatic/Makefile.am b/contrib/mixed_elastostatic/Makefile.am
index c2185ca..681c40a 100644
--- a/contrib/mixed_elastostatic/Makefile.am
+++ b/contrib/mixed_elastostatic/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 
 check_PROGRAMS =                 \
diff --git a/contrib/mixed_elastostatic/Makefile.in b/contrib/mixed_elastostatic/Makefile.in
index 9b47b55..eb69d22 100644
--- a/contrib/mixed_elastostatic/Makefile.in
+++ b/contrib/mixed_elastostatic/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,9 @@ build_triplet = @build@
 host_triplet = @host@
 check_PROGRAMS = mixed_elastostatic$(EXEEXT)
 subdir = contrib/mixed_elastostatic
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +116,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -383,8 +392,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -452,7 +459,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -485,8 +491,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -567,7 +575,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -602,6 +609,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mixed_elastostatic/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/mixed_elastostatic/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -750,7 +758,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1040,8 +1048,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/mixed_elastostatic/mixed_elastostatic.cc b/contrib/mixed_elastostatic/mixed_elastostatic.cc
index 6531dc8..7702772 100644
--- a/contrib/mixed_elastostatic/mixed_elastostatic.cc
+++ b/contrib/mixed_elastostatic/mixed_elastostatic.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -277,15 +277,22 @@ namespace getfem {
 			       const mesh_region &rg) {
      GMM_ASSERT1(mf_data.get_qdim() == 1, "invalid data mesh_fem");
 
-    const char *st;
+    // const char *st;
+    // if (mf.get_qdim_n() == 1)
+    //   st = "F=data(#2);"
+    // 	"V(#1)+=comp(vBase(#1).Base(#2).Normal())(:,j,k,j).F(k);";
+    // else
+    //   st = "F=data(mdim(#1),#2);" // a corriger pour les tenseurs non carres
+    // 	"V(#1)+=comp(mBase(#1).Base(#2).Normal())(:,i,j,k,j).F(i,k);";
+
+    // asm_real_or_complex_1_param(B, mim, mf, mf_data, F, rg, st);
+
     if (mf.get_qdim_n() == 1)
-      st = "F=data(#2);"
-	"V(#1)+=comp(vBase(#1).Base(#2).Normal())(:,j,k,j).F(k);";
+      asm_real_or_complex_1_param_vec(B, mim, mf, &mf_data, F, rg, 
+				      "(A*Test_u).Normal");
     else
-      st = "F=data(mdim(#1),#2);" // a corriger pour les tenseurs non carres
-	"V(#1)+=comp(mBase(#1).Base(#2).Normal())(:,i,j,k,j).F(i,k);";
-
-    asm_real_or_complex_1_param(B, mim, mf, mf_data, F, rg, st);
+      asm_real_or_complex_1_param_vec(B, mim, mf, &mf_data, F, rg, 
+				      "((Test_u')*A).Normal");
   }
 
   
diff --git a/contrib/mixed_elastostatic/mixed_elastostatic.param b/contrib/mixed_elastostatic/mixed_elastostatic.param
old mode 100755
new mode 100644
index f066e5d..4fe5f96
--- a/contrib/mixed_elastostatic/mixed_elastostatic.param
+++ b/contrib/mixed_elastostatic/mixed_elastostatic.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program mixed_elastostatic                               %
diff --git a/contrib/mixed_elastostatic/mixed_elastostatic.pl b/contrib/mixed_elastostatic/mixed_elastostatic.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/mixed_elastostatic/mixed_elastostatic.pl
+++ b/contrib/mixed_elastostatic/mixed_elastostatic.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/opt_assembly/Makefile.am b/contrib/opt_assembly/Makefile.am
new file mode 100644
index 0000000..73dfc49
--- /dev/null
+++ b/contrib/opt_assembly/Makefile.am
@@ -0,0 +1,32 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+check_PROGRAMS =  opt_assembly
+
+CLEANFILES =
+
+opt_assembly_SOURCES = opt_assembly.cc
+
+AM_CPPFLAGS = -I$(top_srcdir)/src -I../../src
+LDADD    = ../../src/libgetfem.la -lm @SUPLDFLAGS@ @BOOST_LIBS@
+
+TESTS =  opt_assembly.pl
+
+EXTRA_DIST = \
+	opt_assembly.pl
+
+LOG_COMPILER = perl
diff --git a/contrib/mixed_elastostatic/Makefile.in b/contrib/opt_assembly/Makefile.in
similarity index 93%
copy from contrib/mixed_elastostatic/Makefile.in
copy to contrib/opt_assembly/Makefile.in
index 9b47b55..39ff45b 100644
--- a/contrib/mixed_elastostatic/Makefile.in
+++ b/contrib/opt_assembly/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,24 @@
 
 @SET_MAKE@
 
-# SUBDIRS = 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,8 +94,11 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-check_PROGRAMS = mixed_elastostatic$(EXEEXT)
-subdir = contrib/mixed_elastostatic
+check_PROGRAMS = opt_assembly$(EXEEXT)
+subdir = contrib/opt_assembly
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,15 +114,14 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
-am_mixed_elastostatic_OBJECTS = mixed_elastostatic.$(OBJEXT)
-mixed_elastostatic_OBJECTS = $(am_mixed_elastostatic_OBJECTS)
-mixed_elastostatic_LDADD = $(LDADD)
-mixed_elastostatic_DEPENDENCIES = ../../src/libgetfem.la
+am_opt_assembly_OBJECTS = opt_assembly.$(OBJEXT)
+opt_assembly_OBJECTS = $(am_opt_assembly_OBJECTS)
+opt_assembly_LDADD = $(LDADD)
+opt_assembly_DEPENDENCIES = ../../src/libgetfem.la
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
@@ -153,8 +160,8 @@ AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
 am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
 am__v_CXXLD_0 = @echo "  CXXLD   " $@;
 am__v_CXXLD_1 = 
-SOURCES = $(mixed_elastostatic_SOURCES)
-DIST_SOURCES = $(mixed_elastostatic_SOURCES)
+SOURCES = $(opt_assembly_SOURCES)
+DIST_SOURCES = $(opt_assembly_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -383,8 +390,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -452,7 +457,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -485,8 +489,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -567,7 +573,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -577,13 +582,12 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 CLEANFILES = 
-mixed_elastostatic_SOURCES = mixed_elastostatic.cc
+opt_assembly_SOURCES = opt_assembly.cc
 AM_CPPFLAGS = -I$(top_srcdir)/src -I../../src
 LDADD = ../../src/libgetfem.la -lm @SUPLDFLAGS@ @BOOST_LIBS@
-TESTS = mixed_elastostatic.pl
+TESTS = opt_assembly.pl
 EXTRA_DIST = \
-	mixed_elastostatic.pl                  \
-	mixed_elastostatic.param
+	opt_assembly.pl
 
 LOG_COMPILER = perl
 all: all-am
@@ -599,9 +603,10 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mixed_elastostatic/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/opt_assembly/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu contrib/mixed_elastostatic/Makefile
+	  $(AUTOMAKE) --gnu contrib/opt_assembly/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -629,9 +634,9 @@ clean-checkPROGRAMS:
 	echo " rm -f" $$list; \
 	rm -f $$list
 
-mixed_elastostatic$(EXEEXT): $(mixed_elastostatic_OBJECTS) $(mixed_elastostatic_DEPENDENCIES) $(EXTRA_mixed_elastostatic_DEPENDENCIES) 
-	@rm -f mixed_elastostatic$(EXEEXT)
-	$(AM_V_CXXLD)$(CXXLINK) $(mixed_elastostatic_OBJECTS) $(mixed_elastostatic_LDADD) $(LIBS)
+opt_assembly$(EXEEXT): $(opt_assembly_OBJECTS) $(opt_assembly_DEPENDENCIES) $(EXTRA_opt_assembly_DEPENDENCIES) 
+	@rm -f opt_assembly$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(opt_assembly_OBJECTS) $(opt_assembly_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -639,7 +644,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mixed_elastostatic.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/opt_assembly.Po at am__quote@
 
 .cc.o:
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -750,7 +755,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -861,9 +866,9 @@ recheck: all $(check_PROGRAMS)
 	        am__force_recheck=am--force-recheck \
 	        TEST_LOGS="$$log_list"; \
 	exit $$?
-mixed_elastostatic.pl.log: mixed_elastostatic.pl
-	@p='mixed_elastostatic.pl'; \
-	b='mixed_elastostatic.pl'; \
+opt_assembly.pl.log: opt_assembly.pl
+	@p='opt_assembly.pl'; \
+	b='opt_assembly.pl'; \
 	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
@@ -1040,8 +1045,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/opt_assembly/opt_assembly.cc b/contrib/opt_assembly/opt_assembly.cc
new file mode 100644
index 0000000..58cb9f4
--- /dev/null
+++ b/contrib/opt_assembly/opt_assembly.cc
@@ -0,0 +1,782 @@
+/*===========================================================================
+
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
+
+ This file is a part of GetFEM++
+
+ GetFEM++  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 along with the GCC Runtime Library
+ Exception either version 3.1 or (at your option) any later version.
+ This program  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 and GCC Runtime Library Exception for more details.
+ You  should  have received a copy of the GNU Lesser General Public License
+ along  with  this program;  if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+===========================================================================*/
+#include "getfem/getfem_assembling.h"
+#include "getfem/getfem_generic_assembly.h"
+#include "getfem/getfem_export.h"
+#include "getfem/getfem_regular_meshes.h"
+#include "getfem/getfem_partial_mesh_fem.h"
+#include "getfem/getfem_mat_elem.h"
+#include "gmm/gmm.h"
+#ifdef GETFEM_HAVE_SYS_TIMES
+# include <sys/times.h>
+#endif
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+using std::endl; using std::cout; using std::cerr;
+using std::ends; using std::cin;
+using std::flush;
+
+using bgeot::base_vector;
+using bgeot::base_matrix;
+using bgeot::base_small_vector;
+using bgeot::base_node;
+using bgeot::scalar_type;
+using bgeot::size_type;
+using bgeot::short_type;
+using bgeot::dim_type;
+
+typedef gmm::wsvector<scalar_type> sparse_vector_type;
+typedef gmm::row_matrix<sparse_vector_type> sparse_matrix_type;
+typedef std::vector<scalar_type> linalg_vector;
+
+
+
+#ifdef HAVE_SYS_TIMES
+struct chrono {
+  struct ::tms t;
+  ::clock_t t_elapsed;
+  float cpu_, elapsed_, system_;
+  float nbclocktk;
+public:
+  chrono() { nbclocktk = ::sysconf(_SC_CLK_TCK); }
+  void init() { elapsed_=0; cpu_=0; system_ =0; }
+  void tic() { t_elapsed = ::times(&t); }
+  void toc() { 
+    struct tms t2; ::clock_t t2_elapsed = ::times(&t2); 
+    elapsed_ += (t2_elapsed - t_elapsed) / nbclocktk;
+    cpu_     += (t2.tms_utime - t.tms_utime) / nbclocktk;
+    system_  += (t2.tms_stime - t.tms_stime) / nbclocktk;
+    memcpy(&t, &t2, sizeof(struct tms));
+  }
+  float cpu() const { return cpu_; }
+  float elapsed() const { return elapsed_; }
+  float system() const { return system_; }
+};
+#else
+struct chrono {
+  float t,cpu_;
+public:
+  chrono() { }
+  void init() { cpu_=0; }
+  void tic() { t = float(::clock())/float(CLOCKS_PER_SEC); }
+  void toc() {
+    float t2 = float(::clock())/float(CLOCKS_PER_SEC);
+    cpu_ += t2 - t; t = t2;
+  }
+  float cpu() const { return cpu_; }
+  float elapsed() const { return cpu_; }
+  float system() const { return 0.; }
+};
+#endif
+
+std::ostream& operator<<(std::ostream& o, const chrono& c) {
+  o << "[elapsed=" << int(c.elapsed()*1000) << "ms, cpu="
+    << int(c.cpu()*1000) << "ms, system=" << int(c.system()*1000) << "ms]";
+  return o;
+}
+
+namespace getfem { // old assembly procedures with low level generic assembly
+
+  /*
+    assembly of a matrix with 1 parameter (real or complex)
+    (the most common here for the assembly routines below)
+  */
+  template <typename MAT, typename VECT>
+  void old_asm_real_or_complex_1_param
+  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_data,
+   const VECT &A, const mesh_region &rg, const char *assembly_description,
+   const mesh_fem *mf_mult = 0) {
+    old_asm_real_or_complex_1_param_
+      (M, mim, mf_u, mf_data, A, rg, assembly_description, mf_mult,
+       typename gmm::linalg_traits<VECT>::value_type());
+  }
+
+  /* real version */
+  template<typename MAT, typename VECT, typename T>
+  void old_asm_real_or_complex_1_param_
+  (const MAT &M, const mesh_im &mim,  const mesh_fem &mf_u,
+   const mesh_fem &mf_data, const VECT &A,  const mesh_region &rg,
+   const char *assembly_description, const mesh_fem *mf_mult, T) {
+    generic_assembly assem(assembly_description);
+    assem.push_mi(mim);
+    assem.push_mf(mf_u);
+    assem.push_mf(mf_data);
+    if (mf_mult) assem.push_mf(*mf_mult);
+    assem.push_data(A);
+    assem.push_mat_or_vec(const_cast<MAT&>(M));
+    assem.assembly(rg);
+  }
+
+  /* complex version */
+  template<typename MAT, typename VECT, typename T>
+  void old_asm_real_or_complex_1_param_
+  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_data,
+   const VECT &A, const mesh_region &rg,const char *assembly_description,
+   const mesh_fem *mf_mult, std::complex<T>) {
+    old_asm_real_or_complex_1_param_(gmm::real_part(M),mim,mf_u,mf_data,
+				 gmm::real_part(A),rg,
+				 assembly_description, mf_mult, T());
+    old_asm_real_or_complex_1_param_(gmm::imag_part(M),mim,mf_u,mf_data,
+				 gmm::imag_part(A),rg,
+				 assembly_description, mf_mult, T());
+  }
+
+  
+  template<typename VECT1, typename VECT2>
+  void old_asm_source_term
+  (const VECT1 &B, const mesh_im &mim, const mesh_fem &mf,
+   const mesh_fem &mf_data, const VECT2 &F,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    GMM_ASSERT1(mf_data.get_qdim() == 1 ||
+		mf_data.get_qdim() == mf.get_qdim(),
+		"invalid data mesh fem (same Qdim or Qdim=1 required)");
+
+    const char *st;
+    if (mf.get_qdim() == 1)
+      st = "F=data(#2); V(#1)+=comp(Base(#1).Base(#2))(:,j).F(j);";
+    else if (mf_data.get_qdim() == 1)
+      st = "F=data(qdim(#1),#2);"
+	"V(#1)+=comp(vBase(#1).Base(#2))(:,i,j).F(i,j);";
+    else
+      st = "F=data(#2);"
+	"V(#1)+=comp(vBase(#1).vBase(#2))(:,i,j,i).F(j);";
+    
+    old_asm_real_or_complex_1_param(const_cast<VECT1 &>(B),mim,mf,
+				    mf_data,F,rg,st);
+  }
+
+  template<typename VECT1, typename VECT2>
+  void old_asm_normal_source_term(VECT1 &B, const mesh_im &mim,
+				  const mesh_fem &mf,
+				  const mesh_fem &mf_data, const VECT2 &F,
+				  const mesh_region &rg) {
+    GMM_ASSERT1(mf_data.get_qdim() == 1 ||
+		mf_data.get_qdim() == mf.get_qdim(),
+		"invalid data mesh_fem (same Qdim or Qdim=1 required)");
+
+    const char *st;
+    if (mf.get_qdim() == 1)
+      st = "F=data(mdim(#1),#2);"
+	"V(#1)+=comp(Base(#1).Base(#2).Normal())(:,j,k).F(k,j);";
+    else if (mf_data.get_qdim() == 1)
+      st = "F=data(qdim(#1),mdim(#1),#2);"
+	"V(#1)+=comp(vBase(#1).Base(#2).Normal())(:,i,j,k).F(i,k,j);";
+    else
+      st = "F=data(mdim(#1),#2);"
+	"V(#1)+=comp(vBase(#1).vBase(#2).Normal())(:,i,j,i,k).F(k,j);";
+
+    old_asm_real_or_complex_1_param(B, mim, mf, mf_data, F, rg, st);
+  }
+
+  template<typename MAT>
+  void old_asm_mass_matrix(const MAT &M, const mesh_im &mim,
+		       const mesh_fem &mf_u1,
+		       const mesh_region &rg = mesh_region::all_convexes()) {
+    generic_assembly assem;
+    if (mf_u1.get_qdim() == 1)
+      assem.set("M(#1,#1)+=sym(comp(Base(#1).Base(#1)))");
+    else
+      assem.set("M(#1,#1)+=sym(comp(vBase(#1).vBase(#1))(:,i,:,i));");
+    assem.push_mi(mim);
+    assem.push_mf(mf_u1);
+    assem.push_mat(const_cast<MAT &>(M));
+    assem.assembly(rg);
+  }
+
+  template<typename MAT>
+  void old_asm_mass_matrix(const MAT &M, const mesh_im &mim, const mesh_fem &mf_u1,
+		       const mesh_fem &mf_u2,
+		       const mesh_region &rg = mesh_region::all_convexes()) {
+    generic_assembly assem;
+    if (mf_u1.get_qdim() == 1 && mf_u2.get_qdim() == 1)
+      assem.set("M(#1,#2)+=comp(Base(#1).Base(#2))");
+    else if (mf_u1.get_qdim() == 1)
+      assem.set("M(#1,#2)+=comp(Base(#1).vBase(#2))(:,:,1);"); // could be i in place of 1
+    else if (mf_u2.get_qdim() == 1)
+      assem.set("M(#1,#2)+=comp(vBase(#1).Base(#2))(:,1,:);");
+    else
+      assem.set("M(#1,#2)+=comp(vBase(#1).vBase(#2))(:,i,:,i);");
+    assem.push_mi(mim);
+    assem.push_mf(mf_u1);
+    assem.push_mf(mf_u2);
+    assem.push_mat(const_cast<MAT &>(M));
+    assem.assembly(rg);
+  }
+
+  /** 
+      Stiffness matrix for linear elasticity, with Lam� coefficients
+      @ingroup asm
+  */
+  template<class MAT, class VECT>
+  void old_asm_stiffness_matrix_for_linear_elasticity
+  (const MAT &RM_, const mesh_im &mim, const mesh_fem &mf,
+   const mesh_fem &mf_data, const VECT &LAMBDA, const VECT &MU,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    MAT &RM = const_cast<MAT &>(RM_);
+    GMM_ASSERT1(mf_data.get_qdim() == 1,
+		"invalid data mesh fem (Qdim=1 required)");
+    
+    GMM_ASSERT1(mf.get_qdim() == mf.linked_mesh().dim(),
+		"wrong qdim for the mesh_fem");
+    /* e = strain tensor,
+       M = 2*mu*e(u):e(v) + lambda*tr(e(u))*tr(e(v))
+    */
+    generic_assembly assem("lambda=data$1(#2); mu=data$2(#2);"
+			   "t=comp(vGrad(#1).vGrad(#1).Base(#2));"
+			   //"e=(t{:,2,3,:,5,6,:}+t{:,3,2,:,5,6,:}"
+			   //"+t{:,2,3,:,6,5,:}+t{:,3,2,:,6,5,:})/4;"
+			   //"e=(t{:,2,3,:,5,6,:}+t{:,3,2,:,5,6,:})*0.5;"
+			   /*"M(#1,#1)+= sym(2*e(:,i,j,:,i,j,k).mu(k)"
+                             " + e(:,i,i,:,j,j,k).lambda(k))");*/
+                           "M(#1,#1)+= sym(t(:,i,j,:,i,j,k).mu(k)"
+			   "+ t(:,j,i,:,i,j,k).mu(k)"
+			   "+ t(:,i,i,:,j,j,k).lambda(k))");
+    assem.push_mi(mim);
+    assem.push_mf(mf);
+    assem.push_mf(mf_data);
+    assem.push_data(LAMBDA);
+    assem.push_data(MU);
+    assem.push_mat(RM);
+    assem.assembly(rg);
+  }
+
+
+  /** 
+      Stiffness matrix for linear elasticity, with constant Lam� coefficients
+      @ingroup asm
+  */
+  template<class MAT, class VECT>
+  void old_asm_stiffness_matrix_for_homogeneous_linear_elasticity
+  (const MAT &RM_, const mesh_im &mim, const mesh_fem &mf,
+   const VECT &LAMBDA, const VECT &MU,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    MAT &RM = const_cast<MAT &>(RM_);
+    GMM_ASSERT1(mf.get_qdim() == mf.linked_mesh().dim(),
+		"wrong qdim for the mesh_fem");
+    generic_assembly assem("lambda=data$1(1); mu=data$2(1);"
+			   "t=comp(vGrad(#1).vGrad(#1));"
+                           "M(#1,#1)+= sym(t(:,i,j,:,i,j).mu(1)"
+			   "+ t(:,j,i,:,i,j).mu(1)"
+			   "+ t(:,i,i,:,j,j).lambda(1))");
+    assem.push_mi(mim);
+    assem.push_mf(mf);
+    assem.push_data(LAMBDA);
+    assem.push_data(MU);
+    assem.push_mat(RM);
+    assem.assembly(rg);
+  }
+
+  template<typename MAT>
+  void old_asm_stiffness_matrix_for_homogeneous_laplacian
+  (const MAT &M_, const mesh_im &mim, const mesh_fem &mf,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    MAT &M = const_cast<MAT &>(M_);
+    generic_assembly 
+      assem("M$1(#1,#1)+=sym(comp(Grad(#1).Grad(#1))(:,i,:,i))");
+    assem.push_mi(mim);
+    assem.push_mf(mf);
+    assem.push_mat(M);
+    assem.assembly(rg);
+  }
+  
+}
+
+
+
+#define VEC_TEST_1(title, ndof, expr, mim_, region, I_, old_asm)        \
+  cout << "\n" << title << endl;                                        \
+  ch.init(); ch.tic(); workspace.clear_expressions();			\
+  workspace.add_expression(expr, mim_, region);                         \
+  workspace.assembly(1); ch.toc();					\
+  cout << "Elapsed time for new assembly " << ch.elapsed() << endl;     \
+  getfem::base_vector V(ndof), V2(ndof);                                \
+  ch.init(); ch.tic(); old_asm; ch.toc();                               \
+  gmm::copy(V, V2);                                                     \
+  cout << "Elapsed time for old assembly " << ch.elapsed() << endl;     \
+  gmm::add(gmm::scaled(gmm::sub_vector(workspace.assembled_vector(),    \
+                                       I_), scalar_type(-1)), V);       \
+  scalar_type norm_error = gmm::vect_norminf(V);                        \
+  cout << "Error : " << norm_error << endl;
+
+#define VEC_TEST_2(ndof, expr, mim_, region, I_)                        \
+  ch.init(); ch.tic(); workspace.clear_expressions();			\
+  workspace.add_expression(expr, mim_, region);                         \
+  workspace.assembly(1); ch.toc();					\
+  cout << "Elapsed time for new assembly, alternative expression "      \
+          << ch.elapsed() << endl;                                      \
+  gmm::copy(V2, V);                                                     \
+  gmm::add(gmm::scaled(gmm::sub_vector(workspace.assembled_vector(),    \
+                                       I_), scalar_type(-1)), V);       \
+  scalar_type norm_error = gmm::vect_norminf(V);                        \
+  cout << "Error : " << norm_error << endl;
+
+#define VEC_TEST_3(title, ndof, expr, mim_, region)			\
+  cout << "\n" << title << endl;                                        \
+  ch.init(); ch.tic(); workspace.clear_expressions();			\
+  workspace.add_expression(expr, mim_, region);                         \
+  workspace.assembly(1); ch.toc();					\
+  cout << "Elapsed time for new assembly " << ch.elapsed() << endl;
+
+#define MAT_TEST_1(title, ndof1, ndof2, expr, mim_, I1_, I2_, old_asm)  \
+  cout << "\n" << title << endl;					\
+  getfem::model_real_sparse_matrix K(ndof1, ndof2), K2(ndof1, ndof2);   \
+  getfem::model_real_sparse_matrix K3(I1_.last()+1, I2_.last()+1);	\
+  ch.init(); ch.tic(); workspace.clear_expressions();			\
+  workspace.set_assembled_matrix(K3);					\
+  workspace.add_expression(expr, mim_);					\
+  workspace.assembly(2); ch.toc();					\
+  cout << "Elapsed time for new assembly " << ch.elapsed() << endl;     \
+  ch.init(); ch.tic(); old_asm; ch.toc();				\
+  gmm::copy(K, K2);                                                     \
+  cout << "Elapsed time for old assembly " << ch.elapsed() << endl;     \
+  gmm::add(gmm::scaled(gmm::sub_matrix(K3,I1_, I2_),			\
+                       scalar_type(-1)), K);				\
+  scalar_type norm_error = gmm::mat_norminf(K);                         \
+  cout << "Error : " << norm_error << endl;
+
+
+#define MAT_TEST_2(nbdof1, nbdof2, expr, mim_, I1_, I2_)                \
+  gmm::clear(K3);							\
+  ch.init(); ch.tic(); workspace.clear_expressions();			\
+  workspace.add_expression(expr, mim_);                                 \
+  workspace.assembly(2);   ch.toc();					\
+  cout << "Elapsed time for new assembly, alternative expression "      \
+          << ch.elapsed() << endl;                                      \
+  gmm::copy(K2, K);                                                     \
+  gmm::add(gmm::scaled(gmm::sub_matrix(K3, I1_, I1_),			\
+		       scalar_type(-1)), K);				\
+  norm_error = gmm::mat_norminf(K);                                     \
+  cout << "Error : " << norm_error << endl;
+
+
+
+static void test_new_assembly(int N, int NX, int pK) {
+
+  
+  cout << "\n\n-------------------------------------\n"
+       <<     "Tests in dimension " << N << " with P" << pK << " elements"
+       <<   "\n-------------------------------------"
+       << endl << endl;
+
+    
+
+  getfem::ga_workspace workspace;
+  base_vector a(1); a[0] = 3.0;
+  workspace.add_fixed_size_constant("a", a);
+  base_vector b(2); b[0] = 3.0; b[1] = 6.0;
+  workspace.add_fixed_size_constant("b", b);
+  // base_vector c(1); c[0] = 1.0;
+  // workspace.add_fixed_size_variable("c", gmm::sub_interval(0, 1), c);
+  
+  getfem::mesh m;
+  
+  char Ns[5]; sprintf(Ns, "%d", N);
+  char Ks[5]; sprintf(Ks, "%d", pK);
+  bgeot::pgeometric_trans pgt =
+    bgeot::geometric_trans_descriptor
+    ((std::string("GT_PK(") + Ns + ",1)").c_str());
+  std::vector<size_type> nsubdiv(N, NX);
+  getfem::regular_unit_mesh(m, nsubdiv, pgt);
+  
+  const size_type NEUMANN_BOUNDARY_NUM = 1;
+  const size_type DIRICHLET_BOUNDARY_NUM = 2;
+  
+  base_small_vector Dir(N); Dir[N-1] = 1.0;
+  getfem::mesh_region border_faces = getfem::outer_faces_of_mesh(m);
+  getfem::mesh_region Neumann_faces
+    = getfem::select_faces_of_normal(m, border_faces, Dir, 0.1);
+  m.region(NEUMANN_BOUNDARY_NUM) = Neumann_faces;
+  m.region(DIRICHLET_BOUNDARY_NUM)
+    = getfem::mesh_region::subtract(border_faces, Neumann_faces);
+  
+  
+  getfem::mesh_fem mf_u(m);
+  getfem::pfem pf_u = getfem::fem_descriptor
+    ((std::string("FEM_PK(") + Ns + "," + Ks + ")").c_str());
+  mf_u.set_finite_element(m.convex_index(), pf_u);
+  mf_u.set_qdim(dim_type(N));
+  
+  getfem::mesh_fem mf_p(m);
+  getfem::pfem pf_p = getfem::fem_descriptor
+    ((std::string("FEM_PK(") + Ns + "," + Ks + ")").c_str());
+  mf_p.set_finite_element(m.convex_index(), pf_p);
+  
+  getfem::mesh_im mim(m);
+  mim.set_integration_method(m.convex_index(), dim_type(2*pK));
+  
+  getfem::mesh_im mim2(m);
+  mim2.set_integration_method(m.convex_index(), dim_type(2*pK-2));
+  
+  std::vector<scalar_type> U(mf_u.nb_dof());
+  gmm::fill_random(U);
+  std::vector<scalar_type> A(mf_u.nb_dof()*N);
+  gmm::fill_random(A);
+  std::vector<scalar_type> P(mf_p.nb_dof());
+  gmm::fill_random(P);
+  size_type ndofu = mf_u.nb_dof(), ndofp = mf_p.nb_dof();
+  cout << "ndofu = " << ndofu << " ndofp = " << ndofp;
+  
+  gmm::sub_interval Iu(0, ndofu);
+  gmm::sub_interval Ip(ndofu, ndofp);
+  
+  workspace.add_fem_variable("u", mf_u, Iu, U);
+  workspace.add_fem_constant("A", mf_u, A);
+  workspace.add_fem_variable("p", mf_p, Ip, P);
+  
+  getfem::partial_mesh_fem mf_chi(mf_p);
+  dal::bit_vector kept_dof
+    = mf_p.basic_dof_on_region(DIRICHLET_BOUNDARY_NUM);
+  mf_chi.adapt(kept_dof);
+  
+  size_type ndofchi = mf_chi.nb_dof();
+  cout << " ndofchi = " << ndofchi << endl;
+  std::vector<scalar_type> chi(ndofchi);
+  gmm::fill_random(chi);
+  gmm::sub_interval Ichi(ndofu+ndofp, ndofchi);
+  workspace.add_fem_variable("chi", mf_chi, Ichi, chi);
+  
+  
+  
+  chrono ch;
+  
+  bool all = false;
+  bool select = true;
+  int only_one = 6;
+
+  if (all || select || only_one == 1) {
+    VEC_TEST_1("Test for source term", ndofu, "u.Test_u", mim, size_type(-1),
+	       Iu, getfem::old_asm_source_term(V, mim, mf_u, mf_u, U));
+    
+  }
+  
+  if (all ||  select || only_one == 2) {
+    VEC_TEST_3("Test for nonlinear residual", ndofu, "Det(Grad_u)", mim,
+	       size_type(-1));
+  }
+
+  if (all || only_one == 3) {
+    
+    {VEC_TEST_1("Test for Neumann term", ndofu, "u.Test_u",
+		mim, NEUMANN_BOUNDARY_NUM,
+		Iu, getfem::old_asm_source_term(V, mim, mf_u, mf_u,
+					    U, NEUMANN_BOUNDARY_NUM));}
+    
+    {VEC_TEST_1("Test for Neumann term", ndofu,
+		"(((Reshape(A,meshdim,meshdim))')*Normal).Test_u",
+		mim, NEUMANN_BOUNDARY_NUM,
+		Iu, getfem::old_asm_normal_source_term(V, mim, mf_u, mf_u,
+						   A, NEUMANN_BOUNDARY_NUM));}
+    
+    if (N == 2)
+      {VEC_TEST_1("Test for Neumann term", ndofu,
+                  "(A'*Normal).Test_u", mim,
+                  NEUMANN_BOUNDARY_NUM,
+                  Iu, getfem::old_asm_normal_source_term(V, mim, mf_u, mf_u,
+						     A, NEUMANN_BOUNDARY_NUM));}
+    if (N == 3)
+      {VEC_TEST_1("Test for Neumann term", ndofu,
+                  "(A'*Normal).Test_u", mim, NEUMANN_BOUNDARY_NUM,
+                  Iu, getfem::old_asm_normal_source_term(V, mim, mf_u, mf_u,
+						     A, NEUMANN_BOUNDARY_NUM));}
+  }
+  
+  if (all || only_one == 4) {
+    {VEC_TEST_1("Test for Neumann term with reduced fem", ndofchi,
+		"p*Test_chi", mim, DIRICHLET_BOUNDARY_NUM,
+		Ichi, getfem::old_asm_source_term(V, mim, mf_chi, mf_p,
+					      P, DIRICHLET_BOUNDARY_NUM));}
+  }
+  
+  
+  
+  
+  if (all || select || only_one == 5) {
+    MAT_TEST_1("Test for scalar Mass matrix", ndofp, ndofp, "Test_p.Test2_p",
+	       mim, Ip, Ip,  getfem::old_asm_mass_matrix(K, mim, mf_p));
+  }
+
+  // if (all || select || only_one == 6) {
+  //   std::vector<scalar_type> Ca(mf_p.nb_dof());
+  //   gmm::fill_random(Ca);
+  //   workspace.add_fem_constant("Ca", mf_p, Ca);
+  //   MAT_TEST_1("Test for vector Mass matrix", ndofu, ndofu,
+  //              "(Ca*Test_u).Test2_u",
+  // 	          mim, Iu, Iu,
+  //              getfem::old_asm_mass_matrix_param(K, mim, mf_u, mf_p, Ca));
+  // }
+  
+  if (all || select || only_one == 6) {
+    MAT_TEST_1("Test for vector Mass matrix", ndofu, ndofu, "(Test_u).Test2_u",
+   	       mim, Iu, Iu,  getfem::old_asm_mass_matrix(K, mim, mf_u));
+  }
+
+  if (all || select || only_one == 7) {
+    MAT_TEST_1("Test for Laplacian stiffness matrix", ndofp, ndofp,
+	       "Grad_Test_p:Grad_Test2_p", mim2, Ip, Ip,
+	       getfem::old_asm_stiffness_matrix_for_homogeneous_laplacian
+	       (K, mim2, mf_p));
+    // MAT_TEST_2(ndofp, ndofp, "(Grad_p:Grad_p)/2", mim2, Ip, Ip);
+    // MAT_TEST_2(ndofp, ndofp, "sqr(Norm(Grad_p))/2", mim2, Ip, Ip);
+    if (all) {
+      MAT_TEST_2(ndofp, ndofp, "Norm_sqr(Grad_p)/2", mim2, Ip, Ip);
+    }
+    if (all && N == 2) {
+      MAT_TEST_2(ndofp, ndofp,
+		 "(sqr(Grad_p(1)) + sqr(Grad_p(2)))/2", mim2, Ip, Ip);
+      MAT_TEST_2(ndofp, ndofp,
+		 "(Grad_p(1)*Grad_p(1) + Grad_p(2)*Grad_p(2))/2",
+		 mim2, Ip, Ip);
+      MAT_TEST_2(ndofp, ndofp,
+		 "([Grad_p(2); Grad_p(1)].[Grad_p(2); Grad_p(1)])/2",
+		 mim2, Ip, Ip);
+      MAT_TEST_2(ndofp, ndofp, "sqr(Norm([Grad_p(2); Grad_p(1)]))/2",
+		 mim2, Ip, Ip);
+    }
+    if (all && N == 3) {
+      MAT_TEST_2(ndofp, ndofp,
+		 "(sqr(Grad_p(1)) + sqr(Grad_p(2)) + sqr(Grad_p(3)))/2",
+		 mim2, Ip, Ip);
+      MAT_TEST_2(ndofp, ndofp,
+		 "(Grad_p(1)*Grad_p(1) + Grad_p(2)*Grad_p(2)"
+		 "+ Grad_p(3)*Grad_p(3))/2", mim2, Ip, Ip);
+      MAT_TEST_2(ndofp, ndofp,
+		 "([Grad_p(1); Grad_p(3); Grad_p(2)]."
+		 "[Grad_p(1); Grad_p(3); Grad_p(2)])/2",
+		 mim2, Ip, Ip);
+    }
+  }
+  
+  if (all || select || only_one == 8) {
+    base_vector lambda(1); lambda[0] = 3.0;
+    workspace.add_fixed_size_constant("lambda", lambda);
+    base_vector mu(1); mu[0] = 2.0;
+    workspace.add_fixed_size_constant("mu", mu);
+    
+    MAT_TEST_1("Test for linear homogeneous elasticity stiffness matrix",
+	       ndofu, ndofu, "(Div_Test_u*(lambda*Id(qdim(u))) "
+	       "+ (2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim2,
+	       Iu, Iu,
+	       getfem::old_asm_stiffness_matrix_for_homogeneous_linear_elasticity
+	       (K, mim2, mf_u, lambda, mu));
+
+    if (all) {
+      MAT_TEST_2(ndofu, ndofu, "lambda*Div_Test_u*Div_Test2_u "
+		 "+ mu*(Grad_Test_u'+Grad_Test_u):Grad_Test2_u", mim2, Iu, Iu);
+    }
+    
+    // MAT_TEST_2(ndofu, ndofu,
+    //           "lambda*((Grad_Test2_u at Grad_Test_u):Id(meshdim))"
+    //           ":Id(meshdim) + mu*(Grad_Test_u'+Grad_Test_u):Grad_Test2_u",
+    //           mim2, Iu, Iu);
+    
+    // MAT_TEST_2(ndofu, ndofu,
+    //           "lambda*Id(meshdim)@Id(meshdim)*Grad_Test_u"
+    //           ":Grad_Test2_u + mu*(Grad_Test_u'+Grad_Test_u):Grad_Test2_u",
+    //           mim2, Iu, Iu);
+    
+    // MAT_TEST_2(ndofu, ndofu,
+    //           "lambda*(Id(meshdim)*Id(meshdim))@Id(meshdim)"
+    //           "*Grad_Test_u:Grad_Test2_u"
+    //           "+ mu*(Grad_Test_u'+Grad_Test_u):Grad_Test2_u",
+    //           mim2, Iu, Iu);
+    
+    if (N == 2 && all) {
+      MAT_TEST_2(ndofu,ndofu,"lambda*Trace(Grad_Test_u)*Trace(Grad_Test2_u) "
+		 "+mu*(Grad_Test_u'(:,1)"
+		 "+Grad_Test_u(:,1)):Grad_Test2_u(:,1)"
+		 "+mu*(Grad_Test_u'(:,2)"
+		 "+Grad_Test_u(:,2)):Grad_Test2_u(:,2) ", mim2, Iu, Iu);
+      
+      MAT_TEST_2(ndofu,ndofu,"lambda*Trace(Grad_Test_u)*Trace(Grad_Test2_u) "
+		 "+mu*(Grad_Test_u'(1,:)"
+		 "+Grad_Test_u(1,:)):Grad_Test2_u(1,:)"
+		 "+mu*(Grad_Test_u'(2,:)"
+		 "+Grad_Test_u(2,:)):Grad_Test2_u(2,:) ", mim2, Iu, Iu);
+    }
+
+    if (N == 3 && all) {
+      MAT_TEST_2(ndofu,ndofu,"lambda*Trace(Grad_Test_u)*Trace(Grad_Test2_u) "
+		 "+mu*(Grad_Test_u'(:,1)"
+		 "+Grad_Test_u(:,1)):Grad_Test2_u(:,1)"
+		 "+mu*(Grad_Test_u'(:,2)"
+		 "+Grad_Test_u(:,2)):Grad_Test2_u(:,2)"
+		 "+mu*(Grad_Test_u'(:,3)"
+		 "+Grad_Test_u(:,3)):Grad_Test2_u(:,3) ", mim2, Iu, Iu);
+      
+      MAT_TEST_2(ndofu,ndofu,"lambda*Trace(Grad_Test_u)*Trace(Grad_Test2_u) "
+		 "+ mu*(Grad_Test_u'(1,:)"
+		 "+Grad_Test_u(1,:)):Grad_Test2_u(1,:)"
+		 "+ mu*(Grad_Test_u'(2,:)"
+		 "+Grad_Test_u(2,:)):Grad_Test2_u(2,:)"
+		 "+mu*(Grad_Test_u'(3,:)"
+		 "+Grad_Test_u(3,:)):Grad_Test2_u(3,:) ", mim2, Iu, Iu);
+    }
+  }
+  
+  if (all || select || only_one == 9) {
+    base_vector lambda2(ndofp, 3.0);
+    workspace.add_fem_constant("lambda2", mf_p, lambda2);
+    base_vector mu2(ndofp, 2.0);
+    workspace.add_fem_constant("mu2", mf_p, mu2);
+    
+    MAT_TEST_1("Test for linear non homogeneous elasticity stiffness matrix",
+	       ndofu, ndofu, "(Div_Test_u*(lambda2*Id(meshdim)) "
+	       "+ (2*mu2)*Sym(Grad_Test_u)):Grad_Test2_u",
+	       mim2, Iu, Iu,
+	       getfem::old_asm_stiffness_matrix_for_linear_elasticity
+	       (K, mim2, mf_u, mf_p, lambda2, mu2));
+  }
+}
+
+
+int main(int /* argc */, char * /* argv */[]) {
+
+  GMM_SET_EXCEPTION_DEBUG; // Exceptions make a memory fault, to debug.
+  FE_ENABLE_EXCEPT;        // Enable floating point exception for Nan.
+  
+  bool all = true;
+  int only_one = 5;
+
+  // Mesured times for
+  // - new assembly,
+  // - old one,
+  // - estimate of the storage in sparse matrices part for the new assembly,
+  // - global assembly part (assembly instruction),
+  // - ga_exec cost (instructions not executed, includes the compilation and 
+  //   workspace initialization),
+  // - J computation.
+  // - Instructions execution except for assembly ones
+  //                        new  | old  | sto  | asse | exec | Ins  |
+  if (all || only_one == 1) // ndofu = 321602 ndofp = 160801 ndofchi = 1201
+    test_new_assembly(2, 400, 1);
+  // Vector source term   : 0.19 | 0.66 |
+  // Nonlinear residual   : 0.26 |      |
+  // Mass (scalar)        : 0.18 | 0.56 | 0.04 | 0.06 | 0.06 | 0.06 |
+  // Mass (vector)        : 0.27 | 0.80 | 0.08 | 0.11 | 0.06 | 0.09 |
+  // Laplacian            : 0.15 | 0.80 | 0.04 | 0.05 | 0.06 | 0.04 |
+  // Homogeneous elas     : 0.30 | 1.88 | 0.08 | 0.14 | 0.06 | 0.10 |
+  // Non-homogeneous elast: 0.34 | 2.26 | 0.09 | 0.15 | 0.06 | 0.13 |
+  if (all || only_one == 2) // ndofu = 151959 ndofp =  50653 ndofchi = 6553
+    test_new_assembly(3, 36, 1);
+  // Vector source term   : 0.22 | 0.79 |
+  // Nonlinear residual   : 0.40 |      |
+  // Mass (scalar)        : 0.21 | 0.58 | 0.05 | 0.09 | 0.08 | 0.05 |
+  // Mass (vector)        : 0.36 | 1.37 | 0.12 | 0.17 | 0.08 | 0.11 |
+  // Laplacian            : 0.17 | 1.13 | 0.03 | 0.06 | 0.08 | 0.03 |
+  // Homogeneous elas     : 0.59 | 4.25 | 0.26 | 0.33 | 0.08 | 0.18 |
+  // Non-homogeneous elast: 0.63 | 6.29 | 0.26 | 0.33 | 0.08 | 0.22 |
+  if (all || only_one == 3) // ndofu = 321602 ndofp = 160801 ndofchi = 1201
+    test_new_assembly(2, 200, 2);
+  // Vector source term   : 0.08 | 0.23 |
+  // Nonlinear residual   : 0.11 |      |
+  // Mass (scalar)        : 0.08 | 0.25 | 0.02 | 0.03 | 0.03 | 0.02 |
+  // Mass (vector)        : 0.15 | 0.44 | 0.05 | 0.07 | 0.03 | 0.05 |
+  // Laplacian            : 0.07 | 0.37 | 0.02 | 0.03 | 0.03 | 0.01 |
+  // Homogeneous elas     : 0.22 | 1.28 | 0.06 | 0.10 | 0.03 | 0.09 |
+  // Non-homogeneous elast: 0.24 | 2.38 | 0.06 | 0.10 | 0.03 | 0.11 |
+  if (all || only_one == 4) // ndofu = 151959 ndofp =  50653 ndofchi = 6553
+    test_new_assembly(3, 18, 2);
+  // Vector source term   : 0.09 | 0.23 |
+  // Nonlinear residual   : 0.20 |      |
+  // Mass (scalar)        : 0.11 | 0.25 | 0.05 | 0.05 | 0.03 | 0.03 |
+  // Mass (vector)        : 0.29 | 0.89 | 0.11 | 0.16 | 0.03 | 0.10 |
+  // Laplacian            : 0.08 | 0.53 | 0.03 | 0.04 | 0.03 | 0.01 |
+  // Homogeneous elas     : 0.99 | 3.35 | 0.59 | 0.73 | 0.03 | 0.23 |
+  // Non-homogeneous elast: 1.00 | 9.08 | 0.59 | 0.73 | 0.03 | 0.24 |
+  if (all || only_one == 5) // ndofu = 151959 ndofp =  50653 ndofchi = 6553
+    test_new_assembly(3, 9, 4);
+  // Vector source term   : 0.08 | 0.19 |
+  // Nonlinear residual   : 0.16 |      |
+  // Mass (scalar)        : 0.51 | 0.34 | 0.09 | 0.16 | 0.01 | 0.34 |
+  // Mass (vector)        : 1.29 | 1.31 | 0.23 | 0.41 | 0.01 | 0.87 |
+  // Laplacian            : 0.36 | 0.76 | 0.09 | 0.14 | 0.01 | 0.21 |
+  // Homogeneous elas     : 2.74 | 5.23 | 0.82 | 1.41 | 0.01 | 1.32 |
+  // Non-homogeneous elast: 2.66 | 47.4 | 0.82 | 1.41 | 0.01 | 1.24 |
+
+  // Conclusions :
+  // - Deactivation of debug test has no sensible effect.
+  // - Compile time of assembly strings is negligible (< 0.0004)
+  // - (J, K, B) computation takes half the computational time of the exec part
+  // - The call itself of optimized instruction virtual functions is negligible
+  //   It means that a real compilation (g++) avoiding them is not necessary
+  //   and would be far more expensive in compilation time.
+  // - For uniform mesh_fem, the resize operations has been suppressed and
+  //   the "update pfp" has been isolated in a set  of instruction being
+  //   executed only on change of integration method.
+  // - The mass matrix is more expansive due to a larger number of Gauss points.
+  // - Loop unrolling may have an important impact, especially for high degree 
+
+
+  // Remaining possible optimizations
+  // - Computations in geotrans_interpolation_context (J, K, B) can be
+  //   transformed into some optimized instruction specialized with respect
+  //   to the dimension.
+  // - Optimization of the non-linear terms (mainly loops)
+
+  // Original table (r5370) :
+#if 0
+  //                             |      | after| Gain |
+  //                        new  | old  |  opt |factor|
+  test_new_assembly(2, 400, 1);
+  // Vector source term   : 0.76 | 0.77 | 0.19 | 4.00 |
+  // Nonlinear residual   : 1.03 |      | 0.26 | 3.96 |
+  // Mass (scalar)        : 0.80 | 0.64 | 0.18 | 4.44 |
+  // Mass (vector)        : 0.94 | 0.91 | 0.27 | 3.48 |
+  // Laplacian            : 0.55 | 0.88 | 0.15 | 3.66 |
+  // Homogeneous elas     : 0.95 | 2.02 | 0.30 | 3.16 |
+  // Non-homogeneous elast: 1.16 | 2.41 | 0.34 | 3.41 |
+  test_new_assembly(3, 36, 1);
+  // Vector source term   : 0.99 | 1.26 | 0.22 | 4.50 |
+  // Nonlinear residual   : 2.82 |      | 0.40 | 7.05 |
+  // Mass (scalar)        : 0.92 | 0.97 | 0.21 | 4.38 |
+  // Mass (vector)        : 1.70 | 1.80 | 0.36 | 4.72 |
+  // Laplacian            : 0.98 | 1.54 | 0.17 | 5.76 |
+  // Homogeneous elas     : 2.48 | 5.09 | 0.59 | 4.20 |
+  // Non-homogeneous elast: 2.72 | 7.10 | 0.63 | 4.31 |
+  test_new_assembly(2, 200, 2);
+  // Vector source term   : 0.33 | 0.26 | 0.08 | 4.12 |
+  // Nonlinear residual   : 0.47 |      | 0.11 | 4.27 |
+  // Mass (scalar)        : 0.35 | 0.29 | 0.08 | 4.37 |
+  // Mass (vector)        : 0.57 | 0.54 | 0.15 | 3.80 |
+  // Laplacian            : 0.28 | 0.42 | 0.07 | 4.00 |
+  // Homogeneous elas     : 0.74 | 1.42 | 0.22 | 3.36 |
+  // Non-homogeneous elast: 0.89 | 2.56 | 0.24 | 3.71 |
+  test_new_assembly(3, 18, 2);
+  // Vector source term   : 0.49 | 0.28 | 0.09 | 5.44 |
+  // Nonlinear residual   : 1.30 |      | 0.20 | 6.50 |
+  // Mass (scalar)        : 0.51 | 0.37 | 0.11 | 4.64 |
+  // Mass (vector)        : 2.31 | 1.09 | 0.29 | 7.96 |
+  // Laplacian            : 0.38 | 0.65 | 0.08 | 4.75 |
+  // Homogeneous elas     : 3.35 | 4.13 | 0.99 | 3.38 |
+  // Non-homogeneous elast: 3.48 | 10.2 | 1.00 | 3.48 |
+  test_new_assembly(3, 9, 4);
+  // Vector source term   : 0.40 | 0.20 | 0.08 | 5.00 |
+  // Nonlinear residual   : 0.93 |      | 0.16 | 5.81 |
+  // Mass (scalar)        : 0.79 | 0.47 | 0.51 | 1.55 |
+  // Mass (vector)        : 7.11 | 1.59 | 1.29 | 5.51 |
+  // Laplacian            : 0.96 | 0.91 | 0.36 | 2.66 |
+  // Homogeneous elas     : 13.4 | 6.61 | 2.74 | 4.89 |
+  // Non-homogeneous elast: 13.7 | 49.1 | 2.66 | 5.15 |
+#endif
+
+  return 0; 
+}
diff --git a/contrib/aposteriori/aposteriori_laplacian.pl b/contrib/opt_assembly/opt_assembly.pl
similarity index 96%
copy from contrib/aposteriori/aposteriori_laplacian.pl
copy to contrib/opt_assembly/opt_assembly.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/aposteriori/aposteriori_laplacian.pl
+++ b/contrib/opt_assembly/opt_assembly.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/static_contact_gears/Makefile.am b/contrib/static_contact_gears/Makefile.am
index faf0a88..f75d8aa 100755
--- a/contrib/static_contact_gears/Makefile.am
+++ b/contrib/static_contact_gears/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 
 check_PROGRAMS = static_contact_gears static_contact_gears_u1_u2
diff --git a/contrib/static_contact_gears/Makefile.in b/contrib/static_contact_gears/Makefile.in
index 9ea16af..e7335f6 100644
--- a/contrib/static_contact_gears/Makefile.in
+++ b/contrib/static_contact_gears/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -92,6 +99,9 @@ host_triplet = @host@
 check_PROGRAMS = static_contact_gears$(EXEEXT) \
 	static_contact_gears_u1_u2$(EXEEXT)
 subdir = contrib/static_contact_gears
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -107,7 +117,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -392,8 +401,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -461,7 +468,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -494,8 +500,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -576,7 +584,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -631,6 +638,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/static_contact_gears/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/static_contact_gears/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -784,7 +792,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1074,8 +1082,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/static_contact_gears/gear1.msh b/contrib/static_contact_gears/gear1.msh
index 2c23282..18f6b4c 100644
--- a/contrib/static_contact_gears/gear1.msh
+++ b/contrib/static_contact_gears/gear1.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 2562
 1 44.74724891990341 133.7998876864911 0
diff --git a/contrib/static_contact_gears/gear1_2D.msh b/contrib/static_contact_gears/gear1_2D.msh
index fde284d..adfb476 100644
--- a/contrib/static_contact_gears/gear1_2D.msh
+++ b/contrib/static_contact_gears/gear1_2D.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 1302
 1 45.43578452813203 132.3499277508515 0
diff --git a/contrib/static_contact_gears/gear1_2teeth.msh b/contrib/static_contact_gears/gear1_2teeth.msh
index 268fbad..1cd0b78 100644
--- a/contrib/static_contact_gears/gear1_2teeth.msh
+++ b/contrib/static_contact_gears/gear1_2teeth.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 4977
 1 66.15969249061219 124.609876496067 0
diff --git a/contrib/static_contact_gears/gear2.msh b/contrib/static_contact_gears/gear2.msh
index 131fcb5..8f2409f 100644
--- a/contrib/static_contact_gears/gear2.msh
+++ b/contrib/static_contact_gears/gear2.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 2562
 1 23.18246280681928 180.3362969347747 0
diff --git a/contrib/static_contact_gears/gear2_2D.msh b/contrib/static_contact_gears/gear2_2D.msh
index 9d05d7e..696a825 100644
--- a/contrib/static_contact_gears/gear2_2D.msh
+++ b/contrib/static_contact_gears/gear2_2D.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 1157
 1 -23.88095691588316 179.6617392725912 0
diff --git a/contrib/static_contact_gears/gear2_2teeth.msh b/contrib/static_contact_gears/gear2_2teeth.msh
index 6d5211f..867a464 100644
--- a/contrib/static_contact_gears/gear2_2teeth.msh
+++ b/contrib/static_contact_gears/gear2_2teeth.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 4977
 1 -1.172970233056069 179.3478494846721 0
diff --git a/contrib/static_contact_gears/static_contact_gears.cc b/contrib/static_contact_gears/static_contact_gears.cc
index 1d6d5fb..aa318f0 100644
--- a/contrib/static_contact_gears/static_contact_gears.cc
+++ b/contrib/static_contact_gears/static_contact_gears.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Konstantinos Poulios.
+ Copyright (C) 2009-2017 Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/static_contact_gears/static_contact_gears.param b/contrib/static_contact_gears/static_contact_gears.param
index 421ee2f..77279a9 100644
--- a/contrib/static_contact_gears/static_contact_gears.param
+++ b/contrib/static_contact_gears/static_contact_gears.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program static Coulomb friction problem                  %
diff --git a/contrib/static_contact_gears/static_contact_gears.pl b/contrib/static_contact_gears/static_contact_gears.pl
index c976640..10b412a 100755
--- a/contrib/static_contact_gears/static_contact_gears.pl
+++ b/contrib/static_contact_gears/static_contact_gears.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2012-2016 Yves Renard
+# Copyright (C) 2012-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/static_contact_gears/static_contact_gears_2D.param b/contrib/static_contact_gears/static_contact_gears_2D.param
index 47f608b..fa390d1 100644
--- a/contrib/static_contact_gears/static_contact_gears_2D.param
+++ b/contrib/static_contact_gears/static_contact_gears_2D.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program static Coulomb friction problem                  %
diff --git a/contrib/static_contact_gears/static_contact_gears_2teeth.param b/contrib/static_contact_gears/static_contact_gears_2teeth.param
index 5fc67dc..c40deb6 100644
--- a/contrib/static_contact_gears/static_contact_gears_2teeth.param
+++ b/contrib/static_contact_gears/static_contact_gears_2teeth.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program static Coulomb friction problem                  %
diff --git a/contrib/static_contact_gears/static_contact_gears_u1_u2.cc b/contrib/static_contact_gears/static_contact_gears_u1_u2.cc
index eeab238..03b3837 100644
--- a/contrib/static_contact_gears/static_contact_gears_u1_u2.cc
+++ b/contrib/static_contact_gears/static_contact_gears_u1_u2.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Konstantinos Poulios.
+ Copyright (C) 2009-2017 Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/static_contact_gears/static_contact_planetary_1.msh b/contrib/static_contact_gears/static_contact_planetary_1.msh
index 913045d..9a96465 100644
--- a/contrib/static_contact_gears/static_contact_planetary_1.msh
+++ b/contrib/static_contact_gears/static_contact_planetary_1.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 2078
 1 6.583011 41.563504 0
diff --git a/contrib/static_contact_gears/static_contact_planetary_2.msh b/contrib/static_contact_gears/static_contact_planetary_2.msh
index 74b2952..2804c95 100644
--- a/contrib/static_contact_gears/static_contact_planetary_2.msh
+++ b/contrib/static_contact_gears/static_contact_planetary_2.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 3594
 1 7.681971 156.370251 0
diff --git a/contrib/static_contact_gears/static_contact_planetary_3.msh b/contrib/static_contact_gears/static_contact_planetary_3.msh
index c621cd1..78fc3ea 100644
--- a/contrib/static_contact_gears/static_contact_planetary_3.msh
+++ b/contrib/static_contact_gears/static_contact_planetary_3.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 2070
 1 12.9565039286592 143.1257515803001 0
diff --git a/contrib/static_contact_gears/static_contact_planetary_4.msh b/contrib/static_contact_gears/static_contact_planetary_4.msh
index 31bed71..e0274fa 100644
--- a/contrib/static_contact_gears/static_contact_planetary_4.msh
+++ b/contrib/static_contact_gears/static_contact_planetary_4.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 2070
 1 -131.2570322867821 -56.04487987082214 0
diff --git a/contrib/static_contact_gears/static_contact_planetary_5.msh b/contrib/static_contact_gears/static_contact_planetary_5.msh
index c96fcc4..75fe9f7 100644
--- a/contrib/static_contact_gears/static_contact_planetary_5.msh
+++ b/contrib/static_contact_gears/static_contact_planetary_5.msh
@@ -1,6 +1,24 @@
 $MeshFormat
 2.1 0 8
 $EndMeshFormat
+$Comment
+  Copyright (C) 2000-2017 Konstantinos Poulios.
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+$EndComment
 $Nodes
 2070
 1 110.5998408427141 -88.18808569338559 0
diff --git a/contrib/test_plasticity/Makefile.am b/contrib/test_plasticity/Makefile.am
index 439b7b5..8baae31 100644
--- a/contrib/test_plasticity/Makefile.am
+++ b/contrib/test_plasticity/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 check_PROGRAMS = 
 
 CLEANFILES = 
@@ -8,10 +25,9 @@ TESTS = test_plasticity.py
 AM_TESTS_ENVIRONMENT = \
 	export PYTHONPATH=$(top_builddir)/interface/src/python; \
 	export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(top_builddir)/src/.libs;
+LOG_COMPILER = $(PYTHON)
+endif
+
 EXTRA_DIST = \
 	test_plasticity.py \
 	test_small_strain_plasticity.py
-
-LOG_COMPILER = python
-endif
-
diff --git a/contrib/test_plasticity/Makefile.in b/contrib/test_plasticity/Makefile.in
index 1a75192..afca81d 100644
--- a/contrib/test_plasticity/Makefile.in
+++ b/contrib/test_plasticity/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,6 +96,8 @@ build_triplet = @build@
 host_triplet = @host@
 check_PROGRAMS =
 subdir = contrib/test_plasticity
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -104,7 +113,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -333,8 +341,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs \
-	$(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -402,7 +408,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -435,8 +440,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -517,7 +524,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -532,11 +538,11 @@ CLEANFILES =
 @BUILDPYTHON_TRUE@	export PYTHONPATH=$(top_builddir)/interface/src/python; \
 @BUILDPYTHON_TRUE@	export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(top_builddir)/src/.libs;
 
- at BUILDPYTHON_TRUE@EXTRA_DIST = \
- at BUILDPYTHON_TRUE@	test_plasticity.py \
- at BUILDPYTHON_TRUE@	test_small_strain_plasticity.py
+ at BUILDPYTHON_TRUE@LOG_COMPILER = $(PYTHON)
+EXTRA_DIST = \
+	test_plasticity.py \
+	test_small_strain_plasticity.py
 
- at BUILDPYTHON_TRUE@LOG_COMPILER = python
 all: all-am
 
 .SUFFIXES:
@@ -553,6 +559,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/test_plasticity/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/test_plasticity/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -622,7 +629,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -907,8 +914,6 @@ uninstall-am:
 	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \
 	uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/test_plasticity/test_plasticity.py b/contrib/test_plasticity/test_plasticity.py
index d3ecba6..da70964 100644
--- a/contrib/test_plasticity/test_plasticity.py
+++ b/contrib/test_plasticity/test_plasticity.py
@@ -36,7 +36,7 @@ with_graphics=True
 try:
     import getfem_tvtk
 except:
-    print "\n** Could NOT import getfem_tvtk -- graphical output disabled **\n"
+    print("\n** Could NOT import getfem_tvtk -- graphical output disabled **\n")
     import time
     time.sleep(2)
     with_graphics=False
@@ -92,9 +92,9 @@ nbstep = F.shape[0]
 
 dd=mf0.basic_dof_from_cvid()
 
-print 'nbstep:', nbstep
+print('nbstep:', nbstep)
 for step in range(0, nbstep):
-    print 'step %d' % (step,)
+    print('step %d' % (step,))
     md.set_variable('VolumicData', [F[step,0],F[step,1]])
     md.solve('noisy', 'lsearch', 'simplest',  'alpha min', 0.8, 'max_iter', 100, 'max_res', 1e-6)
     U = md.variable('u')
@@ -115,5 +115,5 @@ for step in range(0, nbstep):
     if with_graphics:
         fig = getfem_tvtk.Figure()
         fig.show(mfu, deformation=U, deformation_scale=1, data=(mfdu,VM))
-        print "Press Q to continue.."
+        print("Press Q to continue..")
         fig.loop()
diff --git a/contrib/xfem_contact/Makefile.am b/contrib/xfem_contact/Makefile.am
index e988bcc..313e28f 100644
--- a/contrib/xfem_contact/Makefile.am
+++ b/contrib/xfem_contact/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 if METIS
 optprogs = xfem_dirichlet
 else
diff --git a/contrib/xfem_contact/Makefile.in b/contrib/xfem_contact/Makefile.in
index 568586b..eeed505 100644
--- a/contrib/xfem_contact/Makefile.in
+++ b/contrib/xfem_contact/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -90,6 +97,9 @@ host_triplet = @host@
 check_PROGRAMS = xfem_contact$(EXEEXT) xfem_stokes$(EXEEXT) \
 	$(am__EXEEXT_1)
 subdir = contrib/xfem_contact
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -105,7 +115,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -394,8 +403,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -463,7 +470,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -496,8 +502,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -578,7 +586,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -619,6 +626,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/xfem_contact/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/xfem_contact/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -777,7 +785,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1067,8 +1075,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/xfem_contact/xfem_contact.cc b/contrib/xfem_contact/xfem_contact.cc
index a5c2856..44c08b3 100644
--- a/contrib/xfem_contact/xfem_contact.cc
+++ b/contrib/xfem_contact/xfem_contact.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/xfem_contact/xfem_contact.param b/contrib/xfem_contact/xfem_contact.param
index 56f60b1..bf96c5d 100644
--- a/contrib/xfem_contact/xfem_contact.param
+++ b/contrib/xfem_contact/xfem_contact.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program xfem_contact                                     %
diff --git a/contrib/xfem_contact/xfem_contact.pl b/contrib/xfem_contact/xfem_contact.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/xfem_contact/xfem_contact.pl
+++ b/contrib/xfem_contact/xfem_contact.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/contrib/xfem_contact/xfem_dirichlet.cc b/contrib/xfem_contact/xfem_dirichlet.cc
index c078596..ef63836 100644
--- a/contrib/xfem_contact/xfem_dirichlet.cc
+++ b/contrib/xfem_contact/xfem_dirichlet.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -882,7 +882,7 @@ int main(int argc, char *argv[]) {
       //cout<<"vwgt="<<vwgt<<endl;
 
       scalar_type ratio_size = PARAM.real_value("RATIO_GR_MESH", "ratio size between mesh and patches");
-      cout<<"ratio size beween mesh and coarse mesh= "<< ratio_size <<endl;
+      cout<<"ratio size between mesh and coarse mesh= "<< ratio_size <<endl;
 
       int nparts = 1;
 #if GETFEM_HAVE_METIS
diff --git a/contrib/xfem_contact/xfem_dirichlet.param b/contrib/xfem_contact/xfem_dirichlet.param
index d65c7c0..eaa0ffa 100644
--- a/contrib/xfem_contact/xfem_dirichlet.param
+++ b/contrib/xfem_contact/xfem_dirichlet.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program xfem_dirichlet                                   %
diff --git a/contrib/xfem_contact/xfem_stokes.cc b/contrib/xfem_contact/xfem_stokes.cc
index 0cb3891..bcd253c 100644
--- a/contrib/xfem_contact/xfem_stokes.cc
+++ b/contrib/xfem_contact/xfem_stokes.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/xfem_contact/xfem_stokes.param b/contrib/xfem_contact/xfem_stokes.param
index ad444c5..6575dc0 100644
--- a/contrib/xfem_contact/xfem_stokes.param
+++ b/contrib/xfem_contact/xfem_stokes.param
@@ -1,76 +1,92 @@
-% -*- matlab -*- (enables emacs matlab mode)
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% parameters for program xfem_dirichlet                                   %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-NU = 1.0;	        % Viscosity coefficient.
-
-QUAD = 0;
-N = 2;
-RADIUS = 0.21;             % radius of the real circular domain.
-LEVEL_SET_DEGREE = 2;      % Degree of the piecewise polynomial.
-                           % defining the level set.
-EXACT_SOL = 4;             % Which exact solution.
-SIMPLIFY_LEVEL_SET = 0;
-STABILIZED_DIRICHLET = 1;    % 0 = no, 1 = Barbosa-Hughes stab, 2 = fully stab.
-MINIMAL_ELT_RATIO = 0.005;   % threshold ratio for the fully stab Dirichlet.
-DIRICHLET_GAMMA0 = 0.01;     % Barbosa Hughes stabilization parameter
-		   
-OK = 0;
-
-if (N == 1) 
-  MESH_FILE='structured:GT="GT_PK(1,1)";SIZES=[1];NOISED=0;NSUBDIV=[10]';
-  IM = 'IM_GAUSS1D(6)';     % Integration method.
-  IM_SIMPLEX = IM;          % Integration method on sub-triangles.
-  FEM = 'FEM_PK(1,1)';      % Finite element method for the unknown.
-  FEM_RHS = FEM;            % Finite element method for the rhs
-  FEM_MULT = 'FEM_PK(1,1)'; % Finite element method for multipliers
-  OK = 1;
-end;
-
-if (N == 2 && QUAD)
-  MESH_FILE='structured:GT="GT_QK(2,1)";SIZES=[1,1];NOISED=0;NSUBDIV=[40,40]';
-  IM = 'IM_GAUSS_PARALLELEPIPED(2,6)';        % Integration method.
-  IM_SIMPLEX = 'IM_STRUCTURED_COMPOSITE(IM_TRIANGLE(6),2)';   % Integration method on sub-triangles.
-  FEM = 'FEM_QK(2,2)';      % Finite element method for the velocity u.
-  FEM_RHS = 'FEM_QK(2,2)';     % Finite element method for the rhs
-  FEM_p = 'FEM_QK(2,1)';      % Finite element method for the pressure p.
-%  FEM = 'FEM_PRODUCT(FEM_PK_WITH_CUBIC_BUBBLE(1,1), FEM_PK_WITH_CUBIC_BUBBLE(1,1))';      % Finite element method for the unknown.
-  FEM_MULT = 'FEM_QK(2,0)'; % Finite element method for multipliers
-  OK = 1;
-end;
-
-if (N == 2 && ~QUAD)
-  MESH_FILE='structured:GT="GT_PK(2,1)";SIZES=[1,1];NOISED=0;NSUBDIV=[20,20]';
-%  IM = 'IM_HCT_COMPOSITE(IM_TRIANGLE(6))';
-  IM = 'IM_STRUCTURED_COMPOSITE(IM_TRIANGLE(9),2)';    % Integration method.
-  IM_SIMPLEX = 'IM_STRUCTURED_COMPOSITE(IM_TRIANGLE(9),2)';
-  FEM =     'FEM_PK(2,2)';      % Finite element method for the velocity u.
-  FEM_RHS = 'FEM_PK(2,2)';  % Finite element method for the rhs
-  FEM_p =   'FEM_PK(2,1)';      % Finite element method for the pressure p.
-  FEM_MULT = 'FEM_PK(2,1)'; % Finite element method for multipliers
-  OK = 1;
-end;
-
-if (N == 3 && ~QUAD)
-  MESH_FILE='structured:GT="GT_PK(3,1)";SIZES=[1,1,1];NOISED=0;NSUBDIV=[3,3,3]';
-  IM = 'IM_STRUCTURED_COMPOSITE(IM_TETRAHEDRON(6),1)';    % Integration method.
-  IM_SIMPLEX = 'IM_STRUCTURED_COMPOSITE(IM_TETRAHEDRON(6),1)'; 
-  FEM = 'FEM_PK(3,2)';      % Finite element method for the unknown.
-  FEM_RHS = FEM;            % Finite element method for the rhs
-  FEM_MULT = 'FEM_PK(3,1)'; % Finite element method for multipliers
-  FEM_MULT_DEGREE = 1;      % Degree for multipliers definition
-   OK = 1;
-end;
-
-if (~OK)
-  error ('Adapt the parameter file first');
-end;
-
-
-%%%%%   saving parameters                                             %%%%%
-ROOTFILENAME = 'xfem_dirichlet';     % Root of data files.
-VTK_EXPORT = 2 % export solution to a .vtk file ?
-
-%  FEM = 'FEM_PK_WITH_CUBIC_BUBBLE(2,1)';
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+% -*- matlab -*- (enables emacs matlab mode)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% parameters for program xfem_dirichlet                                   %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+NU = 1.0;	        % Viscosity coefficient.
+
+QUAD = 0;
+N = 2;
+RADIUS = 0.21;             % radius of the real circular domain.
+LEVEL_SET_DEGREE = 2;      % Degree of the piecewise polynomial.
+                           % defining the level set.
+EXACT_SOL = 4;             % Which exact solution.
+SIMPLIFY_LEVEL_SET = 0;
+STABILIZED_DIRICHLET = 1;    % 0 = no, 1 = Barbosa-Hughes stab, 2 = fully stab.
+MINIMAL_ELT_RATIO = 0.005;   % threshold ratio for the fully stab Dirichlet.
+DIRICHLET_GAMMA0 = 0.01;     % Barbosa Hughes stabilization parameter
+		   
+OK = 0;
+
+if (N == 1) 
+  MESH_FILE='structured:GT="GT_PK(1,1)";SIZES=[1];NOISED=0;NSUBDIV=[10]';
+  IM = 'IM_GAUSS1D(6)';     % Integration method.
+  IM_SIMPLEX = IM;          % Integration method on sub-triangles.
+  FEM = 'FEM_PK(1,1)';      % Finite element method for the unknown.
+  FEM_RHS = FEM;            % Finite element method for the rhs
+  FEM_MULT = 'FEM_PK(1,1)'; % Finite element method for multipliers
+  OK = 1;
+end;
+
+if (N == 2 && QUAD)
+  MESH_FILE='structured:GT="GT_QK(2,1)";SIZES=[1,1];NOISED=0;NSUBDIV=[40,40]';
+  IM = 'IM_GAUSS_PARALLELEPIPED(2,6)';        % Integration method.
+  IM_SIMPLEX = 'IM_STRUCTURED_COMPOSITE(IM_TRIANGLE(6),2)';   % Integration method on sub-triangles.
+  FEM = 'FEM_QK(2,2)';      % Finite element method for the velocity u.
+  FEM_RHS = 'FEM_QK(2,2)';     % Finite element method for the rhs
+  FEM_p = 'FEM_QK(2,1)';      % Finite element method for the pressure p.
+%  FEM = 'FEM_PRODUCT(FEM_PK_WITH_CUBIC_BUBBLE(1,1), FEM_PK_WITH_CUBIC_BUBBLE(1,1))';      % Finite element method for the unknown.
+  FEM_MULT = 'FEM_QK(2,0)'; % Finite element method for multipliers
+  OK = 1;
+end;
+
+if (N == 2 && ~QUAD)
+  MESH_FILE='structured:GT="GT_PK(2,1)";SIZES=[1,1];NOISED=0;NSUBDIV=[20,20]';
+%  IM = 'IM_HCT_COMPOSITE(IM_TRIANGLE(6))';
+  IM = 'IM_STRUCTURED_COMPOSITE(IM_TRIANGLE(9),2)';    % Integration method.
+  IM_SIMPLEX = 'IM_STRUCTURED_COMPOSITE(IM_TRIANGLE(9),2)';
+  FEM =     'FEM_PK(2,2)';      % Finite element method for the velocity u.
+  FEM_RHS = 'FEM_PK(2,2)';  % Finite element method for the rhs
+  FEM_p =   'FEM_PK(2,1)';      % Finite element method for the pressure p.
+  FEM_MULT = 'FEM_PK(2,1)'; % Finite element method for multipliers
+  OK = 1;
+end;
+
+if (N == 3 && ~QUAD)
+  MESH_FILE='structured:GT="GT_PK(3,1)";SIZES=[1,1,1];NOISED=0;NSUBDIV=[3,3,3]';
+  IM = 'IM_STRUCTURED_COMPOSITE(IM_TETRAHEDRON(6),1)';    % Integration method.
+  IM_SIMPLEX = 'IM_STRUCTURED_COMPOSITE(IM_TETRAHEDRON(6),1)'; 
+  FEM = 'FEM_PK(3,2)';      % Finite element method for the unknown.
+  FEM_RHS = FEM;            % Finite element method for the rhs
+  FEM_MULT = 'FEM_PK(3,1)'; % Finite element method for multipliers
+  FEM_MULT_DEGREE = 1;      % Degree for multipliers definition
+   OK = 1;
+end;
+
+if (~OK)
+  error ('Adapt the parameter file first');
+end;
+
+
+%%%%%   saving parameters                                             %%%%%
+ROOTFILENAME = 'xfem_dirichlet';     % Root of data files.
+VTK_EXPORT = 2 % export solution to a .vtk file ?
+
+%  FEM = 'FEM_PK_WITH_CUBIC_BUBBLE(2,1)';
 %  FEM = 'FEM_P1_PIECEWISE_LINEAR_BUBBLE';
\ No newline at end of file
diff --git a/contrib/xfem_stab_unilat_contact/Makefile.am b/contrib/xfem_stab_unilat_contact/Makefile.am
index 34bbadb..20b93d5 100644
--- a/contrib/xfem_stab_unilat_contact/Makefile.am
+++ b/contrib/xfem_stab_unilat_contact/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 
 check_PROGRAMS = xfem_stab_unilat_contact
diff --git a/contrib/xfem_stab_unilat_contact/Makefile.in b/contrib/xfem_stab_unilat_contact/Makefile.in
index 150a51b..6455b90 100644
--- a/contrib/xfem_stab_unilat_contact/Makefile.in
+++ b/contrib/xfem_stab_unilat_contact/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # SUBDIRS = 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,9 @@ build_triplet = @build@
 host_triplet = @host@
 check_PROGRAMS = xfem_stab_unilat_contact$(EXEEXT)
 subdir = contrib/xfem_stab_unilat_contact
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +116,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -385,8 +394,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -454,7 +461,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -487,8 +493,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -569,7 +577,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -604,6 +611,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/xfem_stab_unilat_contact/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu contrib/xfem_stab_unilat_contact/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -752,7 +760,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1042,8 +1050,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.cc b/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.cc
index 3387520..86d13b6 100644
--- a/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.cc
+++ b/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.param b/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.param
index 97dc7e9..c6e7119 100644
--- a/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.param
+++ b/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %-*- mat-lab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for    unilateral_contact_problem                            %
diff --git a/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.pl b/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.pl
index 69f3fc6..602a8bb 100644
--- a/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.pl
+++ b/contrib/xfem_stab_unilat_contact/xfem_stab_unilat_contact.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/cubature/CUBE4D_5.IM b/cubature/CUBE4D_5.IM
old mode 100755
new mode 100644
index d521989..bd2126c
--- a/cubature/CUBE4D_5.IM
+++ b/cubature/CUBE4D_5.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 5 on a 4D cube with 24 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/CUBE4D_9.IM b/cubature/CUBE4D_9.IM
old mode 100755
new mode 100644
index b3acc67..54ff92f
--- a/cubature/CUBE4D_9.IM
+++ b/cubature/CUBE4D_9.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 9 on a 4D cube with 145 points (and a negative weight on first point..)
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/GAUSSLOBATTO1D1.IM b/cubature/GAUSSLOBATTO1D1.IM
old mode 100755
new mode 100644
index f3edfd9..eabf33d
--- a/cubature/GAUSSLOBATTO1D1.IM
+++ b/cubature/GAUSSLOBATTO1D1.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(1)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D11.IM b/cubature/GAUSSLOBATTO1D11.IM
old mode 100755
new mode 100644
index e8252b1..0708165
--- a/cubature/GAUSSLOBATTO1D11.IM
+++ b/cubature/GAUSSLOBATTO1D11.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(11)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D13.IM b/cubature/GAUSSLOBATTO1D13.IM
old mode 100755
new mode 100644
index 08e09e3..e6e7230
--- a/cubature/GAUSSLOBATTO1D13.IM
+++ b/cubature/GAUSSLOBATTO1D13.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(13)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D15.IM b/cubature/GAUSSLOBATTO1D15.IM
old mode 100755
new mode 100644
index e0e0c3a..3da8ae1
--- a/cubature/GAUSSLOBATTO1D15.IM
+++ b/cubature/GAUSSLOBATTO1D15.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(15)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D17.IM b/cubature/GAUSSLOBATTO1D17.IM
old mode 100755
new mode 100644
index 9f0cb3c..8f23bb3
--- a/cubature/GAUSSLOBATTO1D17.IM
+++ b/cubature/GAUSSLOBATTO1D17.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(17)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D19.IM b/cubature/GAUSSLOBATTO1D19.IM
old mode 100755
new mode 100644
index d44812a..7767300
--- a/cubature/GAUSSLOBATTO1D19.IM
+++ b/cubature/GAUSSLOBATTO1D19.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(19)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D21.IM b/cubature/GAUSSLOBATTO1D21.IM
old mode 100755
new mode 100644
index 9932560..879bcd0
--- a/cubature/GAUSSLOBATTO1D21.IM
+++ b/cubature/GAUSSLOBATTO1D21.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(21)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D23.IM b/cubature/GAUSSLOBATTO1D23.IM
old mode 100755
new mode 100644
index f0dbe1a..639a9d6
--- a/cubature/GAUSSLOBATTO1D23.IM
+++ b/cubature/GAUSSLOBATTO1D23.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(23)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D25.IM b/cubature/GAUSSLOBATTO1D25.IM
old mode 100755
new mode 100644
index 775ef8b..28f2b8b
--- a/cubature/GAUSSLOBATTO1D25.IM
+++ b/cubature/GAUSSLOBATTO1D25.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(25)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D27.IM b/cubature/GAUSSLOBATTO1D27.IM
old mode 100755
new mode 100644
index 6d278b8..ae52ded
--- a/cubature/GAUSSLOBATTO1D27.IM
+++ b/cubature/GAUSSLOBATTO1D27.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(27)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D29.IM b/cubature/GAUSSLOBATTO1D29.IM
old mode 100755
new mode 100644
index 9661a38..856c842
--- a/cubature/GAUSSLOBATTO1D29.IM
+++ b/cubature/GAUSSLOBATTO1D29.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(29)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D3.IM b/cubature/GAUSSLOBATTO1D3.IM
old mode 100755
new mode 100644
index 625e2ef..b96fde3
--- a/cubature/GAUSSLOBATTO1D3.IM
+++ b/cubature/GAUSSLOBATTO1D3.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(3)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D31.IM b/cubature/GAUSSLOBATTO1D31.IM
old mode 100755
new mode 100644
index 24bcfe4..f69b65c
--- a/cubature/GAUSSLOBATTO1D31.IM
+++ b/cubature/GAUSSLOBATTO1D31.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(31)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D33.IM b/cubature/GAUSSLOBATTO1D33.IM
old mode 100755
new mode 100644
index e05a770..4790c2a
--- a/cubature/GAUSSLOBATTO1D33.IM
+++ b/cubature/GAUSSLOBATTO1D33.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(33)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D35.IM b/cubature/GAUSSLOBATTO1D35.IM
old mode 100755
new mode 100644
index 312558f..c4c05c3
--- a/cubature/GAUSSLOBATTO1D35.IM
+++ b/cubature/GAUSSLOBATTO1D35.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(35)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D37.IM b/cubature/GAUSSLOBATTO1D37.IM
old mode 100755
new mode 100644
index ee2fb9b..1cec343
--- a/cubature/GAUSSLOBATTO1D37.IM
+++ b/cubature/GAUSSLOBATTO1D37.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(37)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D39.IM b/cubature/GAUSSLOBATTO1D39.IM
old mode 100755
new mode 100644
index 4715ee0..a7f0a97
--- a/cubature/GAUSSLOBATTO1D39.IM
+++ b/cubature/GAUSSLOBATTO1D39.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(39)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D41.IM b/cubature/GAUSSLOBATTO1D41.IM
old mode 100755
new mode 100644
index 0d007ee..ed14c41
--- a/cubature/GAUSSLOBATTO1D41.IM
+++ b/cubature/GAUSSLOBATTO1D41.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(41)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D43.IM b/cubature/GAUSSLOBATTO1D43.IM
old mode 100755
new mode 100644
index 126a1f8..72d1439
--- a/cubature/GAUSSLOBATTO1D43.IM
+++ b/cubature/GAUSSLOBATTO1D43.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(43)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D45.IM b/cubature/GAUSSLOBATTO1D45.IM
old mode 100755
new mode 100644
index 28725ee..ed3233c
--- a/cubature/GAUSSLOBATTO1D45.IM
+++ b/cubature/GAUSSLOBATTO1D45.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(45)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D47.IM b/cubature/GAUSSLOBATTO1D47.IM
old mode 100755
new mode 100644
index 5a44ce5..32c1448
--- a/cubature/GAUSSLOBATTO1D47.IM
+++ b/cubature/GAUSSLOBATTO1D47.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(47)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D49.IM b/cubature/GAUSSLOBATTO1D49.IM
old mode 100755
new mode 100644
index cacd8b6..e35fc91
--- a/cubature/GAUSSLOBATTO1D49.IM
+++ b/cubature/GAUSSLOBATTO1D49.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(49)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D5.IM b/cubature/GAUSSLOBATTO1D5.IM
old mode 100755
new mode 100644
index fd4e449..3e152af
--- a/cubature/GAUSSLOBATTO1D5.IM
+++ b/cubature/GAUSSLOBATTO1D5.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(5)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D51.IM b/cubature/GAUSSLOBATTO1D51.IM
old mode 100755
new mode 100644
index 7ef8b0a..4aa9914
--- a/cubature/GAUSSLOBATTO1D51.IM
+++ b/cubature/GAUSSLOBATTO1D51.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(51)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D53.IM b/cubature/GAUSSLOBATTO1D53.IM
old mode 100755
new mode 100644
index 9fa86a3..677c763
--- a/cubature/GAUSSLOBATTO1D53.IM
+++ b/cubature/GAUSSLOBATTO1D53.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(53)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D55.IM b/cubature/GAUSSLOBATTO1D55.IM
old mode 100755
new mode 100644
index fde4861..672936f
--- a/cubature/GAUSSLOBATTO1D55.IM
+++ b/cubature/GAUSSLOBATTO1D55.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(55)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D57.IM b/cubature/GAUSSLOBATTO1D57.IM
old mode 100755
new mode 100644
index 463d0fd..c804aab
--- a/cubature/GAUSSLOBATTO1D57.IM
+++ b/cubature/GAUSSLOBATTO1D57.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(57)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D59.IM b/cubature/GAUSSLOBATTO1D59.IM
old mode 100755
new mode 100644
index 71c8c00..006bb41
--- a/cubature/GAUSSLOBATTO1D59.IM
+++ b/cubature/GAUSSLOBATTO1D59.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(59)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D61.IM b/cubature/GAUSSLOBATTO1D61.IM
old mode 100755
new mode 100644
index d707da2..63826b4
--- a/cubature/GAUSSLOBATTO1D61.IM
+++ b/cubature/GAUSSLOBATTO1D61.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(61)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D63.IM b/cubature/GAUSSLOBATTO1D63.IM
old mode 100755
new mode 100644
index 71ed402..3f375ef
--- a/cubature/GAUSSLOBATTO1D63.IM
+++ b/cubature/GAUSSLOBATTO1D63.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(63)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D65.IM b/cubature/GAUSSLOBATTO1D65.IM
old mode 100755
new mode 100644
index ab04c94..7b3df03
--- a/cubature/GAUSSLOBATTO1D65.IM
+++ b/cubature/GAUSSLOBATTO1D65.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(65)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D67.IM b/cubature/GAUSSLOBATTO1D67.IM
old mode 100755
new mode 100644
index da5d5a1..44b01a7
--- a/cubature/GAUSSLOBATTO1D67.IM
+++ b/cubature/GAUSSLOBATTO1D67.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(67)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D69.IM b/cubature/GAUSSLOBATTO1D69.IM
old mode 100755
new mode 100644
index 4f18217..be74d81
--- a/cubature/GAUSSLOBATTO1D69.IM
+++ b/cubature/GAUSSLOBATTO1D69.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(69)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D7.IM b/cubature/GAUSSLOBATTO1D7.IM
old mode 100755
new mode 100644
index 409c153..25da82f
--- a/cubature/GAUSSLOBATTO1D7.IM
+++ b/cubature/GAUSSLOBATTO1D7.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(7)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D71.IM b/cubature/GAUSSLOBATTO1D71.IM
old mode 100755
new mode 100644
index 49b1f26..021d3a1
--- a/cubature/GAUSSLOBATTO1D71.IM
+++ b/cubature/GAUSSLOBATTO1D71.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(71)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D73.IM b/cubature/GAUSSLOBATTO1D73.IM
old mode 100755
new mode 100644
index 7fa2d8f..f4e1cf4
--- a/cubature/GAUSSLOBATTO1D73.IM
+++ b/cubature/GAUSSLOBATTO1D73.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(73)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D75.IM b/cubature/GAUSSLOBATTO1D75.IM
old mode 100755
new mode 100644
index fca7649..1aac2dd
--- a/cubature/GAUSSLOBATTO1D75.IM
+++ b/cubature/GAUSSLOBATTO1D75.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(75)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D77.IM b/cubature/GAUSSLOBATTO1D77.IM
old mode 100755
new mode 100644
index 3287fcd..4677fde
--- a/cubature/GAUSSLOBATTO1D77.IM
+++ b/cubature/GAUSSLOBATTO1D77.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(77)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D79.IM b/cubature/GAUSSLOBATTO1D79.IM
old mode 100755
new mode 100644
index d002752..9494940
--- a/cubature/GAUSSLOBATTO1D79.IM
+++ b/cubature/GAUSSLOBATTO1D79.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(79)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D81.IM b/cubature/GAUSSLOBATTO1D81.IM
old mode 100755
new mode 100644
index ae843cc..d853619
--- a/cubature/GAUSSLOBATTO1D81.IM
+++ b/cubature/GAUSSLOBATTO1D81.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(81)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D83.IM b/cubature/GAUSSLOBATTO1D83.IM
old mode 100755
new mode 100644
index 52accec..2f78595
--- a/cubature/GAUSSLOBATTO1D83.IM
+++ b/cubature/GAUSSLOBATTO1D83.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(83)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D85.IM b/cubature/GAUSSLOBATTO1D85.IM
old mode 100755
new mode 100644
index ed7e88f..0fc66b3
--- a/cubature/GAUSSLOBATTO1D85.IM
+++ b/cubature/GAUSSLOBATTO1D85.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(85)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D87.IM b/cubature/GAUSSLOBATTO1D87.IM
old mode 100755
new mode 100644
index 1bc2230..c39ccc6
--- a/cubature/GAUSSLOBATTO1D87.IM
+++ b/cubature/GAUSSLOBATTO1D87.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(87)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D89.IM b/cubature/GAUSSLOBATTO1D89.IM
old mode 100755
new mode 100644
index 994a10c..0d77f65
--- a/cubature/GAUSSLOBATTO1D89.IM
+++ b/cubature/GAUSSLOBATTO1D89.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(89)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D9.IM b/cubature/GAUSSLOBATTO1D9.IM
old mode 100755
new mode 100644
index 9e7f649..07e232c
--- a/cubature/GAUSSLOBATTO1D9.IM
+++ b/cubature/GAUSSLOBATTO1D9.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(9)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D91.IM b/cubature/GAUSSLOBATTO1D91.IM
old mode 100755
new mode 100644
index a738a40..1c437e7
--- a/cubature/GAUSSLOBATTO1D91.IM
+++ b/cubature/GAUSSLOBATTO1D91.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(91)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D93.IM b/cubature/GAUSSLOBATTO1D93.IM
old mode 100755
new mode 100644
index 114138f..0e41f10
--- a/cubature/GAUSSLOBATTO1D93.IM
+++ b/cubature/GAUSSLOBATTO1D93.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(93)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D95.IM b/cubature/GAUSSLOBATTO1D95.IM
old mode 100755
new mode 100644
index 7e74abf..1f03ba0
--- a/cubature/GAUSSLOBATTO1D95.IM
+++ b/cubature/GAUSSLOBATTO1D95.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(95)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D97.IM b/cubature/GAUSSLOBATTO1D97.IM
old mode 100755
new mode 100644
index 9f831fb..3845366
--- a/cubature/GAUSSLOBATTO1D97.IM
+++ b/cubature/GAUSSLOBATTO1D97.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(97)
 N=1
diff --git a/cubature/GAUSSLOBATTO1D99.IM b/cubature/GAUSSLOBATTO1D99.IM
old mode 100755
new mode 100644
index 3b51ff1..1abc1ae
--- a/cubature/GAUSSLOBATTO1D99.IM
+++ b/cubature/GAUSSLOBATTO1D99.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_GAUSSLOBATTO1D(99)
 N=1
diff --git a/cubature/Gauss1D1.IM b/cubature/Gauss1D1.IM
old mode 100755
new mode 100644
index e2d4057..94e46e4
--- a/cubature/Gauss1D1.IM
+++ b/cubature/Gauss1D1.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(1)
 N=1
diff --git a/cubature/Gauss1D11.IM b/cubature/Gauss1D11.IM
old mode 100755
new mode 100644
index cef9a46..a95edf3
--- a/cubature/Gauss1D11.IM
+++ b/cubature/Gauss1D11.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(11)
 N=1
diff --git a/cubature/Gauss1D13.IM b/cubature/Gauss1D13.IM
old mode 100755
new mode 100644
index 99de805..bf86d1b
--- a/cubature/Gauss1D13.IM
+++ b/cubature/Gauss1D13.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(13)
 N=1
diff --git a/cubature/Gauss1D15.IM b/cubature/Gauss1D15.IM
old mode 100755
new mode 100644
index c30eb33..464baff
--- a/cubature/Gauss1D15.IM
+++ b/cubature/Gauss1D15.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(15)
 N=1
diff --git a/cubature/Gauss1D17.IM b/cubature/Gauss1D17.IM
old mode 100755
new mode 100644
index 566022e..2f71fa2
--- a/cubature/Gauss1D17.IM
+++ b/cubature/Gauss1D17.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(17)
 N=1
diff --git a/cubature/Gauss1D19.IM b/cubature/Gauss1D19.IM
old mode 100755
new mode 100644
index df780b4..c7c0cc8
--- a/cubature/Gauss1D19.IM
+++ b/cubature/Gauss1D19.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(19)
 N=1
diff --git a/cubature/Gauss1D21.IM b/cubature/Gauss1D21.IM
old mode 100755
new mode 100644
index 0b656b4..3e85e12
--- a/cubature/Gauss1D21.IM
+++ b/cubature/Gauss1D21.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(21)
 N=1
diff --git a/cubature/Gauss1D23.IM b/cubature/Gauss1D23.IM
old mode 100755
new mode 100644
index 1c7b121..84ba907
--- a/cubature/Gauss1D23.IM
+++ b/cubature/Gauss1D23.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(23)
 N=1
diff --git a/cubature/Gauss1D25.IM b/cubature/Gauss1D25.IM
old mode 100755
new mode 100644
index 68b7e20..c029340
--- a/cubature/Gauss1D25.IM
+++ b/cubature/Gauss1D25.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(25)
 N=1
diff --git a/cubature/Gauss1D27.IM b/cubature/Gauss1D27.IM
old mode 100755
new mode 100644
index bb83c7a..adc0289
--- a/cubature/Gauss1D27.IM
+++ b/cubature/Gauss1D27.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(27)
 N=1
diff --git a/cubature/Gauss1D29.IM b/cubature/Gauss1D29.IM
old mode 100755
new mode 100644
index 0a71f3e..f21fe1d
--- a/cubature/Gauss1D29.IM
+++ b/cubature/Gauss1D29.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(29)
 N=1
diff --git a/cubature/Gauss1D3.IM b/cubature/Gauss1D3.IM
old mode 100755
new mode 100644
index 228f20d..299f9ac
--- a/cubature/Gauss1D3.IM
+++ b/cubature/Gauss1D3.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(3)
 N=1
diff --git a/cubature/Gauss1D31.IM b/cubature/Gauss1D31.IM
old mode 100755
new mode 100644
index d79629e..88f4276
--- a/cubature/Gauss1D31.IM
+++ b/cubature/Gauss1D31.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(31)
 N=1
diff --git a/cubature/Gauss1D33.IM b/cubature/Gauss1D33.IM
old mode 100755
new mode 100644
index bfc29cb..fc9236e
--- a/cubature/Gauss1D33.IM
+++ b/cubature/Gauss1D33.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(33)
 N=1
diff --git a/cubature/Gauss1D35.IM b/cubature/Gauss1D35.IM
old mode 100755
new mode 100644
index 952a6d7..97c6860
--- a/cubature/Gauss1D35.IM
+++ b/cubature/Gauss1D35.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(35)
 N=1
diff --git a/cubature/Gauss1D37.IM b/cubature/Gauss1D37.IM
old mode 100755
new mode 100644
index 104662f..a3cfb96
--- a/cubature/Gauss1D37.IM
+++ b/cubature/Gauss1D37.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(37)
 N=1
diff --git a/cubature/Gauss1D39.IM b/cubature/Gauss1D39.IM
old mode 100755
new mode 100644
index fa326ee..4852407
--- a/cubature/Gauss1D39.IM
+++ b/cubature/Gauss1D39.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(39)
 N=1
diff --git a/cubature/Gauss1D41.IM b/cubature/Gauss1D41.IM
old mode 100755
new mode 100644
index 2c7ee17..d00b975
--- a/cubature/Gauss1D41.IM
+++ b/cubature/Gauss1D41.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(41)
 N=1
diff --git a/cubature/Gauss1D43.IM b/cubature/Gauss1D43.IM
old mode 100755
new mode 100644
index e3db9d2..5710c51
--- a/cubature/Gauss1D43.IM
+++ b/cubature/Gauss1D43.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(43)
 N=1
diff --git a/cubature/Gauss1D45.IM b/cubature/Gauss1D45.IM
old mode 100755
new mode 100644
index 19ce331..662a43b
--- a/cubature/Gauss1D45.IM
+++ b/cubature/Gauss1D45.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(45)
 N=1
diff --git a/cubature/Gauss1D47.IM b/cubature/Gauss1D47.IM
old mode 100755
new mode 100644
index acd8204..ee7c7a6
--- a/cubature/Gauss1D47.IM
+++ b/cubature/Gauss1D47.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(47)
 N=1
diff --git a/cubature/Gauss1D49.IM b/cubature/Gauss1D49.IM
old mode 100755
new mode 100644
index 37d73f5..df80970
--- a/cubature/Gauss1D49.IM
+++ b/cubature/Gauss1D49.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(49)
 N=1
diff --git a/cubature/Gauss1D5.IM b/cubature/Gauss1D5.IM
old mode 100755
new mode 100644
index f04c7b0..94cee39
--- a/cubature/Gauss1D5.IM
+++ b/cubature/Gauss1D5.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(5)
 N=1
diff --git a/cubature/Gauss1D51.IM b/cubature/Gauss1D51.IM
old mode 100755
new mode 100644
index 666d6fd..18a3f84
--- a/cubature/Gauss1D51.IM
+++ b/cubature/Gauss1D51.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(51)
 N=1
diff --git a/cubature/Gauss1D53.IM b/cubature/Gauss1D53.IM
old mode 100755
new mode 100644
index 3cb3c9a..36818ff
--- a/cubature/Gauss1D53.IM
+++ b/cubature/Gauss1D53.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(53)
 N=1
diff --git a/cubature/Gauss1D55.IM b/cubature/Gauss1D55.IM
old mode 100755
new mode 100644
index e749eaa..1aa03a4
--- a/cubature/Gauss1D55.IM
+++ b/cubature/Gauss1D55.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(55)
 N=1
diff --git a/cubature/Gauss1D57.IM b/cubature/Gauss1D57.IM
old mode 100755
new mode 100644
index 75463b2..88c1f05
--- a/cubature/Gauss1D57.IM
+++ b/cubature/Gauss1D57.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(57)
 N=1
diff --git a/cubature/Gauss1D59.IM b/cubature/Gauss1D59.IM
old mode 100755
new mode 100644
index 95e72fc..e3530ed
--- a/cubature/Gauss1D59.IM
+++ b/cubature/Gauss1D59.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(59)
 N=1
diff --git a/cubature/Gauss1D61.IM b/cubature/Gauss1D61.IM
old mode 100755
new mode 100644
index f3a63e1..4d28840
--- a/cubature/Gauss1D61.IM
+++ b/cubature/Gauss1D61.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(61)
 N=1
diff --git a/cubature/Gauss1D63.IM b/cubature/Gauss1D63.IM
old mode 100755
new mode 100644
index b42c9a5..22dac1b
--- a/cubature/Gauss1D63.IM
+++ b/cubature/Gauss1D63.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(63)
 N=1
diff --git a/cubature/Gauss1D65.IM b/cubature/Gauss1D65.IM
old mode 100755
new mode 100644
index 0ad6361..d14fdcb
--- a/cubature/Gauss1D65.IM
+++ b/cubature/Gauss1D65.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(65)
 N=1
diff --git a/cubature/Gauss1D67.IM b/cubature/Gauss1D67.IM
old mode 100755
new mode 100644
index a6a8c52..c4b076c
--- a/cubature/Gauss1D67.IM
+++ b/cubature/Gauss1D67.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(67)
 N=1
diff --git a/cubature/Gauss1D69.IM b/cubature/Gauss1D69.IM
old mode 100755
new mode 100644
index 624305f..63e3887
--- a/cubature/Gauss1D69.IM
+++ b/cubature/Gauss1D69.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(69)
 N=1
diff --git a/cubature/Gauss1D7.IM b/cubature/Gauss1D7.IM
old mode 100755
new mode 100644
index 8ffb728..3d6458c
--- a/cubature/Gauss1D7.IM
+++ b/cubature/Gauss1D7.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(7)
 N=1
diff --git a/cubature/Gauss1D71.IM b/cubature/Gauss1D71.IM
old mode 100755
new mode 100644
index dce7797..778e7b7
--- a/cubature/Gauss1D71.IM
+++ b/cubature/Gauss1D71.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(71)
 N=1
diff --git a/cubature/Gauss1D73.IM b/cubature/Gauss1D73.IM
old mode 100755
new mode 100644
index 8c52131..d4c3df8
--- a/cubature/Gauss1D73.IM
+++ b/cubature/Gauss1D73.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(73)
 N=1
diff --git a/cubature/Gauss1D75.IM b/cubature/Gauss1D75.IM
old mode 100755
new mode 100644
index 4fb71a2..9f9aa06
--- a/cubature/Gauss1D75.IM
+++ b/cubature/Gauss1D75.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(75)
 N=1
diff --git a/cubature/Gauss1D77.IM b/cubature/Gauss1D77.IM
old mode 100755
new mode 100644
index d41ca0f..8655dff
--- a/cubature/Gauss1D77.IM
+++ b/cubature/Gauss1D77.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(77)
 N=1
diff --git a/cubature/Gauss1D79.IM b/cubature/Gauss1D79.IM
old mode 100755
new mode 100644
index 93007c1..4387917
--- a/cubature/Gauss1D79.IM
+++ b/cubature/Gauss1D79.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(79)
 N=1
diff --git a/cubature/Gauss1D81.IM b/cubature/Gauss1D81.IM
old mode 100755
new mode 100644
index 5178a53..d6462d5
--- a/cubature/Gauss1D81.IM
+++ b/cubature/Gauss1D81.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(81)
 N=1
diff --git a/cubature/Gauss1D83.IM b/cubature/Gauss1D83.IM
old mode 100755
new mode 100644
index f9594d1..bd188ec
--- a/cubature/Gauss1D83.IM
+++ b/cubature/Gauss1D83.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(83)
 N=1
diff --git a/cubature/Gauss1D85.IM b/cubature/Gauss1D85.IM
old mode 100755
new mode 100644
index 3aad7f7..1414dde
--- a/cubature/Gauss1D85.IM
+++ b/cubature/Gauss1D85.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(85)
 N=1
diff --git a/cubature/Gauss1D87.IM b/cubature/Gauss1D87.IM
old mode 100755
new mode 100644
index 47d434e..611f8e6
--- a/cubature/Gauss1D87.IM
+++ b/cubature/Gauss1D87.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(87)
 N=1
diff --git a/cubature/Gauss1D89.IM b/cubature/Gauss1D89.IM
old mode 100755
new mode 100644
index 58e35f8..ba54d18
--- a/cubature/Gauss1D89.IM
+++ b/cubature/Gauss1D89.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(89)
 N=1
diff --git a/cubature/Gauss1D9.IM b/cubature/Gauss1D9.IM
old mode 100755
new mode 100644
index c2000d0..e12302e
--- a/cubature/Gauss1D9.IM
+++ b/cubature/Gauss1D9.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(9)
 N=1
diff --git a/cubature/Gauss1D91.IM b/cubature/Gauss1D91.IM
old mode 100755
new mode 100644
index cd477cd..45c546b
--- a/cubature/Gauss1D91.IM
+++ b/cubature/Gauss1D91.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(91)
 N=1
diff --git a/cubature/Gauss1D93.IM b/cubature/Gauss1D93.IM
old mode 100755
new mode 100644
index 9cbd6a0..91ceb82
--- a/cubature/Gauss1D93.IM
+++ b/cubature/Gauss1D93.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(93)
 N=1
diff --git a/cubature/Gauss1D95.IM b/cubature/Gauss1D95.IM
old mode 100755
new mode 100644
index 21a4809..9af9142
--- a/cubature/Gauss1D95.IM
+++ b/cubature/Gauss1D95.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(95)
 N=1
diff --git a/cubature/Gauss1D97.IM b/cubature/Gauss1D97.IM
old mode 100755
new mode 100644
index 60cf532..dd54485
--- a/cubature/Gauss1D97.IM
+++ b/cubature/Gauss1D97.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(97)
 N=1
diff --git a/cubature/Gauss1D99.IM b/cubature/Gauss1D99.IM
old mode 100755
new mode 100644
index 38a61b6..632de91
--- a/cubature/Gauss1D99.IM
+++ b/cubature/Gauss1D99.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %% Automatically generated by Maple %%
 NAME=IM_Gauss1D(99)
 N=1
diff --git a/cubature/HEXAHEDRON_11.IM b/cubature/HEXAHEDRON_11.IM
old mode 100755
new mode 100644
index e725bcd..3cc5722
--- a/cubature/HEXAHEDRON_11.IM
+++ b/cubature/HEXAHEDRON_11.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 11 on a 3D Hexahedron with 90 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/HEXAHEDRON_5.IM b/cubature/HEXAHEDRON_5.IM
old mode 100755
new mode 100644
index 3976a62..6667c77
--- a/cubature/HEXAHEDRON_5.IM
+++ b/cubature/HEXAHEDRON_5.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 5 on a 3D Hexahedron with 14 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/HEXAHEDRON_9.IM b/cubature/HEXAHEDRON_9.IM
old mode 100755
new mode 100644
index c7df63f..eeadb5d
--- a/cubature/HEXAHEDRON_9.IM
+++ b/cubature/HEXAHEDRON_9.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 9 on a 3D Hexahedron with 58 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/Makefile.am b/cubature/Makefile.am
index a554f8d..22b2b18 100644
--- a/cubature/Makefile.am
+++ b/cubature/Makefile.am
@@ -1,3 +1,19 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 all : getfem_im_list.h
 check : getfem_im_list.h
diff --git a/cubature/Makefile.in b/cubature/Makefile.in
index 902389e..2e8d9c2 100644
--- a/cubature/Makefile.in
+++ b/cubature/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -88,6 +95,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = cubature
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -103,7 +112,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -128,7 +136,6 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -196,7 +203,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -229,8 +235,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -311,7 +319,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -337,6 +344,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cubature/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu cubature/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -512,8 +520,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 all : getfem_im_list.h
 check : getfem_im_list.h
diff --git a/cubature/NC_0_0.IM b/cubature/NC_0_0.IM
old mode 100755
new mode 100644
index 337234d..c6ff543
--- a/cubature/NC_0_0.IM
+++ b/cubature/NC_0_0.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae on a point, for compatibility only
 NAME=	IM_NC(0,0) % Name of the method
 N=0
diff --git a/cubature/QUAD_17.IM b/cubature/QUAD_17.IM
old mode 100755
new mode 100644
index 0f77977..0514f3f
--- a/cubature/QUAD_17.IM
+++ b/cubature/QUAD_17.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 17 on a quadrangle with 70 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/QUAD_2.IM b/cubature/QUAD_2.IM
old mode 100755
new mode 100644
index c65335d..3a387d1
--- a/cubature/QUAD_2.IM
+++ b/cubature/QUAD_2.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 2 on a quadrangle with 3 points
 NAME = IM_QUAD(2)
 N = 2
diff --git a/cubature/QUAD_3.IM b/cubature/QUAD_3.IM
old mode 100755
new mode 100644
index 7692bc4..d2323ee
--- a/cubature/QUAD_3.IM
+++ b/cubature/QUAD_3.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 3 on a quadrangle with 4 points
 NAME = IM_QUAD(3)
 N = 2
diff --git a/cubature/QUAD_5.IM b/cubature/QUAD_5.IM
old mode 100755
new mode 100644
index 519953d..c77a335
--- a/cubature/QUAD_5.IM
+++ b/cubature/QUAD_5.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 5 on a quadrangle with 7 points
 NAME = IM_QUAD(5)
 N = 2
diff --git a/cubature/QUAD_7.IM b/cubature/QUAD_7.IM
old mode 100755
new mode 100644
index 6ca0a83..81f1cda
--- a/cubature/QUAD_7.IM
+++ b/cubature/QUAD_7.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 7 on a quadrangle with 12 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/QUAD_9.IM b/cubature/QUAD_9.IM
old mode 100755
new mode 100644
index 12ebad8..e0bcd8a
--- a/cubature/QUAD_9.IM
+++ b/cubature/QUAD_9.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 9 on a quadrangle with 20 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/SIMPLEX4D_3.IM b/cubature/SIMPLEX4D_3.IM
old mode 100755
new mode 100644
index 82dcd28..03cf4df
--- a/cubature/SIMPLEX4D_3.IM
+++ b/cubature/SIMPLEX4D_3.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 3 on a 4D simplex with 6 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/TETRA_1.IM b/cubature/TETRA_1.IM
old mode 100755
new mode 100644
index d5e60ce..0e677c9
--- a/cubature/TETRA_1.IM
+++ b/cubature/TETRA_1.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 1 on a tetrahedron with 1 point
 NAME = IM_TETRAHEDRON(1)
 N = 3
diff --git a/cubature/TETRA_2.IM b/cubature/TETRA_2.IM
old mode 100755
new mode 100644
index d66abf3..e380b54
--- a/cubature/TETRA_2.IM
+++ b/cubature/TETRA_2.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 2 on a tetrahedron with 4 points
 % double precision only
 NAME = IM_TETRAHEDRON(2)
diff --git a/cubature/TETRA_3.IM b/cubature/TETRA_3.IM
old mode 100755
new mode 100644
index d20a2c6..927a030
--- a/cubature/TETRA_3.IM
+++ b/cubature/TETRA_3.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 3 on a tetrahedron with 5 points
 NAME = IM_TETRAHEDRON(3)
 N = 3
diff --git a/cubature/TETRA_5.IM b/cubature/TETRA_5.IM
old mode 100755
new mode 100644
index 43d9955..f971c5b
--- a/cubature/TETRA_5.IM
+++ b/cubature/TETRA_5.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 5 on a tetrahedron with 15 points
 % double precision only
 NAME = IM_TETRAHEDRON(5)
diff --git a/cubature/TETRA_6.IM b/cubature/TETRA_6.IM
old mode 100755
new mode 100644
index 4747aa1..29345a4
--- a/cubature/TETRA_6.IM
+++ b/cubature/TETRA_6.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 6 on a tetrahedron with 24 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/TETRA_8.IM b/cubature/TETRA_8.IM
old mode 100755
new mode 100644
index 6642e97..bfc9f20
--- a/cubature/TETRA_8.IM
+++ b/cubature/TETRA_8.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 8 on a tetrahedron with 43 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/TRIANGLE_1.IM b/cubature/TRIANGLE_1.IM
old mode 100755
new mode 100644
index 4cf5f57..8e62d5b
--- a/cubature/TRIANGLE_1.IM
+++ b/cubature/TRIANGLE_1.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 1 on a triangle with 1 point
 NAME = IM_TRIANGLE(1)
 N = 2
diff --git a/cubature/TRIANGLE_10.IM b/cubature/TRIANGLE_10.IM
old mode 100755
new mode 100644
index 994c149..434430e
--- a/cubature/TRIANGLE_10.IM
+++ b/cubature/TRIANGLE_10.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 10 on a triangle with 25 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/TRIANGLE_13.IM b/cubature/TRIANGLE_13.IM
old mode 100755
new mode 100644
index dc4be66..0049b2f
--- a/cubature/TRIANGLE_13.IM
+++ b/cubature/TRIANGLE_13.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 13 on a triangle with 37 points
 % taken from "P. Solin, K. Segeth and I. Dolezel: Higher-Order 
 % Finite Element Methods", Chapman & Hall/CRC Press, 2003.
diff --git a/cubature/TRIANGLE_17.IM b/cubature/TRIANGLE_17.IM
old mode 100755
new mode 100644
index 9291236..626058c
--- a/cubature/TRIANGLE_17.IM
+++ b/cubature/TRIANGLE_17.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 17 on a triangle with 61 points
 % taken from "P. Solin, K. Segeth and I. Dolezel: Higher-Order 
 % Finite Element Methods", Chapman & Hall/CRC Press, 2003.
diff --git a/cubature/TRIANGLE_19.IM b/cubature/TRIANGLE_19.IM
old mode 100755
new mode 100644
index a61ffb3..a5d7c6c
--- a/cubature/TRIANGLE_19.IM
+++ b/cubature/TRIANGLE_19.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 19 on a triangle with 73 points
 % taken from "P. Solin, K. Segeth and I. Dolezel: Higher-Order 
 % Finite Element Methods", Chapman & Hall/CRC Press, 2003.
diff --git a/cubature/TRIANGLE_2.IM b/cubature/TRIANGLE_2.IM
old mode 100755
new mode 100644
index 6484c6c..75e3117
--- a/cubature/TRIANGLE_2.IM
+++ b/cubature/TRIANGLE_2.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 2 on a triangle with 3 points
 NAME = IM_TRIANGLE(2)
 N = 2
diff --git a/cubature/TRIANGLE_3.IM b/cubature/TRIANGLE_3.IM
old mode 100755
new mode 100644
index 5fa11f4..e55008f
--- a/cubature/TRIANGLE_3.IM
+++ b/cubature/TRIANGLE_3.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 3 on a triangle with 4 points
 NAME = IM_TRIANGLE(3)
 N = 2
diff --git a/cubature/TRIANGLE_4.IM b/cubature/TRIANGLE_4.IM
old mode 100755
new mode 100644
index 7897e17..9d89ee8
--- a/cubature/TRIANGLE_4.IM
+++ b/cubature/TRIANGLE_4.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 4 on a triangle with 6 points
 % only double precision
 NAME = IM_TRIANGLE(4)
diff --git a/cubature/TRIANGLE_5.IM b/cubature/TRIANGLE_5.IM
old mode 100755
new mode 100644
index e6f1b2f..a5ffb4b
--- a/cubature/TRIANGLE_5.IM
+++ b/cubature/TRIANGLE_5.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 5 on a triangle with 7 points
 % only double precision
 NAME = IM_TRIANGLE(5)
diff --git a/cubature/TRIANGLE_6.IM b/cubature/TRIANGLE_6.IM
old mode 100755
new mode 100644
index be3f3aa..bbe7633
--- a/cubature/TRIANGLE_6.IM
+++ b/cubature/TRIANGLE_6.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 6 on a triangle with 12 points
 % only double precision
 NAME = IM_TRIANGLE(6)
diff --git a/cubature/TRIANGLE_7.IM b/cubature/TRIANGLE_7.IM
old mode 100755
new mode 100644
index 9e44364..ffb7ad8
--- a/cubature/TRIANGLE_7.IM
+++ b/cubature/TRIANGLE_7.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 7 on a triangle with 13 points
 % only double precision
 NAME = IM_TRIANGLE(7)
diff --git a/cubature/TRIANGLE_8.IM b/cubature/TRIANGLE_8.IM
old mode 100755
new mode 100644
index 9f4754b..ec9688a
--- a/cubature/TRIANGLE_8.IM
+++ b/cubature/TRIANGLE_8.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 8 on a triangle with 16 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/TRIANGLE_9.IM b/cubature/TRIANGLE_9.IM
old mode 100755
new mode 100644
index 13490a7..99697da
--- a/cubature/TRIANGLE_9.IM
+++ b/cubature/TRIANGLE_9.IM
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % Integration formulae of order 9 on a triangle with 19 points
 % taken from the  Encyclopaedia of Cubature Formulas
 % http://www.cs.kuleuven.ac.be/~nines/research/ecf/ecf.html
diff --git a/cubature/getfem_im_list.h b/cubature/getfem_im_list.h
index e30baa3..8d30cdf 100644
--- a/cubature/getfem_im_list.h
+++ b/cubature/getfem_im_list.h
@@ -2,7 +2,7 @@
 
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/cubature/make_getfem_im_list b/cubature/make_getfem_im_list
index 373717f..83c355e 100755
--- a/cubature/make_getfem_im_list
+++ b/cubature/make_getfem_im_list
@@ -1,5 +1,22 @@
-
 # -*- perl -*-
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
 eval 'exec perl -S $0 "$@"'
   if 0;
 
diff --git a/doc/Makefile.am b/doc/Makefile.am
index ad75e64..311f953 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,2 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
 SUBDIRS = sphinx
 
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 5435fcb..bb948ef 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -88,6 +95,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -103,7 +112,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -163,7 +171,6 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -256,7 +263,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -289,8 +295,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -371,7 +379,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -396,6 +403,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu doc/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -690,8 +698,6 @@ uninstall-am:
 	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
 	ps ps-am tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am
index b72aac5..adb8259 100644
--- a/doc/sphinx/Makefile.am
+++ b/doc/sphinx/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # Makefile for Sphinx documentation
 #
 
@@ -29,7 +46,7 @@ help:
 	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
 	@echo "  pdf       to make pdfLaTeX files, you can set PAPER=a4 or PAPER=letter"
 	@echo "  linkcheck to check all external links for integrity"
-	@echo "  upload    to make HTML and LATEX docs and upload it to gna.org"
+	@echo "  upload    to make HTML and LATEX docs and upload it to Savannah.org"
 
 checkout:
 	@if [ ! -d tools ]; then \
@@ -155,4 +172,4 @@ EXTRA_DIST = \
 	source/project/images/Makefile                  \
 	source/matlab/images/Makefile                  \
 	source/python/images/Makefile                  \
-	source/scilab/images/Makefile
\ No newline at end of file
+	source/scilab/images/Makefile
diff --git a/doc/sphinx/Makefile.in b/doc/sphinx/Makefile.in
index 9d1004d..7c076ab 100644
--- a/doc/sphinx/Makefile.in
+++ b/doc/sphinx/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,20 +14,27 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 # Makefile for Sphinx documentation
 #
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = doc/sphinx
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +115,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -148,7 +156,6 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -216,7 +223,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -251,8 +257,10 @@ PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 
 # You can set these variables from the command line.
 PYTHON = python
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -333,7 +341,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -377,6 +384,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/sphinx/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu doc/sphinx/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -592,8 +600,6 @@ uninstall-am:
 	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
 	uninstall-am
 
-.PRECIOUS: Makefile
-
 
 .PHONY: help checkout update images build view html htmlview htmlhelp latex pdf linkcheck clean upload
 
@@ -606,7 +612,7 @@ help:
 	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
 	@echo "  pdf       to make pdfLaTeX files, you can set PAPER=a4 or PAPER=letter"
 	@echo "  linkcheck to check all external links for integrity"
-	@echo "  upload    to make HTML and LATEX docs and upload it to gna.org"
+	@echo "  upload    to make HTML and LATEX docs and upload it to Savannah.org"
 
 checkout:
 	@if [ ! -d tools ]; then \
diff --git a/doc/sphinx/source/matlab/images/Makefile b/doc/sphinx/source/matlab/images/Makefile
index f2de9aa..b80f917 100644
--- a/doc/sphinx/source/matlab/images/Makefile
+++ b/doc/sphinx/source/matlab/images/Makefile
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 FIGS=hierarchy.fig
 
 EPSFIGS=$(FIGS:.fig=.eps)
@@ -9,7 +26,7 @@ PNGFIGS=$(FIGS:.fig=.png)
 	../../../../../bin/fig2eps $(@:.eps=.fig)
 
 .eps.png:
-	convert $(@:.png=.eps) $@
+	convert  -density 200 $(@:.png=.eps) $@
 
 png: $(PNGFIGS)
 
diff --git a/doc/sphinx/source/project/images/Makefile b/doc/sphinx/source/project/images/Makefile
index 3dc6d91..ff9c3fa 100644
--- a/doc/sphinx/source/project/images/Makefile
+++ b/doc/sphinx/source/project/images/Makefile
@@ -1,5 +1,23 @@
-FIGS=diagram.fig \
-     getfemelemelem.fig \
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+FIGS=diagram.fig 		 \
+     getfemelemelem.fig  	 \
+     tree_simple_laplace_tan.fig \
      getfemtransgeo.fig
 
 EPSFIGS=$(FIGS:.fig=.eps)
@@ -11,7 +29,7 @@ PNGFIGS=$(FIGS:.fig=.png)
 	../../../../../bin/fig2eps $(@:.eps=.fig)
 
 .eps.png:
-	convert $(@:.png=.eps) $@
+	convert -density 200 $(@:.png=.eps) $@
 
 png: $(PNGFIGS)
 
diff --git a/doc/sphinx/source/python/images/Makefile b/doc/sphinx/source/python/images/Makefile
index f2de9aa..79d6d96 100644
--- a/doc/sphinx/source/python/images/Makefile
+++ b/doc/sphinx/source/python/images/Makefile
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 FIGS=hierarchy.fig
 
 EPSFIGS=$(FIGS:.fig=.eps)
@@ -9,7 +26,7 @@ PNGFIGS=$(FIGS:.fig=.png)
 	../../../../../bin/fig2eps $(@:.eps=.fig)
 
 .eps.png:
-	convert $(@:.png=.eps) $@
+	convert -density 200 $(@:.png=.eps) $@
 
 png: $(PNGFIGS)
 
diff --git a/doc/sphinx/source/scilab/images/Makefile b/doc/sphinx/source/scilab/images/Makefile
index f2de9aa..79d6d96 100644
--- a/doc/sphinx/source/scilab/images/Makefile
+++ b/doc/sphinx/source/scilab/images/Makefile
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 FIGS=hierarchy.fig
 
 EPSFIGS=$(FIGS:.fig=.eps)
@@ -9,7 +26,7 @@ PNGFIGS=$(FIGS:.fig=.png)
 	../../../../../bin/fig2eps $(@:.eps=.fig)
 
 .eps.png:
-	convert $(@:.png=.eps) $@
+	convert -density 200 $(@:.png=.eps) $@
 
 png: $(PNGFIGS)
 
diff --git a/doc/sphinx/source/userdoc/images/Makefile b/doc/sphinx/source/userdoc/images/Makefile
index 4527f0d..f002e3e 100644
--- a/doc/sphinx/source/userdoc/images/Makefile
+++ b/doc/sphinx/source/userdoc/images/Makefile
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 FIGS=getfemlistargyris.fig                   \
      getfemlistcubeQ1.fig                    \
      getfemlistcubeQ3.fig                    \
@@ -77,6 +94,9 @@ FIGS=getfemlistargyris.fig                   \
      getfemusermodeldetectcontact.fig        \
      getfemusermodelfalsecontact1.fig        \
      getfemusermodelfalsecontact2.fig        \
+     getfemlistpyramidP0.fig                 \
+     getfemlistpyramidP1.fig                 \
+     getfemlistpyramidP2.fig                 \
      ALE_rotating_body.fig		     \
      ALE_translation_body.fig		     \
      ALE_rotating_conf.fig
@@ -90,7 +110,7 @@ PNGFIGS=$(FIGS:.fig=.png)
 	../../../../../bin/fig2eps $(@:.eps=.fig)
 
 .eps.png:
-	convert -density 100 $(@:.png=.eps) $@
+	convert -density 200 $(@:.png=.eps) $@
 
 png: $(PNGFIGS)
 
diff --git a/getfem-config-notinstalled.in b/getfem-config-notinstalled.in
index 467c649..db234ac 100644
--- a/getfem-config-notinstalled.in
+++ b/getfem-config-notinstalled.in
@@ -1,3 +1,21 @@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 #!/bin/sh
 getfemconf=`echo $0 | sed -e s/-notinstalled//`
 if [ -x $getfemconf ]; then
diff --git a/getfem-config.in b/getfem-config.in
index a2ca744..3701ae3 100644
--- a/getfem-config.in
+++ b/getfem-config.in
@@ -1,5 +1,30 @@
 #!/bin/sh
 # @configure_input@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+
+
+
+
+
+
 prefix="@prefix@"
 exec_prefix="@exec_prefix@"
 includedir="@includedir@"
diff --git a/gmm-config.in b/gmm-config.in
old mode 100755
new mode 100644
index dba878d..347a99f
--- a/gmm-config.in
+++ b/gmm-config.in
@@ -1,5 +1,25 @@
 #!/bin/sh
 # @configure_input@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+
 prefix="@prefix@"
 exec_prefix="@exec_prefix@"
 includedir="@includedir@"
diff --git a/install-sh b/install-sh
index 59990a1..377bb86 100755
--- a/install-sh
+++ b/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2014-09-12.12; # UTC
+scriptversion=2011-11-20.07; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -41,15 +41,19 @@ scriptversion=2014-09-12.12; # UTC
 # This script is compatible with the BSD install script, but was written
 # from scratch.
 
-tab='	'
 nl='
 '
-IFS=" $tab$nl"
+IFS=" ""	$nl"
 
-# Set DOITPROG to "echo" to test this script.
+# set DOITPROG to echo to test this script
 
+# Don't use :- since 4.3BSD and earlier shells don't like it.
 doit=${DOITPROG-}
-doit_exec=${doit:-exec}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
 
 # Put in absolute file names if you don't have them in your path;
 # or use environment vars.
@@ -64,6 +68,17 @@ mvprog=${MVPROG-mv}
 rmprog=${RMPROG-rm}
 stripprog=${STRIPPROG-strip}
 
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
 posix_mkdir=
 
 # Desired mode of installed file.
@@ -82,7 +97,7 @@ dir_arg=
 dst_arg=
 
 copy_on_change=false
-is_target_a_directory=possibly
+no_target_directory=
 
 usage="\
 Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
@@ -122,57 +137,46 @@ while test $# -ne 0; do
     -d) dir_arg=true;;
 
     -g) chgrpcmd="$chgrpprog $2"
-        shift;;
+	shift;;
 
     --help) echo "$usage"; exit $?;;
 
     -m) mode=$2
-        case $mode in
-          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
-            echo "$0: invalid mode: $mode" >&2
-            exit 1;;
-        esac
-        shift;;
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
 
     -o) chowncmd="$chownprog $2"
-        shift;;
+	shift;;
 
     -s) stripcmd=$stripprog;;
 
-    -t)
-        is_target_a_directory=always
-        dst_arg=$2
-        # Protect names problematic for 'test' and other utilities.
-        case $dst_arg in
-          -* | [=\(\)!]) dst_arg=./$dst_arg;;
-        esac
-        shift;;
+    -t) dst_arg=$2
+	# Protect names problematic for 'test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
+	shift;;
 
-    -T) is_target_a_directory=never;;
+    -T) no_target_directory=true;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
-    --) shift
-        break;;
+    --)	shift
+	break;;
 
-    -*) echo "$0: invalid option: $1" >&2
-        exit 1;;
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
 
     *)  break;;
   esac
   shift
 done
 
-# We allow the use of options -d and -T together, by making -d
-# take the precedence; this is for compatibility with GNU install.
-
-if test -n "$dir_arg"; then
-  if test -n "$dst_arg"; then
-    echo "$0: target directory not allowed when installing a directory." >&2
-    exit 1
-  fi
-fi
-
 if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
   # When -d is used, all remaining arguments are directories to create.
   # When -t is used, the destination is already specified.
@@ -204,15 +208,6 @@ if test $# -eq 0; then
 fi
 
 if test -z "$dir_arg"; then
-  if test $# -gt 1 || test "$is_target_a_directory" = always; then
-    if test ! -d "$dst_arg"; then
-      echo "$0: $dst_arg: Is not a directory." >&2
-      exit 1
-    fi
-  fi
-fi
-
-if test -z "$dir_arg"; then
   do_exit='(exit $ret); exit $ret'
   trap "ret=129; $do_exit" 1
   trap "ret=130; $do_exit" 2
@@ -228,16 +223,16 @@ if test -z "$dir_arg"; then
 
     *[0-7])
       if test -z "$stripcmd"; then
-        u_plus_rw=
+	u_plus_rw=
       else
-        u_plus_rw='% 200'
+	u_plus_rw='% 200'
       fi
       cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
     *)
       if test -z "$stripcmd"; then
-        u_plus_rw=
+	u_plus_rw=
       else
-        u_plus_rw=,u+rw
+	u_plus_rw=,u+rw
       fi
       cp_umask=$mode$u_plus_rw;;
   esac
@@ -274,15 +269,41 @@ do
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
     if test -d "$dst"; then
-      if test "$is_target_a_directory" = never; then
-        echo "$0: $dst_arg: Is a directory" >&2
-        exit 1
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
       fi
       dstdir=$dst
       dst=$dstdir/`basename "$src"`
       dstdir_status=0
     else
-      dstdir=`dirname "$dst"`
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
       test -d "$dstdir"
       dstdir_status=$?
     fi
@@ -293,81 +314,74 @@ do
   if test $dstdir_status != 0; then
     case $posix_mkdir in
       '')
-        # Create intermediate dirs using mode 755 as modified by the umask.
-        # This is like FreeBSD 'install' as of 1997-10-28.
-        umask=`umask`
-        case $stripcmd.$umask in
-          # Optimize common cases.
-          *[2367][2367]) mkdir_umask=$umask;;
-          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-          *[0-7])
-            mkdir_umask=`expr $umask + 22 \
-              - $umask % 100 % 40 + $umask % 20 \
-              - $umask % 10 % 4 + $umask % 2
-            `;;
-          *) mkdir_umask=$umask,go-w;;
-        esac
-
-        # With -d, create the new directory with the user-specified mode.
-        # Otherwise, rely on $mkdir_umask.
-        if test -n "$dir_arg"; then
-          mkdir_mode=-m$mode
-        else
-          mkdir_mode=
-        fi
-
-        posix_mkdir=false
-        case $umask in
-          *[123567][0-7][0-7])
-            # POSIX mkdir -p sets u+wx bits regardless of umask, which
-            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-            ;;
-          *)
-            # $RANDOM is not portable (e.g. dash);  use it when possible to
-            # lower collision chance
-            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
-            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
-
-            # As "mkdir -p" follows symlinks and we work in /tmp possibly;  so
-            # create the $tmpdir first (and fail if unsuccessful) to make sure
-            # that nobody tries to guess the $tmpdir name.
-            if (umask $mkdir_umask &&
-                $mkdirprog $mkdir_mode "$tmpdir" &&
-                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
-            then
-              if test -z "$dir_arg" || {
-                   # Check for POSIX incompatibilities with -m.
-                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                   # other-writable bit of parent directory when it shouldn't.
-                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                   test_tmpdir="$tmpdir/a"
-                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
-                   case $ls_ld_tmpdir in
-                     d????-?r-*) different_mode=700;;
-                     d????-?--*) different_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
-                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
-                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                   }
-                 }
-              then posix_mkdir=:
-              fi
-              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
-            else
-              # Remove any dirs left behind by ancient mkdir implementations.
-              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
-            fi
-            trap '' 0;;
-        esac;;
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
     esac
 
     if
       $posix_mkdir && (
-        umask $mkdir_umask &&
-        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
       )
     then :
     else
@@ -377,51 +391,53 @@ do
       # directory the slow way, step by step, checking for races as we go.
 
       case $dstdir in
-        /*) prefix='/';;
-        [-=\(\)!]*) prefix='./';;
-        *)  prefix='';;
+	/*) prefix='/';;
+	[-=\(\)!]*) prefix='./';;
+	*)  prefix='';;
       esac
 
+      eval "$initialize_posix_glob"
+
       oIFS=$IFS
       IFS=/
-      set -f
+      $posix_glob set -f
       set fnord $dstdir
       shift
-      set +f
+      $posix_glob set +f
       IFS=$oIFS
 
       prefixes=
 
       for d
       do
-        test X"$d" = X && continue
-
-        prefix=$prefix$d
-        if test -d "$prefix"; then
-          prefixes=
-        else
-          if $posix_mkdir; then
-            (umask=$mkdir_umask &&
-             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
-            # Don't fail if two instances are running concurrently.
-            test -d "$prefix" || exit 1
-          else
-            case $prefix in
-              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
-              *) qprefix=$prefix;;
-            esac
-            prefixes="$prefixes '$qprefix'"
-          fi
-        fi
-        prefix=$prefix/
+	test X"$d" = X && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
       done
 
       if test -n "$prefixes"; then
-        # Don't fail if two instances are running concurrently.
-        (umask $mkdir_umask &&
-         eval "\$doit_exec \$mkdirprog $prefixes") ||
-          test -d "$dstdir" || exit 1
-        obsolete_mkdir_used=true
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
       fi
     fi
   fi
@@ -456,12 +472,15 @@ do
 
     # If -C, don't bother to copy if it wouldn't change the file.
     if $copy_on_change &&
-       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
-       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
-       set -f &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
        set X $old && old=:$2:$4:$5:$6 &&
        set X $new && new=:$2:$4:$5:$6 &&
-       set +f &&
+       $posix_glob set +f &&
+
        test "$old" = "$new" &&
        $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
     then
@@ -474,24 +493,24 @@ do
       # to itself, or perhaps because mv is so ancient that it does not
       # support -f.
       {
-        # Now remove or move aside any old file at destination location.
-        # We try this two ways since rm can't unlink itself on some
-        # systems and the destination file might be busy for other
-        # reasons.  In this case, the final cleanup might fail but the new
-        # file should still install successfully.
-        {
-          test ! -f "$dst" ||
-          $doit $rmcmd -f "$dst" 2>/dev/null ||
-          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
-          } ||
-          { echo "$0: cannot unlink or rename $dst" >&2
-            (exit 1); exit 1
-          }
-        } &&
-
-        # Now rename the file to the real destination.
-        $doit $mvcmd "$dsttmp" "$dst"
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
       }
     fi || exit 1
 
diff --git a/interface/Makefile.am b/interface/Makefile.am
index 3ecf2ed..4f87bb6 100644
--- a/interface/Makefile.am
+++ b/interface/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 #http://sources.redhat.com/automake/automake.html#Local-Macros
 #ACLOCAL_AMFLAGS = -I m4
 
diff --git a/interface/Makefile.in b/interface/Makefile.in
index d76ab40..7975109 100644
--- a/interface/Makefile.in
+++ b/interface/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,20 +14,27 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 #http://sources.redhat.com/automake/automake.html#Local-Macros
 #ACLOCAL_AMFLAGS = -I m4
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = interface
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +115,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -166,7 +174,6 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -259,7 +266,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -292,8 +298,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -374,7 +382,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -404,6 +411,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -698,8 +706,6 @@ uninstall-am:
 	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
 	ps ps-am tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 install-toolbox: all
 	cd src && $(MAKE) install-toolbox
diff --git a/interface/src/Makefile.am b/interface/src/Makefile.am
index 7f8f701..9a858c5 100644
--- a/interface/src/Makefile.am
+++ b/interface/src/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 if BUILDMEX
 subdirMATLAB=matlab
 endif
@@ -8,7 +25,6 @@ endif
 
 if BUILDSCILAB
 subdirSCILAB=scilab
-.NOTPARALLEL: scilab
 endif
 
 SUBDIRS = . $(subdirMATLAB) $(subdirPYTHON) $(subdirSCILAB)
diff --git a/interface/src/Makefile.in b/interface/src/Makefile.in
index 0072ae1..885a375 100644
--- a/interface/src/Makefile.in
+++ b/interface/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -91,6 +98,8 @@ build_triplet = @build@
 host_triplet = @host@
 EXTRA_PROGRAMS = getfem_server$(EXEEXT)
 subdir = interface/src
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -106,7 +115,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -239,8 +247,6 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = . matlab python scilab
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -333,7 +339,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -366,8 +371,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -448,7 +455,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -569,6 +575,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/src/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/src/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -1048,9 +1055,6 @@ uninstall-am: uninstall-binPROGRAMS
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
 
-.PRECIOUS: Makefile
-
- at BUILDSCILAB_TRUE@.NOTPARALLEL: scilab
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/interface/src/getfem_interface.cc b/interface/src/getfem_interface.cc
index 2d26670..1d43da5 100644
--- a/interface/src/getfem_interface.cc
+++ b/interface/src/getfem_interface.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: getfem_interface.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <getfem_interface.h>
 #include <getfemint.h>
 
diff --git a/interface/src/getfem_interface.h b/interface/src/getfem_interface.h
index f575f00..9b5ceab 100644
--- a/interface/src/getfem_interface.h
+++ b/interface/src/getfem_interface.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/getfemint.cc b/interface/src/getfemint.cc
index 7174b63..bc4d03d 100644
--- a/interface/src/getfemint.cc
+++ b/interface/src/getfemint.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2001-2016 Y. Renard, J. Pommier.
+ Copyright (C) 2001-2017 Y. Renard, J. Pommier.
 
  This file is a part of GetFEM++
 
@@ -82,8 +82,9 @@ namespace getfemint {
 
   static std::string dim_of_gfi_array(const gfi_array *t) {
     std::stringstream ss;
-    for (size_type i=0; i < static_cast<size_type>(gfi_array_get_ndim(t)); ++i) {
-      if (i) ss << "x"; ss << gfi_array_get_dim(t)[i];
+    for (size_type i=0; i<static_cast<size_type>(gfi_array_get_ndim(t)); ++i) {
+      if (i) ss << "x";
+      ss << gfi_array_get_dim(t)[i];
     }
     return ss.str();
   }
diff --git a/interface/src/getfemint.h b/interface/src/getfemint.h
index cdc8cef..c93320d 100644
--- a/interface/src/getfemint.h
+++ b/interface/src/getfemint.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2001-2016 Y. Renard, J. Pommier.
+ Copyright (C) 2001-2017 Y. Renard, J. Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/getfemint_gsparse.cc b/interface/src/getfemint_gsparse.cc
index 19caaec..0549d5f 100644
--- a/interface/src/getfemint_gsparse.cc
+++ b/interface/src/getfemint_gsparse.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -64,10 +64,14 @@ namespace getfemint {
   }
 
   void gsparse::destroy() {
-    if (pwscmat_r) delete pwscmat_r; pwscmat_r = 0;
-    if (pwscmat_c) delete pwscmat_c; pwscmat_c = 0;
-    if (pcscmat_r) delete pcscmat_r; pcscmat_r = 0;
-    if (pcscmat_c) delete pcscmat_c; pcscmat_c = 0;
+    if (pwscmat_r) delete pwscmat_r;
+    pwscmat_r = 0;
+    if (pwscmat_c) delete pwscmat_c;
+    pwscmat_c = 0;
+    if (pcscmat_r) delete pcscmat_r;
+    pcscmat_r = 0;
+    if (pcscmat_c) delete pcscmat_c;
+    pcscmat_c = 0;
   }
 
   void gsparse::allocate(size_type m, size_type n, storage_type s_, value_type v_) {
diff --git a/interface/src/getfemint_gsparse.h b/interface/src/getfemint_gsparse.h
index 6e89616..4133d56 100644
--- a/interface/src/getfemint_gsparse.h
+++ b/interface/src/getfemint_gsparse.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2001-2016 Julien Pommier.
+ Copyright (C) 2001-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/getfemint_levelset.cc b/interface/src/getfemint_levelset.cc
index 5a2380d..5257a0c 100644
--- a/interface/src/getfemint_levelset.cc
+++ b/interface/src/getfemint_levelset.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Julien Pommier.
+ Copyright (C) 2007-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/getfemint_levelset.h b/interface/src/getfemint_levelset.h
index 3d5b004..fd708a8 100644
--- a/interface/src/getfemint_levelset.h
+++ b/interface/src/getfemint_levelset.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2001-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2001-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/getfemint_misc.cc b/interface/src/getfemint_misc.cc
index c9db82c..f8054c9 100644
--- a/interface/src/getfemint_misc.cc
+++ b/interface/src/getfemint_misc.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -84,8 +84,8 @@ namespace getfemint {
     std::vector<int> ccnt(nj);
     std::fill(ccnt.begin(), ccnt.end(), 0);
     std::vector<double> rowmax(ni, 0.0), colmax(nj, 0.0);
-    gmm::linalg_traits<gmm::linalg_traits<gf_real_sparse_by_row>
-      ::const_sub_row_type>::const_iterator it, ite;
+    gmm::linalg_traits<gmm::org_type<gmm::linalg_traits<gf_real_sparse_by_row>
+       ::const_sub_row_type>::t>::const_iterator it, ite;
 
     /* first pass : find the maxima / row & column */
     for (int i = 0; i < ni; ++i) {
@@ -159,8 +159,8 @@ namespace getfemint {
     std::vector<int> ccnt(nj);
     std::fill(ccnt.begin(), ccnt.end(), 0);
     std::vector<double> rowmax(ni, 0.0), colmax(nj, 0.0);
-    gmm::linalg_traits<gmm::linalg_traits<gf_real_sparse_by_col>
-      ::const_sub_col_type>::const_iterator it, ite;
+    gmm::linalg_traits<gmm::org_type<gmm::linalg_traits<gf_real_sparse_by_col>
+       ::const_sub_col_type>::t>::const_iterator it, ite;
 
     /* first pass : find the maxima / row & column */
     for (int j = 0; j < nj; ++j) {
diff --git a/interface/src/getfemint_misc.h b/interface/src/getfemint_misc.h
index 2ccc624..57d235a 100644
--- a/interface/src/getfemint_misc.h
+++ b/interface/src/getfemint_misc.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2001-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2001-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/getfemint_precond.h b/interface/src/getfemint_precond.h
index 683192c..da668e9 100644
--- a/interface/src/getfemint_precond.h
+++ b/interface/src/getfemint_precond.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2001-2016 Julien Pommier.
+ Copyright (C) 2001-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/getfemint_std.h b/interface/src/getfemint_std.h
index 404b187..a4235b5 100644
--- a/interface/src/getfemint_std.h
+++ b/interface/src/getfemint_std.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/getfemint_workspace.cc b/interface/src/getfemint_workspace.cc
index 47b3587..826b40e 100644
--- a/interface/src/getfemint_workspace.cc
+++ b/interface/src/getfemint_workspace.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Julien Pommier.
+ Copyright (C) 2002-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: getfemint_workspace.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #define GETFEMINT_WORKSPACE_C
 
 #include <getfem/dal_singleton.h>
diff --git a/interface/src/getfemint_workspace.h b/interface/src/getfemint_workspace.h
index e1f5197..599f1d1 100644
--- a/interface/src/getfemint_workspace.h
+++ b/interface/src/getfemint_workspace.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Julien Pommier
+ Copyright (C) 2002-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -28,7 +28,7 @@
  might be covered by the GNU Lesser General Public License.
 
 ===========================================================================*/
-// $Id: getfemint_workspace.h 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #ifndef GETFEMINT_WORKSPACE_H__
 #define GETFEMINT_WORKSPACE_H__
 
@@ -60,7 +60,7 @@ namespace getfemint {
       getfemint_class_id class_id;
       std::vector<dal::pstatic_stored_object> dependent_on;
 
-      object_info() : raw_pointer(0), class_id(GETFEMINT_NB_CLASS) {}
+      object_info() : raw_pointer(0), workspace(-1), class_id(GETFEMINT_NB_CLASS) {}
     };
 
     typedef std::vector<object_info>  obj_ct;
diff --git a/interface/src/gf_asm.cc b/interface/src/gf_asm.cc
index e6baa8c..d3af874 100644
--- a/interface/src/gf_asm.cc
+++ b/interface/src/gf_asm.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -933,40 +933,6 @@ void gf_asm(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
          THROW_BADARG("too much arguments for asm(nonlinear_elasticity)");
        );
 
-
-    /*@FUNC @CELL{K, B} = ('stokes', @tmim mim, @tmf mf_u, @tmf mf_p, @tmf mf_d, @dvec nu[, @int region])
-    Assembly of matrices for the Stokes problem.
-
-    :math:`-\nu(x)\Delta u + \nabla p = 0`
-    :math:`\nabla\cdot u  = 0`
-    with :math:`\nu` (`nu`), the fluid's dynamic viscosity.
-
-    On output, `K` is the usual linear elasticity stiffness matrix with
-    :math:`\lambda = 0` and
-    :math:`2\mu = \nu`. `B` is a matrix
-    corresponding to :math:`\int p\nabla\cdot\phi`.
-
-    `K` and `B` are @tsp object's.
-    @*/
-    sub_command
-      ("stokes", 5, 6, 0, 2,
-       const getfem::mesh_im *mim = get_mim(in);
-       const getfem::mesh_fem *mf_u = to_meshfem_object(in.pop());
-       const getfem::mesh_fem *mf_p = to_meshfem_object(in.pop());
-       const getfem::mesh_fem *mf_d = to_meshfem_object(in.pop());
-       darray           vec_d = in.pop().to_darray(int(mf_d->nb_dof()));
-       gf_real_sparse_by_col  K(mf_u->nb_dof(), mf_u->nb_dof());
-       gf_real_sparse_by_col  B(mf_u->nb_dof(), mf_p->nb_dof());
-       size_type region = size_type(-1);
-       if (in.remaining()) region = in.pop().to_integer();
-       getfem::mesh_region rg(region);
-       mf_u->linked_mesh().intersect_with_mpi_region(rg);
-       getfem::asm_stokes(K, B, *mim, *mf_u, *mf_p, *mf_d, vec_d, rg);
-       out.pop().from_sparse(K);
-       out.pop().from_sparse(B);
-       );
-
-
     /*@FUNC A = ('helmholtz', @tmim mim, @tmf mf_u, @tmf mf_d, @cvec k[, @int region])
     Assembly of the matrix for the Helmholtz problem.
 
diff --git a/interface/src/gf_compute.cc b/interface/src/gf_compute.cc
index 169e481..1942fd6 100644
--- a/interface/src/gf_compute.cc
+++ b/interface/src/gf_compute.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -232,7 +232,7 @@ void gf_compute(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
     Compute the L2 norm of the (real or complex) field `U`.
 
     If `CVids` is given, the norm will be computed only on the listed
-    convexes.@*/
+    elements.@*/
     sub_command
       ("L2 norm", 1, 2, 0, 1,
        U_is_a_vector(U, "L2 norm");
@@ -248,7 +248,7 @@ void gf_compute(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
     Compute the L2 distance between `U` and `U2`.
 
     If `CVids` is given, the norm will be computed only on the listed
-    convexes.@*/
+    elements.@*/
     sub_command
       ("L2 dist", 3, 4, 0, 1,
        U_is_a_vector(U, "L2 dist");
@@ -262,15 +262,13 @@ void gf_compute(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
 
 	 out.pop().from_scalar(getfem::asm_L2_dist(*mim, *mf, U.real(),
 						   *mf_2, V, bv));
-       } else {
-	 GMM_ASSERT1(false, "Sorry, complex version to be done");
-//          carray st = in.pop().to_carray();
-//          std::vector<std::complex<double> > V(st.begin(), st.end());
-// 	 dal::bit_vector bv = in.remaining() ?
-// 	   in.pop().to_bit_vector(&mf->convex_index()) : mf->convex_index();
-
-//          out.pop().from_scalar(getfem::asm_L2_dist(*mim, *mf, U.cplx(),
-// 						   *mf_2, V, bv));
+       } else {	 
+	 carray st = in.pop().to_carray();
+	 std::vector<std::complex<double> > V(st.begin(), st.end());
+ 	 dal::bit_vector bv = in.remaining() ?
+ 	   in.pop().to_bit_vector(&mf->convex_index()) : mf->convex_index();
+	 out.pop().from_scalar(getfem::asm_L2_dist(*mim, *mf, U.cplx(),
+						   *mf_2, V, bv));
        }
        );
 
@@ -279,7 +277,7 @@ void gf_compute(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
     Compute the L2 norm of grad(`U`).
 
     If `CVids` is given, the norm will be computed only on the listed
-    convexes.@*/
+    elements.@*/
     sub_command
       ("H1 semi norm", 1, 2, 0, 1,
        U_is_a_vector(U, "H1 semi norm");
@@ -298,7 +296,7 @@ void gf_compute(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
     Compute the semi H1 distance between `U` and `U2`.
 
     If `CVids` is given, the norm will be computed only on the listed
-    convexes.@*/
+    elements.@*/
     sub_command
       ("H1 semi dist", 3, 4, 0, 1,
        U_is_a_vector(U, "H1 semi dist");
@@ -311,16 +309,15 @@ void gf_compute(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
 	   in.pop().to_bit_vector(&mf->convex_index()) : mf->convex_index();
 
 	 out.pop().from_scalar(getfem::asm_H1_semi_dist(*mim, *mf, U.real(),
-						   *mf_2, V, bv));
+							*mf_2, V, bv));
        } else {
-	 GMM_ASSERT1(false, "Sorry, complex version to be done");
-//          carray st = in.pop().to_carray();
-//          std::vector<std::complex<double> > V(st.begin(), st.end());
-// 	 dal::bit_vector bv = in.remaining() ?
-// 	   in.pop().to_bit_vector(&mf->convex_index()) : mf->convex_index();
-
-//          out.pop().from_scalar(getfem::asm_L2_dist(*mim, *mf, U.cplx(),
-// 						   *mf_2, V, bv));
+	 carray st = in.pop().to_carray();
+	 std::vector<std::complex<double> > V(st.begin(), st.end());
+ 	 dal::bit_vector bv = in.remaining() ?
+ 	   in.pop().to_bit_vector(&mf->convex_index()) : mf->convex_index();
+	 
+	 out.pop().from_scalar(getfem::asm_H1_semi_dist(*mim, *mf, U.cplx(),
+							*mf_2, V, bv));
        }
        );
 
@@ -329,7 +326,7 @@ void gf_compute(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
     Compute the H1 norm of `U`.
 
     If `CVids` is given, the norm will be computed only on the listed
-    convexes.@*/
+    elements.@*/
     sub_command
       ("H1 norm", 1, 2, 0, 1,
        U_is_a_vector(U, "H1 norm");
@@ -347,7 +344,7 @@ void gf_compute(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
     Compute the L2 norm of D^2(`U`).
 
     If `CVids` is given, the norm will be computed only on the listed
-    convexes.@*/
+    elements.@*/
     sub_command
       ("H2 semi norm", 1, 2, 0, 1,
        U_is_a_vector(U, "H2 semi norm");
@@ -366,7 +363,7 @@ void gf_compute(getfemint::mexargs_in& m_in, getfemint::mexargs_out& m_out) {
     Compute the H2 norm of `U`.
 
     If `CVids` is given, the norm will be computed only on the listed
-    convexes.@*/
+    elements.@*/
     sub_command
       ("H2 norm", 1, 2, 0, 1,
        U_is_a_vector(U, "H2 norm");
diff --git a/interface/src/gf_cont_struct.cc b/interface/src/gf_cont_struct.cc
index 4fdb70a..69a775e 100644
--- a/interface/src/gf_cont_struct.cc
+++ b/interface/src/gf_cont_struct.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2012-2016 Tomas Ligursky, Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2012-2017 Tomas Ligursky, Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_cont_struct_get.cc b/interface/src/gf_cont_struct_get.cc
index 25c11c6..90b3bfc 100644
--- a/interface/src/gf_cont_struct_get.cc
+++ b/interface/src/gf_cont_struct_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2012-2016 Tomas Ligursky, Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2012-2017 Tomas Ligursky, Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
@@ -230,8 +230,8 @@ void gf_cont_struct_get(getfemint::mexargs_in& m_in,
        the non-smooth point. It is supposed that the point given by
        `solution` and `parameter` is a point on a smooth solution branch
        within the distance equal to the minimum step size from the end point
-       of this branch, and the corresponding tangent that is directed towards
-       the end point is given by `tangent_sol` and `tangent_par`.@*/
+       of this branch, and the corresponding tangent given by `tangent_sol`
+       and `tangent_par` is directed towards the end point.@*/
     sub_command
       ("non-smooth branching", 4, 4, 0, 0,
 
diff --git a/interface/src/gf_cvstruct_get.cc b/interface/src/gf_cvstruct_get.cc
index f608ba1..52dacc7 100644
--- a/interface/src/gf_cvstruct_get.cc
+++ b/interface/src/gf_cvstruct_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_delete.cc b/interface/src/gf_delete.cc
index 3519afa..12f3b67 100644
--- a/interface/src/gf_delete.cc
+++ b/interface/src/gf_delete.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2001-2016 Yves Renard.
+ Copyright (C) 2001-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_eltm.cc b/interface/src/gf_eltm.cc
index 2df953b..65e1963 100644
--- a/interface/src/gf_eltm.cc
+++ b/interface/src/gf_eltm.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_fem.cc b/interface/src/gf_fem.cc
index 41c6830..217cffe 100644
--- a/interface/src/gf_fem.cc
+++ b/interface/src/gf_fem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_fem.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <getfem/getfem_mesh_im.h>
 #include <getfem/getfem_mesh_fem.h>
 #include <getfem/getfem_interpolated_fem.h>
diff --git a/interface/src/gf_fem_get.cc b/interface/src/gf_fem_get.cc
index d2d106d..42ce850 100644
--- a/interface/src/gf_fem_get.cc
+++ b/interface/src/gf_fem_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_geotrans.cc b/interface/src/gf_geotrans.cc
index 94e5f98..5081b65 100644
--- a/interface/src/gf_geotrans.cc
+++ b/interface/src/gf_geotrans.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_geotrans_get.cc b/interface/src/gf_geotrans_get.cc
index 6424450..fc62333 100644
--- a/interface/src/gf_geotrans_get.cc
+++ b/interface/src/gf_geotrans_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_global_function.cc b/interface/src/gf_global_function.cc
index c89b833..fe3aa05 100644
--- a/interface/src/gf_global_function.cc
+++ b/interface/src/gf_global_function.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Luis Saavedra.
+ Copyright (C) 2009-2017 Luis Saavedra.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_global_function.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <getfemint.h>
 #include <getfemint_workspace.h>
 #include <getfem/getfem_global_function.h>
diff --git a/interface/src/gf_global_function_get.cc b/interface/src/gf_global_function_get.cc
index edeeb05..8f50f19 100644
--- a/interface/src/gf_global_function_get.cc
+++ b/interface/src/gf_global_function_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Luis Saavedra.
+ Copyright (C) 2009-2017 Luis Saavedra.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_global_function_get.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <getfemint.h>
 #include <getfem/getfem_global_function.h>
 
diff --git a/interface/src/gf_integ.cc b/interface/src/gf_integ.cc
index 8d9642c..ec24dd1 100644
--- a/interface/src/gf_integ.cc
+++ b/interface/src/gf_integ.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_integ_get.cc b/interface/src/gf_integ_get.cc
index d0cf5cb..525525c 100644
--- a/interface/src/gf_integ_get.cc
+++ b/interface/src/gf_integ_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_levelset.cc b/interface/src/gf_levelset.cc
index 96d9226..519e92d 100644
--- a/interface/src/gf_levelset.cc
+++ b/interface/src/gf_levelset.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2005-2016 Julien Pommier.
+ Copyright (C) 2005-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_levelset_get.cc b/interface/src/gf_levelset_get.cc
index 4e60328..3fbbff5 100644
--- a/interface/src/gf_levelset_get.cc
+++ b/interface/src/gf_levelset_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Julien Pommier.
+ Copyright (C) 2006-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_levelset_set.cc b/interface/src/gf_levelset_set.cc
index 287771c..41efb96 100644
--- a/interface/src/gf_levelset_set.cc
+++ b/interface/src/gf_levelset_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Julien Pommier.
+ Copyright (C) 2006-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_linsolve.cc b/interface/src/gf_linsolve.cc
index 65e5e39..395bf62 100644
--- a/interface/src/gf_linsolve.cc
+++ b/interface/src/gf_linsolve.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_mesh.cc b/interface/src/gf_mesh.cc
index b937635..c59ea36 100644
--- a/interface/src/gf_mesh.cc
+++ b/interface/src/gf_mesh.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2005-2016 Julien Pommier.
+ Copyright (C) 2005-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_mesh.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <getfemint.h>
 #include <getfemint_workspace.h>
 #include <getfem/getfem_import.h>
@@ -98,6 +98,82 @@ cartesian_mesh(getfem::mesh *pmesh, getfemint::mexargs_in &in,
   }
 }
 
+static void
+pyramidal_mesh(getfem::mesh *pmesh, getfemint::mexargs_in &in) {
+  getfemint::size_type dim = 3;
+
+  std::vector<darray> ppos(dim);
+  std::vector<size_type> npts(dim);
+  size_type grid_npoints=1, grid_nconvex=1;
+  for (size_type i = 0; i < dim; i++) {
+    ppos[i] = in.pop().to_darray();
+    npts[i] = ppos[i].size();
+    grid_npoints *= npts[i];
+    grid_nconvex *= (npts[i]-1);
+  }
+
+  /* add the points in 'fortran style' order */
+  getfem::base_node pt(dim);
+  for (size_type i=0; i < grid_npoints; i++) {
+    size_type k = i;
+    for (size_type j = 0; j < dim; j++) {
+      pt[j] = ppos[j][k % (npts[j])];
+      k /= (npts[j]);
+    }
+
+    size_type id_pt = pmesh->add_point(pt);
+    if (id_pt != i) {
+      THROW_ERROR(
+		"something has changed in getfem, you need to reconsider "
+		"gf_mesh('cartesian')\nfor point " << i <<
+		", the index is " << id_pt << endl);
+    }
+  }
+
+  std::vector<int> ipt(dim);
+  std::vector<getfem::base_node> pts(1 << (dim+1));
+
+  bgeot::pgeometric_trans pgt = bgeot::pyramidal_geotrans(1);
+
+  /* add the convexes */
+  for (size_type i=0; i < grid_nconvex; i++) {
+    size_type k = i;
+
+    /* find point location */
+    for (size_type j = 0; j < dim; j++) {
+      ipt[j] = int(k % (npts[j]-1));
+      k /= (npts[j]-1);
+    }
+
+    /* build the vertices list */
+    for (size_type j = 0; j < (unsigned(1)<<dim); j++) {
+      pts[j].resize(dim);
+      for (size_type d=0; d < dim; d++) {
+	if ((j >> d) & 1) {
+	  pts[j][d] = ppos[d][ipt[d]+1];
+	} else {
+	  pts[j][d] = ppos[d][ipt[d]];
+	}
+      }
+    }
+	
+    bgeot::base_node barycenter(3);
+    std::vector<size_type> iipts(8);
+    for (size_type j = 0; j < 8; j++) {
+	barycenter += pts[j];
+	iipts[j] = pmesh->add_point(pts[j]);
+    }
+    barycenter /= 8.;
+    size_type ib = pmesh->add_point(barycenter);
+    pmesh->add_pyramid(iipts[0],iipts[1],iipts[2],iipts[3],ib);
+    pmesh->add_pyramid(iipts[7],iipts[6],iipts[5],iipts[4],ib);
+    pmesh->add_pyramid(iipts[0],iipts[4],iipts[1],iipts[5],ib);
+    pmesh->add_pyramid(iipts[1],iipts[5],iipts[3],iipts[7],ib);
+    pmesh->add_pyramid(iipts[3],iipts[7],iipts[2],iipts[6],ib);
+    pmesh->add_pyramid(iipts[2],iipts[6],iipts[0],iipts[4],ib);
+
+  }
+}
 
 static void
 triangles_grid_mesh(getfem::mesh *pmesh, getfemint::mexargs_in &in)
@@ -190,7 +266,7 @@ regular_simplices_mesh(getfem::mesh *pmesh, getfemint::mexargs_in &in) {
       }
       pmesh->add_convex_by_points(pgt, pts.begin());
     }
-    pmesh->optimize_structure();
+    pmesh->optimize_structure(false);
   }
 
   getfem::base_small_vector diff(N);
@@ -355,6 +431,12 @@ void gf_mesh(getfemint::mexargs_in& m_in,
        cartesian_mesh(pmesh, in);
        );
 
+    /*@INIT M = ('pyramidal', @dvec X[, @dvec Y[, @dvec Z,..]])
+      Build quickly a regular mesh of pyramids, etc.@*/
+    sub_command
+      ("pyramidal", 1, 32, 0, 1,
+       pyramidal_mesh(pmesh, in);
+       );
 
     /*@INIT M = ('cartesian Q1', @dvec X, @dvec Y[, @dvec Z,..])
       Build quickly a regular mesh of quadrangles, cubes, etc. with
@@ -474,6 +556,7 @@ void gf_mesh(getfemint::mexargs_in& m_in,
 
       - 'gmsh' for a mesh created with `Gmsh`
       - 'gid' for a mesh created with `GiD`
+      - 'cdb' for a mesh created with `ANSYS`
       - 'am_fmt' for a mesh created with `EMC2`@*/
     sub_command
       ("import", 2, 2, 0, 1,
diff --git a/interface/src/gf_mesh_fem.cc b/interface/src/gf_mesh_fem.cc
index cdcd313..c66ac5e 100644
--- a/interface/src/gf_mesh_fem.cc
+++ b/interface/src/gf_mesh_fem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_mesh_fem_get.cc b/interface/src/gf_mesh_fem_get.cc
index e71637a..21d9587 100644
--- a/interface/src/gf_mesh_fem_get.cc
+++ b/interface/src/gf_mesh_fem_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Julien Pommier.
+ Copyright (C) 2006-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_mesh_fem_get.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 
 #include <getfem/getfem_fem.h>
 #include <getfem/getfem_export.h>
@@ -509,40 +509,39 @@ void gf_mesh_fem_get(getfemint::mexargs_in& m_in,
        );
 
     /*@GET Vr = ('reduce vector', @vec V)
-    Multiply the provided vector V with the extension matrix of the @tmf.@*/
+      Multiply the provided vector V with the extension matrix of the @tmf.@*/
     sub_command
       ("reduce vector", 1, 1, 0, 1,
        if (in.front().is_complex()) {
-         carray V = in.pop().to_carray(-1);
-         std::vector<std::complex<double> > Vr(mf->nb_dof());
-         mf->reduce_vector(V, Vr);
-         out.pop().from_dcvector(Vr);
+	 carray V = in.pop().to_carray(-1);
+	 std::vector<std::complex<double> > Vr(mf->nb_dof());
+	 mf->reduce_vector(V, Vr);
+	 out.pop().from_dcvector(Vr);
        } else {
-         darray V = in.pop().to_darray(-1);
-         std::vector<double> Vr(mf->nb_dof());
-         mf->reduce_vector(V, Vr);
-         out.pop().from_dcvector(Vr);
+	 darray V = in.pop().to_darray(-1);
+	 std::vector<double> Vr(mf->nb_dof());
+	 mf->reduce_vector(V, Vr);
+	 out.pop().from_dcvector(Vr);
        }
        );
-
+    
     /*@GET Ve = ('extend vector', @vec V)
-    Multiply the provided vector V with the reduction matrix of the @tmf.@*/
+      Multiply the provided vector V with the reduction matrix of the @tmf.@*/
     sub_command
       ("extend vector", 1, 1, 0, 1,
        if (in.front().is_complex()) {
-         carray V = in.pop().to_carray(-1);
-         std::vector<std::complex<double> > Ve(mf->nb_basic_dof());
-         mf->extend_vector(V, Ve);
-         out.pop().from_dcvector(Ve);
+	 carray V = in.pop().to_carray(-1);
+	 std::vector<std::complex<double> > Ve(mf->nb_basic_dof());
+	 mf->extend_vector(V, Ve);
+	 out.pop().from_dcvector(Ve);
        } else {
-         darray V = in.pop().to_darray(-1);
-         std::vector<double> Ve(mf->nb_basic_dof());
-         mf->extend_vector(V, Ve);
-         out.pop().from_dcvector(Ve);
+	 darray V = in.pop().to_darray(-1);
+	 std::vector<double> Ve(mf->nb_basic_dof());
+	 mf->extend_vector(V, Ve);
+	 out.pop().from_dcvector(Ve);
        }
        );
-
-
+    
     /*@GET DOFs = ('basic dof on region', at mat Rs)
     Return the list of basic dof (before the optional reduction) lying on one
     of the mesh regions listed in `Rs`.
@@ -971,18 +970,18 @@ void gf_mesh_fem_get(getfemint::mexargs_in& m_in,
       nbd = P.shape[1]
     vars = ('x','y','z','u','v','w')
     nbvars = min(P.shape[0],len(vars))
-    for i in xrange(0,nbvars):
+    for i in range(0,nbvars):
       gl[vars[i]] = P[i,0]
       lo[vars[i]] = P[i,0]
     ccode = compile(expression, '<string>', 'eval');
     r = numpy.array(eval(ccode,gl,lo))
     Z = numpy.zeros(r.shape + (nbd,), r.dtype)
-    nbd_p = nbd/nbp
+    nbd_p = int(nbd/nbp)
     nbd_end = nbd_p*(rk+1)
     if (rk == nbp-1):
       nbd_end = nbd
-    for j in xrange(nbd_p*rk,nbd_end):
-      for i in xrange(0,nbvars):
+    for j in range(nbd_p*rk,nbd_end):
+      for i in range(0,nbvars):
         gl[vars[i]] = P[i,j]
         lo[vars[i]] = P[i,j]
       Z[...,j] = eval(ccode,gl,lo)
diff --git a/interface/src/gf_mesh_fem_set.cc b/interface/src/gf_mesh_fem_set.cc
index 1e5c6ad..b758f95 100644
--- a/interface/src/gf_mesh_fem_set.cc
+++ b/interface/src/gf_mesh_fem_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Julien Pommier.
+ Copyright (C) 2006-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_mesh_get.cc b/interface/src/gf_mesh_get.cc
index e1ef139..61c70a2 100644
--- a/interface/src/gf_mesh_get.cc
+++ b/interface/src/gf_mesh_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_mesh_get.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <map>
 #include <getfemint_misc.h>
 #include <getfem/getfem_export.h>
diff --git a/interface/src/gf_mesh_im.cc b/interface/src/gf_mesh_im.cc
index 1de74bd..3a696fb 100644
--- a/interface/src/gf_mesh_im.cc
+++ b/interface/src/gf_mesh_im.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_mesh_im_data.cc b/interface/src/gf_mesh_im_data.cc
index 64a2309..8bece7f 100644
--- a/interface/src/gf_mesh_im_data.cc
+++ b/interface/src/gf_mesh_im_data.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2014-2016 Konstantinos Poulios.
+ Copyright (C) 2014-2017 Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_mesh_im_data_get.cc b/interface/src/gf_mesh_im_data_get.cc
index 52f788c..77a0309 100644
--- a/interface/src/gf_mesh_im_data_get.cc
+++ b/interface/src/gf_mesh_im_data_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2014-2016 Konstantinos Poulios.
+ Copyright (C) 2014-2017 Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_mesh_im_data_set.cc b/interface/src/gf_mesh_im_data_set.cc
index f939569..de68f82 100644
--- a/interface/src/gf_mesh_im_data_set.cc
+++ b/interface/src/gf_mesh_im_data_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2014-2016 Konstantinos Poulios.
+ Copyright (C) 2014-2017 Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_mesh_im_get.cc b/interface/src/gf_mesh_im_get.cc
index e42cef2..437fef0 100644
--- a/interface/src/gf_mesh_im_get.cc
+++ b/interface/src/gf_mesh_im_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -24,7 +24,7 @@
 #include <getfem/getfem_integration.h>
 #include <getfem/getfem_mat_elem.h>
 /*
-  $Id: gf_mesh_im_get.cc 5353 2016-07-26 13:36:19Z renard $
+  $Id$
  */
 
 
diff --git a/interface/src/gf_mesh_im_set.cc b/interface/src/gf_mesh_im_set.cc
index c283bba..cfc398d 100644
--- a/interface/src/gf_mesh_im_set.cc
+++ b/interface/src/gf_mesh_im_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_mesh_levelset.cc b/interface/src/gf_mesh_levelset.cc
index d6dab33..e60767a 100644
--- a/interface/src/gf_mesh_levelset.cc
+++ b/interface/src/gf_mesh_levelset.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2005-2016 Julien Pommier.
+ Copyright (C) 2005-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_mesh_levelset.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <getfemint.h>
 #include <getfem/getfem_mesh_level_set.h>
 #include <getfemint_workspace.h>
diff --git a/interface/src/gf_mesh_levelset_get.cc b/interface/src/gf_mesh_levelset_get.cc
index da22430..1858400 100644
--- a/interface/src/gf_mesh_levelset_get.cc
+++ b/interface/src/gf_mesh_levelset_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Julien Pommier.
+ Copyright (C) 2006-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_mesh_levelset_get.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <getfem/getfem_mesh_level_set.h>
 #include <getfemint.h>
 #include <getfemint_workspace.h>
diff --git a/interface/src/gf_mesh_levelset_set.cc b/interface/src/gf_mesh_levelset_set.cc
index 3fd3577..42535e8 100644
--- a/interface/src/gf_mesh_levelset_set.cc
+++ b/interface/src/gf_mesh_levelset_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Julien Pommier.
+ Copyright (C) 2006-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_mesh_levelset_set.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <getfem/getfem_mesh_level_set.h>
 #include <getfemint.h>
 #include <getfemint_levelset.h>
diff --git a/interface/src/gf_mesh_set.cc b/interface/src/gf_mesh_set.cc
index 71b39a9..4cbe639 100644
--- a/interface/src/gf_mesh_set.cc
+++ b/interface/src/gf_mesh_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -372,7 +372,7 @@ void gf_mesh_set(getfemint::mexargs_in& m_in,
        );
 
 
-    /*@SET ('optimize structure')
+    /*@SET ('optimize structure'[, @int with_renumbering])
     Reset point and convex numbering.
 
     After optimisation, the points (resp. convexes) will
@@ -381,8 +381,10 @@ void gf_mesh_set(getfemint::mexargs_in& m_in,
     (resp. MESH:GET('max cvid'))}@PYTHON{``0`` to
     ``MESH:GET('max pid')-1`` (resp. ``MESH:GET('max cvid')-1``)}.@*/
     sub_command
-      ("optimize structure", 0, 0, 0, 0,
-       pmesh->optimize_structure();
+      ("optimize structure", 0, 1, 0, 0,
+       bool with_renumbering = true;
+       if (in.remaining()) with_renumbering = (in.pop().to_integer(0,1) != 0);
+       pmesh->optimize_structure(with_renumbering);
        );
 
 
diff --git a/interface/src/gf_mesher_object.cc b/interface/src/gf_mesher_object.cc
index 5ac9bba..3cb0dae 100644
--- a/interface/src/gf_mesher_object.cc
+++ b/interface/src/gf_mesher_object.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2011-2016 Yves Renard.
+ Copyright (C) 2011-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_mesher_object_get.cc b/interface/src/gf_mesher_object_get.cc
index 802cc80..4d82030 100644
--- a/interface/src/gf_mesher_object_get.cc
+++ b/interface/src/gf_mesher_object_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2011-2016 Yves Renard.
+ Copyright (C) 2011-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_model.cc b/interface/src/gf_model.cc
index 954d1f8..0254cba 100644
--- a/interface/src/gf_model.cc
+++ b/interface/src/gf_model.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard.
+ Copyright (C) 2009-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_model_get.cc b/interface/src/gf_model_get.cc
index a29f9af..ba0d365 100644
--- a/interface/src/gf_model_get.cc
+++ b/interface/src/gf_model_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard.
+ Copyright (C) 2009-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
@@ -411,19 +411,19 @@ void gf_model_get(getfemint::mexargs_in& m_in,
        Possible values are 'superlu', 'mumps' (if supported),
        'cg/ildlt', 'gmres/ilu' and 'gmres/ilut'.
     - 'lsearch', @str LINE_SEARCH_NAME
-       select explicitely the line search method used for the linear systems
-       (the default value is 'default').
+       select explicitely the line search method used for the linear systems (the
+       default value is 'default').
        Possible values are 'simplest', 'systematic', 'quadratic' or 'basic'.
 
-    Return the number of iterations, if an iterative method is used.
+      Return the number of iterations, if an iterative method is used.
       
-    Note that it is possible to disable some variables
-    (see MODEL:SET('disable variable') ) in order to
-    solve the problem only with respect to a subset of variables (the
-    disabled variables are then considered as data) for instance to
-    replace the global Newton strategy with a fixed point one.
+      Note that it is possible to disable some variables
+      (see MODEL:SET('disable variable') ) in order to
+      solve the problem only with respect to a subset of variables (the
+      disabled variables are then considered as data) for instance to
+      replace the global Newton strategy with a fixed point one.
 
-    @*/
+      @*/
     sub_command
       ("solve", 0, 17, 0, 2,
        getfemint::interruptible_iteration iter;
@@ -874,7 +874,7 @@ void gf_model_get(getfemint::mexargs_in& m_in,
 
     /*@GET ('elastoplasticity next iter', @tmim mim, @str varname, @str previous_dep_name, @str projname, @str datalambda, @str datamu, @str datathreshold, @str datasigma)
       Used with the old (obsolete) elastoplasticity brick to pass from an
-      iteration to the next one. 
+      iteration to the next one.
       Compute and save the stress constraints sigma for the next iterations.
       'mim' is the integration method to use for the computation.
       'varname' is the main variable of the problem.
@@ -900,7 +900,7 @@ void gf_model_get(getfemint::mexargs_in& m_in,
         datalambda, datamu, datathreshold, datasigma);
        );
 
-    /*@GET ('small strain elastoplasticity next iter', @tmim mim,  @str lawname, @str unknowns_type [, @str varnames, ...] [, @str params, ...] [, @str theta = '1' [, @str dt = 'timestep']] [, @int region = -1])
+    /*@GET ('small strain elastoplasticity next iter', @tmim mim,  @str lawname, @str unknowns_type [, @str varnames, ...] [, @str params, ...] [, @str theta = '1' [, @str dt = 'timestep']] [, @int region = -1]) 	 
       Function that allows to pass from a time step to another for the
       small strain plastic brick. The parameters have to be exactly the
       same than the one of `add_small_strain_elastoplasticity_brick`,
@@ -919,64 +919,64 @@ void gf_model_get(getfemint::mexargs_in& m_in,
        filter_lawname(lawname);
        size_type nb_var = 0; size_type nb_params = 0;
        if (lawname.compare("isotropic_perfect_plasticity") == 0 ||
-           lawname.compare("prandtl_reuss") == 0 ||
-           lawname.compare("plane_strain_isotropic_perfect_plasticity") == 0 ||
-           lawname.compare("plane_strain_prandtl_reuss") == 0) {
-         nb_var = nb_params = 3;
+	   lawname.compare("prandtl_reuss") == 0 ||
+	   lawname.compare("plane_strain_isotropic_perfect_plasticity") == 0 ||
+	   lawname.compare("plane_strain_prandtl_reuss") == 0) {
+	 nb_var = nb_params = 3;
        } else if
-         (lawname.compare("isotropic_plasticity_linear_hardening") == 0 ||
-          lawname.compare("prandtl_reuss_linear_hardening") == 0 ||
-          lawname.compare("plane_strain_isotropic_plasticity_linear_hardening") == 0 ||
-          lawname.compare("plane_strain_prandtl_reuss_linear_hardening") == 0) {
-         nb_var = 4; nb_params = 5;
+	   (lawname.compare("isotropic_plasticity_linear_hardening") == 0 ||
+	    lawname.compare("prandtl_reuss_linear_hardening") == 0 ||
+	    lawname.compare("plane_strain_isotropic_plasticity_linear_hardening") == 0 ||
+	    lawname.compare("plane_strain_prandtl_reuss_linear_hardening") == 0) {
+	 nb_var = 4; nb_params = 5;
        } else
-         THROW_BADARG(lawname << " is not an implemented elastoplastic law");
+	 THROW_BADARG(lawname << " is not an implemented elastoplastic law");
 
-       getfem::plasticity_unknowns_type unknowns_type(getfem::DISPLACEMENT_ONLY);
+       getfem::plasticity_unknowns_type unknowns_type(getfem::DISPLACEMENT_ONLY); 	 
        mexarg_in argin = in.pop();
        if (argin.is_string()) {
-         std::string opt = argin.to_string();
-         filter_lawname(opt);
-         if (opt.compare("displacement_only") == 0)
-           unknowns_type = getfem::DISPLACEMENT_ONLY;
-         else if (opt.compare("displacement_and_plastic_multiplier") == 0)
-           unknowns_type = getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER;
-         else
-           THROW_BADARG("Wrong input");
+	 std::string opt = argin.to_string();
+	 filter_lawname(opt);
+	 if (opt.compare("displacement_only") == 0)
+	   unknowns_type = getfem::DISPLACEMENT_ONLY;
+	 else if (opt.compare("displacement_and_plastic_multiplier") == 0)
+	   unknowns_type = getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER;
+	 else
+	   THROW_BADARG("Wrong input");
        } else if (argin.is_integer())
-         unknowns_type = static_cast<getfem::plasticity_unknowns_type>
-                         (argin.to_integer(0,1));
+	 unknowns_type = static_cast<getfem::plasticity_unknowns_type>
+	   (argin.to_integer(0,1));
 
        std::vector<std::string> varnames;
        for (size_type i = 0; i < nb_var; ++i)
-         varnames.push_back(in.pop().to_string());
-
+	 varnames.push_back(in.pop().to_string());
+       
        std::vector<std::string> params;
        for (size_type i = 0; i < nb_params; ++i)
-         params.push_back(in.pop().to_string());
-
+	 params.push_back(in.pop().to_string());
+       
        std::string theta = "1";
        std::string dt = "timestep";
        size_type region = size_type(-1);
        for (size_type i=0; i < 3 && in.remaining(); ++i) {
-         argin = in.pop();
-         if (argin.is_string()) {
-           if (i==0)      theta = argin.to_string();
-           else if (i==1) dt = argin.to_string();
-           else           THROW_BADARG("Wrong input");
-         } else if (argin.is_integer()) {
-           region = argin.to_integer();
-           GMM_ASSERT1(!in.remaining(), "Wrong input");
-         }
+	 argin = in.pop();
+	 if (argin.is_string()) {
+	   if (i==0)      theta = argin.to_string();
+	   else if (i==1) dt = argin.to_string();
+	   else           THROW_BADARG("Wrong input");
+	 } else if (argin.is_integer()) {
+	   region = argin.to_integer();
+	   GMM_ASSERT1(!in.remaining(), "Wrong input");
+	 }
        }
        params.push_back(theta);
        params.push_back(dt);
-
+       
        getfem::small_strain_elastoplasticity_next_iter
-         (*md, *mim, lawname, unknowns_type, varnames, params, region);
+       (*md, *mim, lawname, unknowns_type, varnames, params, region);
        workspace().set_dependence(md, mim);
        );
-
+    
     /*@GET V = ('small strain elastoplasticity Von Mises', @tmim mim, @tmf mf_vm, @str lawname, @str unknowns_type [, @str varnames, ...] [, @str params, ...] [, @str theta = '1' [, @str dt = 'timestep']] [, @int region])
       This function computes the Von Mises stress field with respect to
       a small strain elastoplasticity term, approximated on `mf_vm`,
@@ -985,7 +985,7 @@ void gf_model_get(getfemint::mexargs_in& m_in,
       Remember that `small_strain_elastoplasticity_next_iter` has to be called
       before any call of this function.
       @*/
-    sub_command
+    sub_command 	 
       ("small strain elastoplasticity Von Mises", 11, 16, 0, 0,
        getfem::mesh_im *mim = to_meshim_object(in.pop());
        const getfem::mesh_fem *mf_vm = to_meshfem_object(in.pop());
@@ -993,67 +993,69 @@ void gf_model_get(getfemint::mexargs_in& m_in,
        filter_lawname(lawname);
        size_type nb_var = 0; size_type nb_params = 0;
        if (lawname.compare("isotropic_perfect_plasticity") == 0 ||
-           lawname.compare("prandtl_reuss") == 0 ||
-           lawname.compare("plane_strain_isotropic_perfect_plasticity") == 0 ||
-           lawname.compare("plane_strain_prandtl_reuss") == 0) {
-         nb_var = nb_params = 3;
+	   lawname.compare("prandtl_reuss") == 0 ||
+	   lawname.compare("plane_strain_isotropic_perfect_plasticity") == 0 ||
+	   lawname.compare("plane_strain_prandtl_reuss") == 0) {
+	 nb_var = nb_params = 3;
        } else if
-         (lawname.compare("isotropic_plasticity_linear_hardening") == 0 ||
-          lawname.compare("prandtl_reuss_linear_hardening") == 0 ||
-          lawname.compare("plane_strain_isotropic_plasticity_linear_hardening") == 0 ||
-          lawname.compare("plane_strain_prandtl_reuss_linear_hardening") == 0) {
-         nb_var = 4; nb_params = 5;
+	   (lawname.compare("isotropic_plasticity_linear_hardening") == 0 ||
+	    lawname.compare("prandtl_reuss_linear_hardening") == 0 ||
+	    lawname.compare("plane_strain_isotropic_plasticity_linear_hardening") == 0 ||
+	    lawname.compare("plane_strain_prandtl_reuss_linear_hardening") == 0) {
+	 nb_var = 4; nb_params = 5;
        } else
-         THROW_BADARG(lawname << " is not an implemented elastoplastic law");
-
+	 THROW_BADARG(lawname << " is not an implemented elastoplastic law");
+       
        getfem::plasticity_unknowns_type unknowns_type(getfem::DISPLACEMENT_ONLY);
        mexarg_in argin = in.pop();
        if (argin.is_string()) {
-         std::string opt = argin.to_string();
-         filter_lawname(opt);
-         if (opt.compare("displacement_only") == 0)
-           unknowns_type = getfem::DISPLACEMENT_ONLY;
-         else if (opt.compare("displacement_and_plastic_multiplier") == 0)
-           unknowns_type = getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER;
-         else
-           THROW_BADARG("Wrong input");
+	 std::string opt = argin.to_string();
+	 filter_lawname(opt);
+	 if (opt.compare("displacement_only") == 0)
+	   unknowns_type = getfem::DISPLACEMENT_ONLY;
+	 else if (opt.compare("displacement_and_plastic_multiplier") == 0)
+	   unknowns_type = getfem::DISPLACEMENT_AND_PLASTIC_MULTIPLIER;
+	 else
+	   THROW_BADARG("Wrong input");
        } else if (argin.is_integer())
-         unknowns_type = static_cast<getfem::plasticity_unknowns_type>
-                         (argin.to_integer(0,1));
-
+	 unknowns_type = static_cast<getfem::plasticity_unknowns_type>
+	   (argin.to_integer(0,1));
+       
        std::vector<std::string> varnames;
        for (size_type i = 0; i < nb_var; ++i)
-         varnames.push_back(in.pop().to_string());
-
+	 varnames.push_back(in.pop().to_string());
+      
        std::vector<std::string> params;
        for (size_type i = 0; i < nb_params; ++i)
-         params.push_back(in.pop().to_string());
-
+	 params.push_back(in.pop().to_string());
+       
        std::string theta = "1";
        std::string dt = "timestep";
        size_type region = size_type(-1);
        for (size_type i=0; i < 3 && in.remaining(); ++i) {
-         argin = in.pop();
-         if (argin.is_string()) {
-           if (i==0)      theta = argin.to_string();
-           else if (i==1) dt = argin.to_string();
-           else           THROW_BADARG("Wrong input");
-         } else if (argin.is_integer()) {
-           region = argin.to_integer();
-           GMM_ASSERT1(!in.remaining(), "Wrong input");
-         }
+	 argin = in.pop();
+	 if (argin.is_string()) {
+	   if (i==0)      theta = argin.to_string();
+	   else if (i==1) dt = argin.to_string();
+	   else           THROW_BADARG("Wrong input");
+	 } else if (argin.is_integer()) {
+	   region = argin.to_integer();
+	   GMM_ASSERT1(!in.remaining(), "Wrong input");
+	 }
        }
        params.push_back(theta);
        params.push_back(dt);
-
+       
        getfem::model_real_plain_vector VMM(mf_vm->nb_dof());
        getfem::compute_small_strain_elastoplasticity_Von_Mises
-       (*md, *mim, lawname, unknowns_type, varnames, params, *mf_vm, VMM, region);
+       (*md, *mim, lawname, unknowns_type, varnames, params, *mf_vm, VMM,
+	region);
        out.pop().from_dcvector(VMM);
        );
-
+    
+    
     /*@GET V = ('compute elastoplasticity Von Mises or Tresca', @str datasigma, @tmf mf_vm[, @str version])
-      For the obsolete plasticity brick. Compute on `mf_vm` the Von-Mises or the Tresca stress of a field for plasticity and return it into the vector V.
+      Compute on `mf_vm` the Von-Mises or the Tresca stress of a field for plasticity and return it into the vector V.
       `datasigma` is a vector which contains the stress constraints values supported by the mesh.
       `version` should be  'Von_Mises' or 'Tresca' ('Von_Mises' is the default).@*/
     sub_command
@@ -1077,7 +1079,7 @@ void gf_model_get(getfemint::mexargs_in& m_in,
        );
 
     /*@GET V = ('compute plastic part', @tmim mim, @tmf mf_pl, @str varname, @str previous_dep_name, @str projname, @str datalambda, @str datamu, @str datathreshold, @str datasigma)
-      For the obsolete plasticity brick. Compute on `mf_pl` the plastic part and return it into the vector V.
+      Compute on `mf_pl` the plastic part and return it into the vector V.
       `datasigma` is a vector which contains the stress constraints values supported by the mesh.@*/
      sub_command
       ("compute plastic part", 9, 9, 0, 1,
@@ -1267,6 +1269,38 @@ void gf_model_get(getfemint::mexargs_in& m_in,
        = transformation_name_of_large_sliding_contact_brick(*md, ind);
        out.pop().from_string(name.c_str());
        );
+  /*@GET V = ('sliding data group name of Nitsche large sliding contact brick', @int indbrick)
+      Gives the name of the group of variables corresponding to the
+      sliding data for an existing large sliding contact brick.@*/
+      sub_command
+      ("sliding data group name of Nitsche large sliding contact brick", 1, 1, 0, 1,
+       size_type ind = in.pop().to_integer() - config::base_index();
+       std::string name
+       = sliding_data_group_name_of_Nitsche_large_sliding_contact_brick(*md, ind);
+       out.pop().from_string(name.c_str());
+       );
+
+     /*@GET V = ('displacement group name of Nitsche large sliding contact brick', @int indbrick)
+      Gives the name of the group of variables corresponding to the
+      sliding data for an existing large sliding contact brick.@*/
+      sub_command
+      ("displacement group name of Nitsche large sliding contact brick", 1, 1, 0, 1,
+       size_type ind = in.pop().to_integer() - config::base_index();
+       std::string name
+       = displacement_group_name_of_Nitsche_large_sliding_contact_brick(*md, ind);
+       out.pop().from_string(name.c_str());
+       );
+
+     /*@GET V = ('transformation name of Nitsche large sliding contact brick', @int indbrick)
+      Gives the name of the group of variables corresponding to the
+      sliding data for an existing large sliding contact brick.@*/
+      sub_command
+      ("transformation name of Nitsche large sliding contact brick", 1, 1, 0, 1,
+       size_type ind = in.pop().to_integer() - config::base_index();
+       std::string name
+       = transformation_name_of_Nitsche_large_sliding_contact_brick(*md, ind);
+       out.pop().from_string(name.c_str());
+       );
 
     /*@GET M = ('matrix term', @int ind_brick, @int ind_term)
       Gives the matrix term ind_term of the brick ind_brick if it exists
diff --git a/interface/src/gf_model_set.cc b/interface/src/gf_model_set.cc
index e023902..7e60db8 100644
--- a/interface/src/gf_model_set.cc
+++ b/interface/src/gf_model_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard.
+ Copyright (C) 2009-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
@@ -54,6 +54,8 @@ struct sub_gf_md_set : virtual public dal::static_stored_object {
 
 typedef std::shared_ptr<sub_gf_md_set> psub_command;
 
+typedef std::map<size_type, size_type> elt_corr_cont;
+
 // Function to avoid warning in macro with unused arguments.
 template <typename T> static inline void dummy_func(T &) {}
 
@@ -423,6 +425,46 @@ void gf_model_set(getfemint::mexargs_in& m_in,
                                                       *tm, expr);
        );
 
+    /*@SET ('add element extrapolation transformation', @str transname, @tmesh source_mesh, @mat elt_corr)
+      Add a special interpolation transformation which represents the identity
+      transformation but allows to evaluate the expression on another element
+      than the current element by polynomial extrapolation. It is used for
+      stabilization term in fictitious domain applications. the array elt_cor
+      should be a two entry array whose first line contains the elements
+      concerned by the transformation and the second line the respective
+      elements on which the extrapolation has to be made. If an element
+      is not listed in elt_cor the evaluation is just made on the current
+      element. @*/
+    sub_command
+      ("add element extrapolation transformation", 3, 3, 0, 0,
+       std::string transname = in.pop().to_string();
+       getfem::mesh *sm = extract_mesh_object(in.pop());
+       iarray v = in.pop().to_iarray();
+       if (v.getm() != 2 || v.getp() != 1 || v.getq() != 1)
+       	 THROW_BADARG("Invalid format for the convex correspondance list");
+       elt_corr_cont elt_corr;
+       for (size_type j=0; j < v.getn(); j++)
+	 elt_corr[v(0,j)-config::base_index()] = v(1,j)-config::base_index();
+       getfem::add_element_extrapolation_transformation(*md, transname, *sm,
+							elt_corr);
+       );
+
+      /*@SET ('set element extrapolation correspondance', @str transname, @mat elt_corr)
+      Change the correspondance map of an element extrapolation interpolate
+     transformation. @*/
+    sub_command
+      ("set element extrapolation correspondance", 2, 2, 0, 0,
+       std::string transname = in.pop().to_string();
+       iarray v = in.pop().to_iarray();
+       if (v.getm() != 2 || v.getp() != 1 || v.getq() != 1)
+       	 THROW_BADARG("Invalid format for the convex correspondance list");
+       elt_corr_cont elt_corr;
+       for (size_type j=0; j < v.getn(); j++)
+	 elt_corr[v(0,j)-config::base_index()] = v(1,j)-config::base_index();
+       getfem::set_element_extrapolation_correspondance(*md, transname,
+							elt_corr);
+       );
+    
     /*@SET ('add raytracing transformation', @str transname, @scalar release_distance)
       Add a raytracing interpolate transformation called `transname` to a model
       to be used by the generic assembly bricks.
@@ -476,7 +518,60 @@ void gf_model_set(getfemint::mexargs_in& m_in,
        add_rigid_obstacle_to_raytracing_transformation
        (*md, transname, expr, N);
        );
+/*@SET ('add projection transformation', @str transname, @scalar release_distance)
+      Add a projection interpolate transformation called `transname` to a model
+      to be used by the generic assembly bricks.
+      CAUTION: For the moment, the derivative of the
+      transformation is not taken into account in the model solve. @*/  
+      sub_command
+      ("add projection transformation", 2, 2, 0, 0,
+       std::string transname = in.pop().to_string();
+       scalar_type d = in.pop().to_scalar();
+       add_projection_transformation(*md, transname, d);
+       );
+
+    /*@SET ('add master contact boundary to projection transformation', @str transname, @tmesh m, @str dispname, @int region)
+      Add a master contact boundary with corresponding displacement variable
+      `dispname` on a specific boundary `region` to an existing projection
+      interpolate transformation called `transname`. @*/
+    sub_command
+      ("add master contact boundary to projection transformation", 4, 4, 0, 0,
+       std::string transname = in.pop().to_string();
+       getfem::mesh *sm = extract_mesh_object(in.pop());
+       std::string dispname = in.pop().to_string();
+       size_type region = in.pop().to_integer();
+       add_master_contact_boundary_to_projection_transformation
+       (*md, transname, *sm, dispname, region);
+       );
+
+    /*@SET ('add slave contact boundary to projection transformation', @str transname, @tmesh m, @str dispname, @int region)
+      Add a slave contact boundary with corresponding displacement variable
+      `dispname` on a specific boundary `region` to an existing projection
+      interpolate transformation called `transname`. @*/
+    sub_command
+      ("add slave contact boundary to projection transformation", 4, 4, 0, 0,
+       std::string transname = in.pop().to_string();
+       getfem::mesh *sm = extract_mesh_object(in.pop());
+       std::string dispname = in.pop().to_string();
+       size_type region = in.pop().to_integer();
+       add_slave_contact_boundary_to_projection_transformation
+       (*md, transname, *sm, dispname, region);
+       );
 
+    /*@SET ('add rigid obstacle to projection transformation', @str transname, @str expr, @int N)
+      Add a rigid obstacle whose geometry corresponds to the zero level-set
+      of the high-level generic assembly expression `expr`
+      to an existing projection interpolate transformation called `transname`.
+      @*/
+    sub_command
+      ("add rigid obstacle to projection transformation", 3, 3, 0, 0,
+       std::string transname = in.pop().to_string();
+       std::string expr = in.pop().to_string();
+       size_type N = in.pop().to_integer();
+       add_rigid_obstacle_to_projection_transformation
+       (*md, transname, expr, N);
+       );
+      
     /*@SET ind = ('add linear generic assembly brick', @tmim mim, @str expression[, @int region[, @int is_symmetric[, @int is_coercive]]])
       Adds a matrix term given by the assembly string `expr` which will
       be assembled in region `region` and with the integration method `mim`.
@@ -566,7 +661,44 @@ void gf_model_set(getfemint::mexargs_in& m_in,
        out.pop().from_integer(int(ind));
        );
 
-
+    /*@SET ('add assembly assignment', @str dataname, @str expression[, @int region[, @int order[, @int before]]]) 	 
+      Adds expression `expr` to be evaluated at assembly time and being	 
+      assigned to the data `dataname` which has to be of im_data type.
+      This allows for instance to store a sub-expression of an assembly
+      computation to be used on an other assembly. It can be used for instance
+      to store the plastic strain in plasticity models.
+      `order` represents the order of assembly where this assignement has to be
+      done (potential(0), weak form(1) or tangent system(2) or at each
+      order(-1)). The default value is 1.
+      If before = 1, the the assignement is perfromed before the computation
+      of the other assembly terms, such that the data can be used in the
+      remaining of the assembly as an intermediary result (be careful that it is
+      still considered as a data, no derivation of the expression is performed
+      for the tangent system). 	 
+      If before = 0 (default), the assignement is done after the assembly terms.
+      @*/ 	 
+    sub_command 	 
+      ("add assembly assignment", 2, 5, 0, 0, 	 
+       std::string dataname = in.pop().to_string(); 	 
+       std::string expr = in.pop().to_string(); 	 
+       size_type region = size_type(-1); 	 
+       if (in.remaining()) region = in.pop().to_integer(); 	 
+       size_type order = 1; 	 
+       if (in.remaining()) order = in.pop().to_integer(); 	 
+       bool before = false; 	 
+       if (in.remaining()) before = (in.pop().to_integer() != 0); 	 
+       
+       md->add_assembly_assignments(dataname, expr, region, order, before);
+       ); 	 
+    
+    /*@SET ('clear assembly assignment') 	 
+      Delete all added assembly assignments 	 
+      @*/ 	 
+    sub_command 	 
+      ("clear assembly assignment", 0, 0, 0, 0, 	 
+       md->clear_assembly_assignments(); 	 
+       );
+    
     /*@SET ind = ('add Laplacian brick', @tmim mim, @str varname[, @int region])
     Add a Laplacian term to the model relatively to the variable `varname`
     (in fact with a minus : :math:`-\text{div}(\nabla u)`).
@@ -1956,9 +2088,10 @@ void gf_model_set(getfemint::mexargs_in& m_in,
       This law supports to possibilities of unknown variables to solve for
       defined by means of `unknowns_type` set to either
       'DISPLACEMENT_AND_PLASTIC_MULTIPLIER' (integer value 1) or
-      'DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE' (integer value 3)
+      'DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE' (integer value 3).
       The  "Simo_Miehe" law expects as `varnames` a set of the
       following names that have to be defined as variables in the model:
+
       - the displacement variable which has to be defined as an unknown,
       - the plastic multiplier which has also defined as an unknown,
       - optionally the pressure variable for a mixed displacement-pressure
@@ -1971,15 +2104,18 @@ void gf_model_set(getfemint::mexargs_in& m_in,
         Cauchy-Green tensor at the previous time step
         (it has to be a 4 element vector for plane strain 2D problems
         and a 6 element vector for 3D problems).
+
       The  "Simo_Miehe" law also expects as `params` a set of the
       following three parameters:
+
       - an expression for the initial bulk modulus K,
       - an expression for the initial shear modulus G,
       - the name of a user predefined function that decribes
         the yield limit as a function of the hardening variable
         (both the yield limit and the hardening variable values are
-         assumed to be Frobenius norms of appropriate stress and strain
-         tensors, respectively),
+        assumed to be Frobenius norms of appropriate stress and strain
+        tensors, respectively).
+
       As usual, `region` is an optional mesh region on which the term is added.
       If it is not specified, it is added on the whole mesh.
       Return the brick index in the model.@*/
@@ -2959,7 +3095,6 @@ void gf_model_set(getfemint::mexargs_in& m_in,
       corresponding to partial differential terms having a Neumann term.
       Moreover, This brick can only be applied to bricks declaring their
       Neumann terms. Returns the brick index in the model.
-      Deprecated brick.
     @*/
     sub_command
       ("add Nitsche contact with rigid obstacle brick", 6, 10, 0, 1,
@@ -3049,7 +3184,7 @@ void gf_model_set(getfemint::mexargs_in& m_in,
 
 #endif
 
-
+#if (0) // Deprecated brick : uses the old Neumann terms
 
     /*@SET ind = ('add Nitsche fictitious domain contact brick', @tmim mim, @str varname1, @str varname2, @str dataname_d1, @str dataname_d2, @str gamma0name [, @scalar theta[, @str dataname_friction_coeff[, @str dataname_alpha, @str dataname_wt1, at str dataname_wt2]]])
      Adds a contact condition with or without Coulomb friction between
@@ -3108,6 +3243,7 @@ void gf_model_set(getfemint::mexargs_in& m_in,
        out.pop().from_integer(int(ind));
        );
 
+#endif
 
     // CONTACT BETWEEN NON-MATCHING MESHES
 
@@ -3168,6 +3304,7 @@ void gf_model_set(getfemint::mexargs_in& m_in,
           mim2 = to_meshim_object(argin);
           varname_u1 = in.pop().to_string();
           varname_u2 = in.pop().to_string();
+	  cout << "ok here" << endl;
         }
         std::string multname_n = in.pop().to_string();
         std::string multname_t;
@@ -3462,6 +3599,117 @@ void gf_model_set(getfemint::mexargs_in& m_in,
        (*md, ind, *mim, region, true, true,
         dispname, lambda, wname);
        );
+
+       /*@SET ind = ('add Nitsche large sliding contact brick raytracing', @bool unbiased_version, @str dataname_r, @scalar release_distance[, @str dataname_fr[, @str dataname_alpha[, @int version]]])
+      Adds a large sliding contact with friction brick to the model based on the Nitsche's method.
+      This brick is able to deal with self-contact, contact between
+      several deformable bodies and contact with rigid obstacles.
+      It uses the high-level generic assembly. It adds to the model
+      a raytracing_interpolate_transformation object. "unbiased_version" refers to the version of Nische's method to be used.
+      (unbiased or biased one).
+      For each slave boundary a  material law should be defined as a function of the dispacement variable on this boundary.
+      The release distance should be determined with care
+      (generally a few times a mean element size, and less than the
+      thickness of the body). Initially, the brick is added with no contact
+      boundaries. The contact boundaries and rigid bodies are added with
+      special functions. `version` is 0 (the default value) for the
+      non-symmetric version and 1 for the more symmetric one
+      (not fully symmetric even without friction). @*/
+
+     sub_command
+       ("add Nitsche large sliding contact brick raytracing", 2, 6, 0, 1,
+        
+        bool unbiased=(in.pop().to_integer() != 0);
+        std::string dataname_r = in.pop().to_string();
+        scalar_type d = in.pop().to_scalar();
+        std::string dataname_fr = "0";
+        if (in.remaining()) dataname_fr = in.pop().to_string();
+        if (dataname_fr.size() == 0) dataname_fr = "0";
+        std::string dataname_alpha = "1";
+        if (in.remaining()) dataname_alpha = in.pop().to_string();
+        if (dataname_alpha.size() == 0) dataname_alpha = "1";
+        bool sym_v = false;
+        if (in.remaining()) sym_v = (in.pop().to_integer() != 0);
+        bool frame_indifferent = false;
+        if (in.remaining()) frame_indifferent = (in.pop().to_integer() != 0);
+
+        size_type  ind
+        = getfem::add_Nitsche_large_sliding_contact_brick_raytracing
+        (*md, unbiased, dataname_r, d, dataname_fr, dataname_alpha, sym_v,
+         frame_indifferent);
+        out.pop().from_integer(int(ind + config::base_index()));
+        );
+
+     /*@SET ('add rigid obstacle to Nitsche large sliding contact brick', @int indbrick, @str expr, @int N)
+      Adds a rigid obstacle to an existing large sliding contact
+      with friction brick. `expr` is an expression using the high-level
+      generic assembly language (where `x` is the current point n the mesh)
+      which should be a signed distance to the obstacle.
+      `N` is the mesh dimension. @*/
+    sub_command
+      ("add rigid obstacle to Nitsche large sliding contact brick", 3, 3, 0, 0,
+       size_type ind = in.pop().to_integer() - config::base_index();
+       std::string expr = in.pop().to_string();
+       size_type N = in.pop().to_integer();
+
+       add_rigid_obstacle_to_Nitsche_large_sliding_contact_brick
+       (*md, ind, expr, N);
+       );
+
+     /*@SET ('add master contact boundary to biased Nitsche large sliding contact brick', @int indbrick, @tmim mim, @int region, @str dispname[, @str wname])
+      Adds a master contact boundary to an existing biased Nitsche's large sliding contact
+      with friction brick. @*/
+    sub_command
+      ("add master contact boundary to biased Nitsche large sliding contact brick", 4, 5, 0,0,
+       size_type ind = in.pop().to_integer() - config::base_index();
+       getfem::mesh_im *mim = to_meshim_object(in.pop());
+       size_type region = in.pop().to_integer();
+       std::string dispname = in.pop().to_string();
+       std::string wname;
+       if (in.remaining()) wname = in.pop().to_string();
+
+       add_contact_boundary_to_Nitsche_large_sliding_contact_brick
+       (*md, ind, *mim, region, true, false, false,
+        dispname, "", wname);
+       );
+
+
+    /*@SET ('add slave contact boundary to biased Nitsche large sliding contact brick', @int indbrick, @tmim mim, @int region, @str dispname, @str lambdaname[, @str wname])
+      Adds a slave contact boundary to an existing biased Nitsche's large sliding contact
+      with friction brick. @*/
+    sub_command
+      ("add slave contact boundary to biased Nitsche large sliding contact brick", 5, 6, 0,0,
+       size_type ind = in.pop().to_integer() - config::base_index();
+       getfem::mesh_im *mim = to_meshim_object(in.pop());
+       size_type region = in.pop().to_integer();
+       std::string dispname = in.pop().to_string();
+       std::string sigma = in.pop().to_string();
+       std::string wname;
+       if (in.remaining()) wname = in.pop().to_string();
+
+       add_contact_boundary_to_Nitsche_large_sliding_contact_brick
+       (*md, ind, *mim, region, false, true, false,
+        dispname, sigma, wname);
+       );
+
+    /*@SET ('add contact boundary to unbiased Nitsche large sliding contact brick', @int indbrick, @tmim mim, @int region, @str dispname, @str lambdaname[, @str wname])
+      Adds a contact boundary to an existing unbiased Nitschelarge sliding contact
+      with friction brick which is both master and slave. @*/
+    sub_command
+      ("add contact boundary to unbiased Nitsche large sliding contact brick",
+       5, 6, 0, 0,
+       size_type ind = in.pop().to_integer() - config::base_index();
+       getfem::mesh_im *mim = to_meshim_object(in.pop());
+       size_type region = in.pop().to_integer();
+       std::string dispname = in.pop().to_string();
+       std::string sigma = in.pop().to_string();
+       std::string wname;
+       if (in.remaining()) wname = in.pop().to_string();
+
+       add_contact_boundary_to_Nitsche_large_sliding_contact_brick
+       (*md, ind, *mim, region, true, true, true,
+        dispname, sigma, wname);
+       );
   }
 
   if (m_in.narg() < 2)  THROW_BADARG( "Wrong number of input arguments");
diff --git a/interface/src/gf_precond.cc b/interface/src/gf_precond.cc
index 5d45b4e..bff386c 100644
--- a/interface/src/gf_precond.cc
+++ b/interface/src/gf_precond.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_precond_get.cc b/interface/src/gf_precond_get.cc
index 5c92306..beeeb2c 100644
--- a/interface/src/gf_precond_get.cc
+++ b/interface/src/gf_precond_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_slice.cc b/interface/src/gf_slice.cc
index be7d604..53a1e65 100644
--- a/interface/src/gf_slice.cc
+++ b/interface/src/gf_slice.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_slice.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 
 #include <memory>
 #include <getfem/getfem_mesh_level_set.h>
diff --git a/interface/src/gf_slice_get.cc b/interface/src/gf_slice_get.cc
index d05a629..4811e8e 100644
--- a/interface/src/gf_slice_get.cc
+++ b/interface/src/gf_slice_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -18,7 +18,7 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-// $Id: gf_slice_get.cc 5353 2016-07-26 13:36:19Z renard $
+// $Id$
 #include <map>
 #include <getfemint_workspace.h>
 #include <getfem/getfem_mesh_slice.h>
diff --git a/interface/src/gf_slice_set.cc b/interface/src/gf_slice_set.cc
index a74e654..34cd76b 100644
--- a/interface/src/gf_slice_set.cc
+++ b/interface/src/gf_slice_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_spmat.cc b/interface/src/gf_spmat.cc
index 1f58b36..b64461c 100644
--- a/interface/src/gf_spmat.cc
+++ b/interface/src/gf_spmat.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Julien Pommier.
+ Copyright (C) 2006-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_spmat_get.cc b/interface/src/gf_spmat_get.cc
index db07ae6..0815c32 100644
--- a/interface/src/gf_spmat_get.cc
+++ b/interface/src/gf_spmat_get.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Julien Pommier.
+ Copyright (C) 2006-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_spmat_set.cc b/interface/src/gf_spmat_set.cc
index b9301f2..54451eb 100644
--- a/interface/src/gf_spmat_set.cc
+++ b/interface/src/gf_spmat_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Julien Pommier.
+ Copyright (C) 2006-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -71,7 +71,8 @@ spmat_set_or_add_sub_matrix(gsparse &gsp, getfemint::mexargs_in& in,
 	break;
       case gsparse::CSCMAT:
 	if (do_add) gmm::add (src->csc(T()), gmm::sub_matrix(gsp.wsc(T()), ii, jj));
-	else        gmm::copy(src->csc(T()), gmm::sub_matrix(gsp.wsc(T()), ii, jj)); break;
+	else        gmm::copy(src->csc(T()), gmm::sub_matrix(gsp.wsc(T()), ii, jj));
+	break;
       default: THROW_INTERNAL_ERROR;
     }
   } else {
diff --git a/interface/src/gf_util.cc b/interface/src/gf_util.cc
index b94c0db..95c901d 100644
--- a/interface/src/gf_util.cc
+++ b/interface/src/gf_util.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gf_workspace.cc b/interface/src/gf_workspace.cc
index a3108ab..a68b5ff 100644
--- a/interface/src/gf_workspace.cc
+++ b/interface/src/gf_workspace.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gfi_array.c b/interface/src/gfi_array.c
index 9385c71..9e5d2fc 100644
--- a/interface/src/gfi_array.c
+++ b/interface/src/gfi_array.c
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gfi_array.h b/interface/src/gfi_array.h
index 3a2ac18..e12c6b2 100644
--- a/interface/src/gfi_array.h
+++ b/interface/src/gfi_array.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gfi_rpc.h b/interface/src/gfi_rpc.h
index 161071e..c414a2b 100644
--- a/interface/src/gfi_rpc.h
+++ b/interface/src/gfi_rpc.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gfi_rpc_clnt.c b/interface/src/gfi_rpc_clnt.c
index e1f63b4..8bb62c6 100644
--- a/interface/src/gfi_rpc_clnt.c
+++ b/interface/src/gfi_rpc_clnt.c
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gfi_rpc_server.c b/interface/src/gfi_rpc_server.c
index 9df4440..7a7302a 100644
--- a/interface/src/gfi_rpc_server.c
+++ b/interface/src/gfi_rpc_server.c
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gfi_rpc_svc.c b/interface/src/gfi_rpc_svc.c
index a9ee5dd..45ebcf4 100644
--- a/interface/src/gfi_rpc_svc.c
+++ b/interface/src/gfi_rpc_svc.c
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/gfi_rpc_xdr.c b/interface/src/gfi_rpc_xdr.c
index 3d45a95..ea1d556 100644
--- a/interface/src/gfi_rpc_xdr.c
+++ b/interface/src/gfi_rpc_xdr.c
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/interface/src/matlab/Makefile.am b/interface/src/matlab/Makefile.am
index 7096592..99771cd 100644
--- a/interface/src/matlab/Makefile.am
+++ b/interface/src/matlab/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 SUBDIRS = private
 
 RPC_INC_DIR=@RPC_INC_DIR@
@@ -30,12 +47,16 @@ if USE_MINGW_MEX
 
 #command extremely sensitive to any modification! fragile! keep the order of the files
 # (gfm_mex.c must be first, libstdc++.a must be last)
-#virer le -DMATLAB_RELEASE qui marche pas..
-#-DMATLAB_RELEASE=@MATLAB_RELEASE@ \ the great windows mex does not understand -D ...
+
 gf_matlab at MATLAB_COM_EXT@: gfm_mex.c gfm_common.c ../libgetfemint.la ../gfi_array.c $(GETFEM_LIB_LA)
-	$(GNUMEX) $(GNUMEXOPTS) -output gf_matlab -g @srcdir@/gfm_mex.c \
-	@srcdir@/gfm_common.c -I at srcdir@ \
-	@srcdir@/../gfi_array.c ../.libs/libgetfemint.a $(GETFEM_STATIC_LIB) @STDCPP_STATICLIBS@
+	matlab -nodesktop -nosplash -nojvm -r "mex -v -output gf_matlab -g ./gfm_mex.c ./gfm_common.c -largeArrayDims -I. -I.. ./../gfi_array.c ../.libs/libgetfemint.a ../../../src/.libs/libgetfem.a ../../../superlu/.libs/libsuperlu.a /msys/local/lib/libsmumps.a /msys/local/lib/libcmumps.a /msys/local/lib/libdmumps.a /msys/local/lib/libzmumps.a /msys/local/lib/libmumps_common.a /msys/local/lib/libmpiseq.a /msys/local/lib/libpord.a /msys/local/lib/liblapack.a /msys/local/lib/libblas.a /msys/loca [...]
+
+
+#	$(GNUMEX) $(GNUMEXOPTS) -output gf_matlab -g @srcdir@/gfm_mex.c \
+#	@srcdir@/gfm_common.c -I at srcdir@ \
+#	@srcdir@/../gfi_array.c ../.libs/libgetfemint.a $(GETFEM_STATIC_LIB) @STDCPP_STATICLIBS@
+
+
 #        /c/MinGW/lib/libstdc++.a
 #	cmd /c "$mexbat -v -f c:/gnumex/mexopts.bat gfm_mex.c -output gfm_rpc_mexint gfi*.o gf_*.o matlabint*.o c:\\msys\\1.0\\home\\j\\getfem++-1.5\\src\\.libs\\libgetfem.a getfem_matlab.o c:\\mingw\\lib\\libstdc++.a -Ic:\\msys\\1.0\\home\\j\\mingw_liboncrpc-4.0"
 else !USE_MINGW_MEX
diff --git a/interface/src/matlab/Makefile.in b/interface/src/matlab/Makefile.in
index e5739df..6f814bc 100644
--- a/interface/src/matlab/Makefile.in
+++ b/interface/src/matlab/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -88,6 +95,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = interface/src/matlab
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -103,7 +112,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -163,7 +171,6 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -256,7 +263,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -289,8 +295,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -371,7 +379,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -416,6 +423,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/src/matlab/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/src/matlab/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -709,8 +717,6 @@ uninstall-am:
 	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
 	uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # $(warning PSEUDO_FUNCTIONS= $(PSEUDO_FUNCTIONS))
 
@@ -721,12 +727,14 @@ all: gf_mesh.m gf_matlab at MATLAB_COM_EXT@
 
 #command extremely sensitive to any modification! fragile! keep the order of the files
 # (gfm_mex.c must be first, libstdc++.a must be last)
-#virer le -DMATLAB_RELEASE qui marche pas..
-#-DMATLAB_RELEASE=@MATLAB_RELEASE@ \ the great windows mex does not understand -D ...
+
 @BUILDMEX_TRUE@@USE_MINGW_MEX_TRUE at gf_matlab@MATLAB_COM_EXT@: gfm_mex.c gfm_common.c ../libgetfemint.la ../gfi_array.c $(GETFEM_LIB_LA)
- at BUILDMEX_TRUE@@USE_MINGW_MEX_TRUE@	$(GNUMEX) $(GNUMEXOPTS) -output gf_matlab -g @srcdir@/gfm_mex.c \
- at BUILDMEX_TRUE@@USE_MINGW_MEX_TRUE@	@srcdir@/gfm_common.c -I at srcdir@ \
- at BUILDMEX_TRUE@@USE_MINGW_MEX_TRUE@	@srcdir@/../gfi_array.c ../.libs/libgetfemint.a $(GETFEM_STATIC_LIB) @STDCPP_STATICLIBS@
+ at BUILDMEX_TRUE@@USE_MINGW_MEX_TRUE@	matlab -nodesktop -nosplash -nojvm -r "mex -v -output gf_matlab -g ./gfm_mex.c ./gfm_common.c -largeArrayDims -I. -I.. ./../gfi_array.c ../.libs/libgetfemint.a ../../../src/.libs/libgetfem.a ../../../superlu/.libs/libsuperlu.a /msys/local/lib/libsmumps.a /msys/local/lib/libcmumps.a /msys/local/lib/libdmumps.a /msys/local/lib/libzmumps.a /msys/local/lib/libmumps_common.a /msys/local/lib/libmpiseq.a /msys/local/lib/libpord.a /msys/local/lib/liblapack.a / [...]
+
+#	$(GNUMEX) $(GNUMEXOPTS) -output gf_matlab -g @srcdir@/gfm_mex.c \
+#	@srcdir@/gfm_common.c -I at srcdir@ \
+#	@srcdir@/../gfi_array.c ../.libs/libgetfemint.a $(GETFEM_STATIC_LIB) @STDCPP_STATICLIBS@
+
 #        /c/MinGW/lib/libstdc++.a
 #	cmd /c "$mexbat -v -f c:/gnumex/mexopts.bat gfm_mex.c -output gfm_rpc_mexint gfi*.o gf_*.o matlabint*.o c:\\msys\\1.0\\home\\j\\getfem++-1.5\\src\\.libs\\libgetfem.a getfem_matlab.o c:\\mingw\\lib\\libstdc++.a -Ic:\\msys\\1.0\\home\\j\\mingw_liboncrpc-4.0"
 @BUILDMEXRPC_TRUE@@BUILDMEX_TRUE@@USE_MINGW_MEX_FALSE at gf_matlab@MATLAB_COM_EXT@: ../gfi_rpc_clnt.c gfm_rpc_mexint.c gfm_common.c ../gfi_rpc_xdr.c ../gfi_array.c
diff --git a/interface/src/matlab/gfObject.m b/interface/src/matlab/gfObject.m
index 064fae2..c18453d 100644
--- a/interface/src/matlab/gfObject.m
+++ b/interface/src/matlab/gfObject.m
@@ -1,5 +1,21 @@
 function b=gfObject(a)
 % converts a getfem struct to an object such as gfMesh, gfFem etc..    
+%  Copyright (C) 1999-2017 Yves Renard
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
   if (isempty(a))
     b=[];
   elseif (isobject(a))
@@ -8,4 +24,4 @@ function b=gfObject(a)
     sclass = gf_workspace('class name',a(1));
     b=feval(sclass,a);
   else error('neither an object nor a struct');
-  end;
\ No newline at end of file
+  end;
diff --git a/interface/src/matlab/gf_asm_pdetoolbc.m b/interface/src/matlab/gf_asm_pdetoolbc.m
index d894838..66bd81a 100644
--- a/interface/src/matlab/gf_asm_pdetoolbc.m
+++ b/interface/src/matlab/gf_asm_pdetoolbc.m
@@ -2,7 +2,23 @@ function [Q,G,H,R,F]=gf_asm_pdetoolbc(mf_u, mf_d, b, e, f_expr)
 %  FUNCTION [Q,G,H,R,F]=gf_asm_pdetoolbc(mf_u, mf_d, b, e, f_expr)
 %  'pdetool style' assembling of boundary conditions
 %  See gf_asm
-% $Id: gf_asm_pdetoolbc.m 1520 2004-03-22 13:15:24Z pommier $  
+%  Copyright (C) 1999-2017 Yves Renard
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+% $Id$  
   if (nargin < 4), error('not enough input arguments'); end;
   nb_boundaries = size(b,2);
   xyeval = gf_mesh_fem_get(mf_d, 'dof nodes');
diff --git a/interface/src/matlab/gf_colormap.m b/interface/src/matlab/gf_colormap.m
index 692d904..68019d7 100644
--- a/interface/src/matlab/gf_colormap.m
+++ b/interface/src/matlab/gf_colormap.m
@@ -3,6 +3,22 @@ function varargout=gf_colormap(name),
 %   return a colormap, or change the current colormap.
 %   name can be: 'tripod', 'chouette', 'froid', 'tank'
 %   or 'earth'.
+%  Copyright (C) 1999-2017 Yves Renard
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
   if (strcmp(name,'tripod')),
     r=[0.7 .7 .7]; 
     l = r(end,:); 
@@ -109,4 +125,4 @@ function varargout=gf_colormap(name),
      164   0   0]; %	Scarlet Red 3
 %     238 238 236]; %	Untitled
 
-  c=c/255;
\ No newline at end of file
+  c=c/255;
diff --git a/interface/src/matlab/gf_compute_Q1grid_interp.m b/interface/src/matlab/gf_compute_Q1grid_interp.m
index 0395930..01d736b 100644
--- a/interface/src/matlab/gf_compute_Q1grid_interp.m
+++ b/interface/src/matlab/gf_compute_Q1grid_interp.m
@@ -1,6 +1,22 @@
 function [U2,Iq,MF2]=gf_compute_Q1grid_interp(MF1,U1,varargin)
 % See help on gf_compute
-%  $Id: gf_compute_Q1grid_interp.m 1937 2005-03-08 16:50:13Z pommier $
+%  $Id$
+%  Copyright (C) 1999-2017 Yves Renard
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
   if (nargin < 3), error('not enough input arguments'); end;
     
   gf_workspace('push', 'gf_compute_Q1grid_interp');
@@ -63,4 +79,4 @@ function [U2,Iq,MF2]=gf_compute_Q1grid_interp(MF1,U1,varargin)
     error(lasterr);
   end
   gf_workspace('pop');
-  
\ No newline at end of file
+  
diff --git a/interface/src/matlab/gf_mesh_fem_get_eval.m b/interface/src/matlab/gf_mesh_fem_get_eval.m
index 0096a42..8fae17f 100644
--- a/interface/src/matlab/gf_mesh_fem_get_eval.m
+++ b/interface/src/matlab/gf_mesh_fem_get_eval.m
@@ -1,5 +1,21 @@
 function X=gf_mesh_fem_get_eval(mf, what, dof)
 % gf_mesh_fem_get_eval : see the help in gf_mesh_fem_get(mf,'eval')
+%  Copyright (C) 1999-2017 Yves Renard
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
   
   if (nargin < 2) error('not enough input arguments'); end;
   qdim=gf_mesh_fem_get(mf, 'qdim');
diff --git a/interface/src/matlab/gf_plot.m b/interface/src/matlab/gf_plot.m
index 7759c50..5128a0b 100644
--- a/interface/src/matlab/gf_plot.m
+++ b/interface/src/matlab/gf_plot.m
@@ -30,6 +30,22 @@ function [hsurf, hcontour, hquiver, hmesh, hdefmesh]=gf_plot(mf,U,varargin)
 %  'disp_options', {'off'|'on'} : shows the option or not.
 %
 %
+%  Copyright (C) 1999-2017 Yves Renard
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
   try 
     gf_workspace('push');
diff --git a/interface/src/matlab/gf_plot_1D.m b/interface/src/matlab/gf_plot_1D.m
index 5dac517..2cbd142 100644
--- a/interface/src/matlab/gf_plot_1D.m
+++ b/interface/src/matlab/gf_plot_1D.m
@@ -8,6 +8,22 @@ function [hline, hdof] = gf_plot_1D(mf,U, varargin)
 %  'color', []          : override the line color.
 %  'dof_color', [1,0,0] : color of the markers for the degrees of freedom.
 %  'width', 2           : line width.
+%  Copyright (C) 1999-2017 Yves Renard
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
   try 
     gf_workspace('push', 'gf_plot_1D');
diff --git a/interface/src/matlab/gf_plot_mesh.m b/interface/src/matlab/gf_plot_mesh.m
index a159da6..a37e6c2 100644
--- a/interface/src/matlab/gf_plot_mesh.m
+++ b/interface/src/matlab/gf_plot_mesh.m
@@ -26,9 +26,24 @@ function [hmesh,hbound,hfill,hvert,hconv,hdof]=gf_plot_mesh(M, varargin)
 %     For 'dof', M should be a mesh_fem identifier, 
 %   not a simple mesh object.
 %  
-%   $Id: gf_plot_mesh.m 2282 2006-02-23 16:24:13Z pommier $
+%   $Id$
+%  Copyright (C) 1999-2017 A. Huard, Y. Renard, J. Pommier
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
-%   A. Huard, Y. Renard, J. Pommier
 if nargin<1,
   error('Too few input arguments')
 end
@@ -270,4 +285,4 @@ set(cfig,'NextPlot',fig_nextplot)
 
  
 function r=ison(v)
-  r = strcmpi(v,'on');
\ No newline at end of file
+  r = strcmpi(v,'on');
diff --git a/interface/src/matlab/gf_plot_slice.m b/interface/src/matlab/gf_plot_slice.m
index f44c409..9ea5820 100644
--- a/interface/src/matlab/gf_plot_slice.m
+++ b/interface/src/matlab/gf_plot_slice.m
@@ -30,7 +30,23 @@ function [hfaces, htube, hquiver, hmesh]=gf_plot_slice(sl,varargin)
 % the 'data' and 'convex_data' are mutually exclusive.
 %  
 % RETURNS: handles to the various graphical objects created.  
-%%%%%%%%%%%%
+%  Copyright (C) 1999-2017 Yves Renard
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
   if nargin<1,
     error('Too few input arguments')
   end
@@ -314,4 +330,4 @@ function r=ison(v)
   r = strcmpi(v,'on');
   
 function r=isauto(v)
-  r = strcmpi(v,'auto');
\ No newline at end of file
+  r = strcmpi(v,'auto');
diff --git a/interface/src/matlab/gfm_common.c b/interface/src/matlab/gfm_common.c
index c807656..277dcb7 100644
--- a/interface/src/matlab/gfm_common.c
+++ b/interface/src/matlab/gfm_common.c
@@ -48,11 +48,9 @@ mxClassID2string(mxClassID id) {
 #endif
     case mxOPAQUE_CLASS: return "OPAQUE_CLASS";
     default:
-#if MATLAB_RELEASE >= 14
       if (id != (mxClassID)(-1))
 	return "OBJECT";
-      else 
-#endif
+      else
 	return "unknown class...did you use the correct mex version ?";
   }
 }
@@ -176,9 +174,7 @@ mxarray_to_gfi_array(const mxArray *mx, gfi_array *t)
     } break;
     case mxOBJECT_CLASS:
     case mxSTRUCT_CLASS: 
-#if MATLAB_RELEASE >= 14
     default: 
-#endif
       {
       mxArray *fid = mxGetField(mx, 0, "id");
       mxArray *fcid = mxGetField(mx, 0, "cid");
@@ -201,12 +197,6 @@ mxarray_to_gfi_array(const mxArray *mx, gfi_array *t)
         mexPrintf("matlab structures (except getfem object ids) not handled"); return 1; 
       }
     } break;
-#if MATLAB_RELEASE < 14
-    default: {
-      mexPrintf("unhandled class type : %s\n", mxClassID2string(mxGetClassID(mx)));
-      return 1;
-    } break;
-#endif
   }
   {
     mwSize *pm;
diff --git a/interface/src/matlab/private/Makefile.am b/interface/src/matlab/private/Makefile.am
index 74dd04a..b66c0e4 100644
--- a/interface/src/matlab/private/Makefile.am
+++ b/interface/src/matlab/private/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 EXTRA_DIST=./getopt.m
 toolboxdir=@TOOLBOXDIR@/private
 toolbox_SCRIPTS=./getopt.m
diff --git a/interface/src/matlab/private/Makefile.in b/interface/src/matlab/private/Makefile.in
index 6ac3af2..8a8a14c 100644
--- a/interface/src/matlab/private/Makefile.in
+++ b/interface/src/matlab/private/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,18 +14,25 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,6 +96,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = interface/src/matlab/private
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -104,7 +113,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -158,7 +166,6 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -226,7 +233,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -259,8 +265,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -341,7 +349,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -368,6 +375,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/src/matlab/private/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/src/matlab/private/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -581,8 +589,6 @@ uninstall-am: uninstall-toolboxSCRIPTS
 	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
 	uninstall-am uninstall-toolboxSCRIPTS
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/interface/src/matlab/private/getopt.m b/interface/src/matlab/private/getopt.m
index 868a5d8..b3ed891 100644
--- a/interface/src/matlab/private/getopt.m
+++ b/interface/src/matlab/private/getopt.m
@@ -1,3 +1,20 @@
+%  Copyright (C) 1999-2017 Yves Renard
+%
+%  This file is a part of GetFEM++
+%
+%  GetFEM++  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 along with the GCC Runtime Library
+%  Exception either version 3.1 or (at your option) any later version.
+%  This program  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 and GCC Runtime Library Exception for more details.
+%  You  should  have received a copy of the GNU Lesser General Public License
+%  along  with  this program;  if not, write to the Free Software Foundation,
+%  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 function o=getopt(opt,v)
   o = opt;
   if (nargin==1) return; end;
diff --git a/interface/src/python/Makefile.am b/interface/src/python/Makefile.am
index 557a3d8..9e18ef1 100644
--- a/interface/src/python/Makefile.am
+++ b/interface/src/python/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 GETFEM_LIB_LA = ../../../src/libgetfem.la
 
 AM_CPPFLAGS = $(PYTHON_CPPFLAGS) -I at srcdir@ -I at srcdir@/..
@@ -38,15 +55,10 @@ getfem_python_c.c : getfem_python.c
 # ARCHFLAGS is set to empty to disable universal binaries with python 2.5 on macos 10.5
 _getfem.so: getfem_python_c.c ../libgetfemint.la $(GETFEM_LIB_LA)
 	touch _getfem.so && rm _getfem.so
-	ARCHFLAGS="" python setup.py -v build --build-temp . --build-base . --build-lib . --force
+	ARCHFLAGS="" CC="$(CC)" CFLAGS="$(CFLAGS)" $(PYTHON) setup.py -v build @PYTHON_CC_ARG@ --build-temp . --build-base . --build-lib . --force
 #LDSHARED="$(CXX) -shared" ARCHFLAGS="" python setup.py -v build --build-temp . --build-base . --build-lib . --force
 
 
-# getfem_python_reference.html: getfem.py _getfem.so
-#	cp getfem.py getfem_python_reference.py
-#	(export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):../../../src/.libs && pydoc -w getfem_python_reference) &&  if test -d $(top_srcdir)/interface/doc; then cp getfem_python_reference.html $(top_srcdir)/interface/doc/getfem_python_reference.html; fi;
-#	rm -f getfem_python_reference.py
-
 all: _getfem.so getfem.py
 #pyexec_LTLIBRARIES = libgfpython.la
 #libgfpython_la_LIBADD = ../.libs/libgetfemint.a @GETFEM_STATICLIBS@
diff --git a/interface/src/python/Makefile.in b/interface/src/python/Makefile.in
index 5424e2b..ba5c2cd 100644
--- a/interface/src/python/Makefile.in
+++ b/interface/src/python/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -88,6 +95,9 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = interface/src/python
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(srcdir)/setup.py.in \
+	$(gfpython_PYTHON) $(top_srcdir)/py-compile
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -103,8 +113,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(gfpython_PYTHON) \
-	$(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES = setup.py
@@ -162,8 +170,6 @@ am__pep3147_tweak = \
   sed -e 's|\.py$$||' -e 's|[^/]*$$|__pycache__/&.*.py|'
 py_compile = $(top_srcdir)/py-compile
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/setup.py.in \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/py-compile
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -231,7 +237,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -264,8 +269,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -346,7 +353,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -383,6 +389,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/src/python/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/src/python/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -662,8 +669,6 @@ uninstall-am: uninstall-gfpythonPYTHON uninstall-nodist_gfpyexecPYTHON
 	uninstall-am uninstall-gfpythonPYTHON \
 	uninstall-nodist_gfpyexecPYTHON
 
-.PRECIOUS: Makefile
-
 
 @BUILDPYTHON_TRUE at getfem.py: ../libgetfemint.la $(top_srcdir)/bin/extract_doc
 @BUILDPYTHON_TRUE@	$(top_srcdir)/bin/extract_doc $(srcdir)/.. $(pythoncom) > getfem.py || ( rm getfem.py ; /bin/false )
@@ -674,14 +679,9 @@ uninstall-am: uninstall-gfpythonPYTHON uninstall-nodist_gfpyexecPYTHON
 # ARCHFLAGS is set to empty to disable universal binaries with python 2.5 on macos 10.5
 @BUILDPYTHON_TRUE at _getfem.so: getfem_python_c.c ../libgetfemint.la $(GETFEM_LIB_LA)
 @BUILDPYTHON_TRUE@	touch _getfem.so && rm _getfem.so
- at BUILDPYTHON_TRUE@	ARCHFLAGS="" python setup.py -v build --build-temp . --build-base . --build-lib . --force
+ at BUILDPYTHON_TRUE@	ARCHFLAGS="" CC="$(CC)" CFLAGS="$(CFLAGS)" $(PYTHON) setup.py -v build @PYTHON_CC_ARG@ --build-temp . --build-base . --build-lib . --force
 #LDSHARED="$(CXX) -shared" ARCHFLAGS="" python setup.py -v build --build-temp . --build-base . --build-lib . --force
 
-# getfem_python_reference.html: getfem.py _getfem.so
-#	cp getfem.py getfem_python_reference.py
-#	(export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):../../../src/.libs && pydoc -w getfem_python_reference) &&  if test -d $(top_srcdir)/interface/doc; then cp getfem_python_reference.html $(top_srcdir)/interface/doc/getfem_python_reference.html; fi;
-#	rm -f getfem_python_reference.py
-
 @BUILDPYTHON_TRUE at all: _getfem.so getfem.py
 #pyexec_LTLIBRARIES = libgfpython.la
 #libgfpython_la_LIBADD = ../.libs/libgetfemint.a @GETFEM_STATICLIBS@
diff --git a/interface/src/python/__init__.py b/interface/src/python/__init__.py
index 356b972..8eb7e0c 100644
--- a/interface/src/python/__init__.py
+++ b/interface/src/python/__init__.py
@@ -8,7 +8,7 @@ This package is licensed under the GNU LGPL 3.
 See the COPYING file in the getfem installation directory or
 print getfem.__LICENSE__
 """
-__revision__ = "$Revision: 4917 $"
+__revision__ = "$Revision$"
 __LICENSE__ = """\
 GetFEM++ 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 along with the GCC Runtime Library Exception either version 3.1 or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or F [...]
 """
diff --git a/interface/src/python/getfem.py b/interface/src/python/getfem.py
index 749c38d..cbb6f3d 100644
--- a/interface/src/python/getfem.py
+++ b/interface/src/python/getfem.py
@@ -47,12 +47,12 @@ getfem('workspace', 'clear all')
 
 def generic_constructor(self, clname, *args):
     """Internal function -- acts as a constructor for all GetFEM objects."""
-    #print 'generic_constructor.'+clname+'('+str(args)+')'
+    #print('generic_constructor.'+clname+'('+str(args)+')')
     if (len(args)==1 and type(args[0]) is GetfemObject):
       if hasattr(self,'id'):
-        print "warning: hasattr(self,'id')!"
-        print "self.id: ",self.id
-        print "args[0]: ",args[0]
+        print("warning: hasattr(self,'id')!")
+        print("self.id: ",self.id)
+        print("args[0]: ",args[0])
       else:
         self.id = args[0]
         #if obj_count.get(self.id,0)==0:
@@ -65,12 +65,12 @@ def generic_destructor(self, destructible=True):
     """Internal function -- acts as a destructor for all GetFEM objects."""
     if (not hasattr(self,'id')):
       return
-    #print "Mesh.__del__       ",self.id,'count=',obj_count[self.id]
-    if (obj_count.has_key(self.id)):
+    #print("Mesh.__del__       ",self.id,'count=',obj_count[self.id])
+    if (self.id in obj_count):
       obj_count[self.id] = obj_count[self.id]-1
       if (destructible and obj_count[self.id] == 0):
         getfem('delete',self.id)
-        #print "effective deletion"
+        #print("effective deletion")
 
 
 
@@ -79,7 +79,7 @@ def generic_destructor(self, destructible=True):
 #
 
 class ContStruct:
-  """GetFEM ContStruct object
+  """GeFEM ContStruct object
 
   This object serves for storing parameters and data used in numerical
   continuation of solution branches of models (for more details about
@@ -266,7 +266,7 @@ class ContStruct:
 #
 
 class CvStruct:
-  """GetFEM CvStruct object
+  """GeFEM CvStruct object
 
 
   """
@@ -328,7 +328,7 @@ class CvStruct:
 #
 
 class Eltm:
-  """GetFEM Eltm object
+  """GeFEM Eltm object
 
 
   This object represents a type of elementary matrix. In order to obtain a
@@ -380,7 +380,7 @@ class Eltm:
 #
 
 class Fem:
-  """GetFEM Fem object
+  """GeFEM Fem object
 
     This object represents a finite element method on a reference element.
 
@@ -586,7 +586,7 @@ class Fem:
 #
 
 class GeoTrans:
-  """GetFEM GeoTrans object
+  """GeFEM GeoTrans object
 
    The geometric transformation must be used when you are building a custom
    mesh convex by convex (see the add_convex() function of Mesh): it also
@@ -683,7 +683,7 @@ class GeoTrans:
 #
 
 class GlobalFunction:
-  """GetFEM GlobalFunction object
+  """GeFEM GlobalFunction object
 
   Global function object is represented by three functions:
 
@@ -780,7 +780,7 @@ class GlobalFunction:
 #
 
 class Integ:
-  """GetFEM Integ object
+  """GeFEM Integ object
 
   General object for obtaining handles to various integrations methods on
   convexes (used when the elementary matrices are built).
@@ -923,7 +923,7 @@ class Integ:
 #
 
 class LevelSet:
-  """GetFEM LevelSet object
+  """GeFEM LevelSet object
 
 
    The level-set object is represented by a primary level-set and optionally
@@ -1029,7 +1029,7 @@ class LevelSet:
 #
 
 class Mesh:
-  """GetFEM Mesh object
+  """GeFEM Mesh object
 
   This object is able to store any element in any dimension even if you mix
   elements with different dimensions.
@@ -1046,6 +1046,9 @@ class Mesh:
   * ``M = Mesh('cartesian', vec X[, vec Y[, vec Z,..]])``
     Build quickly a regular mesh of quadrangles, cubes, etc.
 
+  * ``M = Mesh('pyramidal', vec X[, vec Y[, vec Z,..]])``
+    Build quickly a regular mesh of pyramids, etc.
+
   * ``M = Mesh('cartesian Q1', vec X, vec Y[, vec Z,..])``
     Build quickly a regular mesh of quadrangles, cubes, etc. with
     Q1 elements.
@@ -1116,6 +1119,7 @@ class Mesh:
     
     - 'gmsh' for a mesh created with `Gmsh`
     - 'gid' for a mesh created with `GiD`
+    - 'cdb' for a mesh created with `ANSYS`
     - 'am_fmt' for a mesh created with `EMC2`
 
   * ``M = Mesh('clone', Mesh m2)``
@@ -1659,13 +1663,13 @@ class Mesh:
     return self.set("merge", m2, tol)
 
 
-  def optimize_structure(self):
+  def optimize_structure(self, with_renumbering=None):
     """Reset point and convex numbering.
     
     After optimisation, the points (resp. convexes) will
     be consecutively numbered from ``0`` to
     ``Mesh.max_pid()-1`` (resp. ``Mesh.max_cvid()-1``)."""
-    return self.set("optimize_structure")
+    return self.set("optimize_structure", with_renumbering)
 
 
   def refine(self, CVIDs=None):
@@ -1683,7 +1687,7 @@ class Mesh:
 #
 
 class MeshFem:
-  """GetFEM MeshFem object
+  """GeFEM MeshFem object
 
   This object represents a finite element method defined on a whole mesh.
 
@@ -2105,18 +2109,18 @@ class MeshFem:
       nbd = P.shape[1]
     vars = ('x','y','z','u','v','w')
     nbvars = min(P.shape[0],len(vars))
-    for i in xrange(0,nbvars):
+    for i in range(0,nbvars):
       gl[vars[i]] = P[i,0]
       lo[vars[i]] = P[i,0]
     ccode = compile(expression, '<string>', 'eval');
     r = numpy.array(eval(ccode,gl,lo))
     Z = numpy.zeros(r.shape + (nbd,), r.dtype)
-    nbd_p = nbd/nbp
+    nbd_p = int(nbd/nbp)
     nbd_end = nbd_p*(rk+1)
     if (rk == nbp-1):
       nbd_end = nbd
-    for j in xrange(nbd_p*rk,nbd_end):
-      for i in xrange(0,nbvars):
+    for j in range(nbd_p*rk,nbd_end):
+      for i in range(0,nbvars):
         gl[vars[i]] = P[i,j]
         lo[vars[i]] = P[i,j]
       Z[...,j] = eval(ccode,gl,lo)
@@ -2218,7 +2222,7 @@ class MeshFem:
 #
 
 class MeshIm:
-  """GetFEM MeshIm object
+  """GeFEM MeshIm object
 
   This object represents an integration method defined on a whole mesh (an 
   potentialy on its boundaries).
@@ -2407,7 +2411,7 @@ class MeshIm:
 #
 
 class MeshImData:
-  """GetFEM MeshImData object
+  """GeFEM MeshImData object
 
   This object represents data defined on a mesh_im object.
 
@@ -2488,7 +2492,7 @@ class MeshImData:
 #
 
 class MeshLevelSet:
-  """GetFEM MeshLevelSet object
+  """GeFEM MeshLevelSet object
 
   General constructor for mesh_levelset objects. The role of this object is
   to provide a mesh cut by a certain number of level_set. This object is
@@ -2595,7 +2599,7 @@ class MeshLevelSet:
 #
 
 class MesherObject:
-  """GetFEM MesherObject object
+  """GeFEM MesherObject object
 
   This object represents a geometric object to be meshed by the
   experimental meshing procedure of Getfem.
@@ -2679,7 +2683,7 @@ class MesherObject:
 #
 
 class Model:
-  """GetFEM Model object
+  """GeFEM Model object
 
   Model variables store the variables and the state data and the
   description of a model. This includes the global tangent matrix, the right
@@ -2868,17 +2872,17 @@ class Model:
        Possible values are 'superlu', 'mumps' (if supported),
        'cg/ildlt', 'gmres/ilu' and 'gmres/ilut'.
     - 'lsearch', string LINE_SEARCH_NAME
-       select explicitely the line search method used for the linear systems
-       (the default value is 'default').
+       select explicitely the line search method used for the linear systems (the
+       default value is 'default').
        Possible values are 'simplest', 'systematic', 'quadratic' or 'basic'.
     
-    Return the number of iterations, if an iterative method is used.
+      Return the number of iterations, if an iterative method is used.
       
-    Note that it is possible to disable some variables
-    (see Model.disable_variable() ) in order to
-    solve the problem only with respect to a subset of variables (the
-    disabled variables are then considered as data) for instance to
-    replace the global Newton strategy with a fixed point one."""
+      Note that it is possible to disable some variables
+      (see Model.disable_variable() ) in order to
+      solve the problem only with respect to a subset of variables (the
+      disabled variables are then considered as data) for instance to
+      replace the global Newton strategy with a fixed point one."""
     return self.get("solve", *args)
 
 
@@ -2994,7 +2998,7 @@ class Model:
 
   def elastoplasticity_next_iter(self, mim, varname, previous_dep_name, projname, datalambda, datamu, datathreshold, datasigma):
     """Used with the old (obsolete) elastoplasticity brick to pass from an
-    iteration to the next one. 
+    iteration to the next one.
     Compute and save the stress constraints sigma for the next iterations.
     'mim' is the integration method to use for the computation.
     'varname' is the main variable of the problem.
@@ -3036,14 +3040,14 @@ class Model:
 
 
   def compute_elastoplasticity_Von_Mises_or_Tresca(self, datasigma, mf_vm, version=None):
-    """For the obsolete plasticity brick. Compute on `mf_vm` the Von-Mises or the Tresca stress of a field for plasticity and return it into the vector V.
+    """Compute on `mf_vm` the Von-Mises or the Tresca stress of a field for plasticity and return it into the vector V.
     `datasigma` is a vector which contains the stress constraints values supported by the mesh.
     `version` should be  'Von_Mises' or 'Tresca' ('Von_Mises' is the default)."""
     return self.get("compute_elastoplasticity_Von_Mises_or_Tresca", datasigma, mf_vm, version)
 
 
   def compute_plastic_part(self, mim, mf_pl, varname, previous_dep_name, projname, datalambda, datamu, datathreshold, datasigma):
-    """For the obsolete plasticity brick. Compute on `mf_pl` the plastic part and return it into the vector V.
+    """Compute on `mf_pl` the plastic part and return it into the vector V.
     `datasigma` is a vector which contains the stress constraints values supported by the mesh."""
     return self.get("compute_plastic_part", mim, mf_pl, varname, previous_dep_name, projname, datalambda, datamu, datathreshold, datasigma)
 
@@ -3092,6 +3096,24 @@ class Model:
     return self.get("transformation_name_of_large_sliding_contact_brick", indbrick)
 
 
+  def sliding_data_group_name_of_Nitsche_large_sliding_contact_brick(self, indbrick):
+    """Gives the name of the group of variables corresponding to the
+    sliding data for an existing large sliding contact brick."""
+    return self.get("sliding_data_group_name_of_Nitsche_large_sliding_contact_brick", indbrick)
+
+
+  def displacement_group_name_of_Nitsche_large_sliding_contact_brick(self, indbrick):
+    """Gives the name of the group of variables corresponding to the
+    sliding data for an existing large sliding contact brick."""
+    return self.get("displacement_group_name_of_Nitsche_large_sliding_contact_brick", indbrick)
+
+
+  def transformation_name_of_Nitsche_large_sliding_contact_brick(self, indbrick):
+    """Gives the name of the group of variables corresponding to the
+    sliding data for an existing large sliding contact brick."""
+    return self.get("transformation_name_of_Nitsche_large_sliding_contact_brick", indbrick)
+
+
   def matrix_term(self, ind_brick, ind_term):
     """Gives the matrix term ind_term of the brick ind_brick if it exists
     """
@@ -3239,6 +3261,25 @@ class Model:
     return self.set("add_interpolate_transformation_from_expression", transname, source_mesh, target_mesh, expr)
 
 
+  def add_element_extrapolation_transformation(self, transname, source_mesh, elt_corr):
+    """Add a special interpolation transformation which represents the identity
+    transformation but allows to evaluate the expression on another element
+    than the current element by polynomial extrapolation. It is used for
+    stabilization term in fictitious domain applications. the array elt_cor
+    should be a two entry array whose first line contains the elements
+    concerned by the transformation and the second line the respective
+    elements on which the extrapolation has to be made. If an element
+    is not listed in elt_cor the evaluation is just made on the current
+    element. """
+    return self.set("add_element_extrapolation_transformation", transname, source_mesh, elt_corr)
+
+
+  def set_element_extrapolation_correspondance(self, transname, elt_corr):
+    """Change the correspondance map of an element extrapolation interpolate
+    transformation. """
+    return self.set("set_element_extrapolation_correspondance", transname, elt_corr)
+
+
   def add_raytracing_transformation(self, transname, release_distance):
     """Add a raytracing interpolate transformation called `transname` to a model
     to be used by the generic assembly bricks.
@@ -3269,6 +3310,36 @@ class Model:
     return self.set("add_rigid_obstacle_to_raytracing_transformation", transname, expr, N)
 
 
+  def add_projection_transformation(self, transname, release_distance):
+    """Add a projection interpolate transformation called `transname` to a model
+    to be used by the generic assembly bricks.
+    CAUTION: For the moment, the derivative of the
+    transformation is not taken into account in the model solve. """
+    return self.set("add_projection_transformation", transname, release_distance)
+
+
+  def add_master_contact_boundary_to_projection_transformation(self, transname, m, dispname, region):
+    """Add a master contact boundary with corresponding displacement variable
+    `dispname` on a specific boundary `region` to an existing projection
+    interpolate transformation called `transname`. """
+    return self.set("add_master_contact_boundary_to_projection_transformation", transname, m, dispname, region)
+
+
+  def add_slave_contact_boundary_to_projection_transformation(self, transname, m, dispname, region):
+    """Add a slave contact boundary with corresponding displacement variable
+    `dispname` on a specific boundary `region` to an existing projection
+    interpolate transformation called `transname`. """
+    return self.set("add_slave_contact_boundary_to_projection_transformation", transname, m, dispname, region)
+
+
+  def add_rigid_obstacle_to_projection_transformation(self, transname, expr, N):
+    """Add a rigid obstacle whose geometry corresponds to the zero level-set
+    of the high-level generic assembly expression `expr`
+    to an existing projection interpolate transformation called `transname`.
+    """
+    return self.set("add_rigid_obstacle_to_projection_transformation", transname, expr, N)
+
+
   def add_linear_generic_assembly_brick(self, mim, expression, region=None, *args):
     """Synopsis: ind = Model.add_linear_generic_assembly_brick(self, MeshIm mim, string expression[, int region[, int is_symmetric[, int is_coercive]]])
 
@@ -3318,6 +3389,33 @@ class Model:
     return self.set("add_source_term_generic_assembly_brick", mim, expression, region)
 
 
+  def add_assembly_assignment(self, dataname, expression, region=None, *args):
+    """Synopsis: Model.add_assembly_assignment(self, string dataname, string expression[, int region[, int order[, int before]]])
+
+    Adds expression `expr` to be evaluated at assembly time and being
+    assigned to the data `dataname` which has to be of im_data type.
+    This allows for instance to store a sub-expression of an assembly
+    computation to be used on an other assembly. It can be used for instance
+    to store the plastic strain in plasticity models.
+    `order` represents the order of assembly where this assignement has to be
+    done (potential(0), weak form(1) or tangent system(2) or at each
+    order(-1)). The default value is 1.
+    If before = 1, the the assignement is perfromed before the computation
+    of the other assembly terms, such that the data can be used in the
+    remaining of the assembly as an intermediary result (be careful that it is
+    still considered as a data, no derivation of the expression is performed
+    for the tangent system). 	 
+    If before = 0 (default), the assignement is done after the assembly terms.
+    """
+    return self.set("add_assembly_assignment", dataname, expression, region, *args)
+
+
+  def clear_assembly_assignment(self):
+    """Delete all added assembly assignments
+    """
+    return self.set("clear_assembly_assignment")
+
+
   def add_Laplacian_brick(self, mim, varname, region=None):
     """Add a Laplacian term to the model relatively to the variable `varname`
     (in fact with a minus : :math:`-\\text{div}(\\nabla u)`).
@@ -3983,9 +4081,10 @@ class Model:
     This law supports to possibilities of unknown variables to solve for
     defined by means of `unknowns_type` set to either
     'DISPLACEMENT_AND_PLASTIC_MULTIPLIER' (integer value 1) or
-    'DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE' (integer value 3)
+    'DISPLACEMENT_AND_PLASTIC_MULTIPLIER_AND_PRESSURE' (integer value 3).
     The  "Simo_Miehe" law expects as `varnames` a set of the
     following names that have to be defined as variables in the model:
+    
     - the displacement variable which has to be defined as an unknown,
     - the plastic multiplier which has also defined as an unknown,
     - optionally the pressure variable for a mixed displacement-pressure
@@ -3998,15 +4097,18 @@ class Model:
       Cauchy-Green tensor at the previous time step
       (it has to be a 4 element vector for plane strain 2D problems
       and a 6 element vector for 3D problems).
+    
     The  "Simo_Miehe" law also expects as `params` a set of the
     following three parameters:
+    
     - an expression for the initial bulk modulus K,
     - an expression for the initial shear modulus G,
     - the name of a user predefined function that decribes
       the yield limit as a function of the hardening variable
       (both the yield limit and the hardening variable values are
-       assumed to be Frobenius norms of appropriate stress and strain
-       tensors, respectively),
+      assumed to be Frobenius norms of appropriate stress and strain
+      tensors, respectively).
+    
     As usual, `region` is an optional mesh region on which the term is added.
     If it is not specified, it is added on the whole mesh.
     Return the brick index in the model."""
@@ -4439,7 +4541,6 @@ class Model:
     corresponding to partial differential terms having a Neumann term.
     Moreover, This brick can only be applied to bricks declaring their
     Neumann terms. Returns the brick index in the model.
-    Deprecated brick.
     """
     return self.set("add_Nitsche_contact_with_rigid_obstacle_brick", mim, varname, Neumannterm, dataname_obstacle, gamma0name, region, theta, *args)
 
@@ -4641,12 +4742,59 @@ class Model:
     return self.set("add_master_slave_contact_boundary_to_large_sliding_contact_brick", indbrick, mim, region, dispname, lambdaname, wname)
 
 
+  def add_Nitsche_large_sliding_contact_brick_raytracing(self, unbiased_version, dataname_r, release_distance, dataname_fr=None, *args):
+    """Synopsis: ind = Model.add_Nitsche_large_sliding_contact_brick_raytracing(self, bool unbiased_version, string dataname_r, scalar release_distance[, string dataname_fr[, string dataname_alpha[, int version]]])
+
+    Adds a large sliding contact with friction brick to the model based on the Nitsche's method.
+    This brick is able to deal with self-contact, contact between
+    several deformable bodies and contact with rigid obstacles.
+    It uses the high-level generic assembly. It adds to the model
+    a raytracing_interpolate_transformation object. "unbiased_version" refers to the version of Nische's method to be used.
+    (unbiased or biased one).
+    For each slave boundary a  material law should be defined as a function of the dispacement variable on this boundary.
+    The release distance should be determined with care
+    (generally a few times a mean element size, and less than the
+    thickness of the body). Initially, the brick is added with no contact
+    boundaries. The contact boundaries and rigid bodies are added with
+    special functions. `version` is 0 (the default value) for the
+    non-symmetric version and 1 for the more symmetric one
+    (not fully symmetric even without friction). """
+    return self.set("add_Nitsche_large_sliding_contact_brick_raytracing", unbiased_version, dataname_r, release_distance, dataname_fr, *args)
+
+
+  def add_rigid_obstacle_to_Nitsche_large_sliding_contact_brick(self, indbrick, expr, N):
+    """Adds a rigid obstacle to an existing large sliding contact
+    with friction brick. `expr` is an expression using the high-level
+    generic assembly language (where `x` is the current point n the mesh)
+    which should be a signed distance to the obstacle.
+    `N` is the mesh dimension. """
+    return self.set("add_rigid_obstacle_to_Nitsche_large_sliding_contact_brick", indbrick, expr, N)
+
+
+  def add_master_contact_boundary_to_biased_Nitsche_large_sliding_contact_brick(self, indbrick, mim, region, dispname, wname=None):
+    """Adds a master contact boundary to an existing biased Nitsche's large sliding contact
+    with friction brick. """
+    return self.set("add_master_contact_boundary_to_biased_Nitsche_large_sliding_contact_brick", indbrick, mim, region, dispname, wname)
+
+
+  def add_slave_contact_boundary_to_biased_Nitsche_large_sliding_contact_brick(self, indbrick, mim, region, dispname, lambdaname, wname=None):
+    """Adds a slave contact boundary to an existing biased Nitsche's large sliding contact
+    with friction brick. """
+    return self.set("add_slave_contact_boundary_to_biased_Nitsche_large_sliding_contact_brick", indbrick, mim, region, dispname, lambdaname, wname)
+
+
+  def add_contact_boundary_to_unbiased_Nitsche_large_sliding_contact_brick(self, indbrick, mim, region, dispname, lambdaname, wname=None):
+    """Adds a contact boundary to an existing unbiased Nitschelarge sliding contact
+    with friction brick which is both master and slave. """
+    return self.set("add_contact_boundary_to_unbiased_Nitsche_large_sliding_contact_brick", indbrick, mim, region, dispname, lambdaname, wname)
+
+
 #
 # GetFEM class Precond definition.
 #
 
 class Precond:
-  """GetFEM Precond object
+  """GeFEM Precond object
 
   The preconditioners may store REAL or COMPLEX values. They accept getfem
   sparse matrices and Matlab sparse matrices.
@@ -4752,7 +4900,7 @@ class Precond:
 #
 
 class Slice:
-  """GetFEM Slice object
+  """GeFEM Slice object
 
   Creation of a mesh slice. Mesh slices are very similar to a
   P1-discontinuous MeshFem on which interpolation is very fast. The slice is
@@ -5052,7 +5200,7 @@ class Slice:
 #
 
 class Spmat:
-  """GetFEM Spmat object
+  """GeFEM Spmat object
 
   Create a new sparse matrix in getfem++ format. These sparse matrix can be stored as CSC (compressed column
   sparse), which is the format used by Matlab, or they can be stored as WSC
@@ -5467,23 +5615,6 @@ def asm_nonlinear_elasticity(mim, mf_u, U, law, mf_d, params, *args):
   return getfem('asm', 'nonlinear_elasticity', mim, mf_u, U, law, mf_d, params, *args)
 
 
-def asm_stokes(mim, mf_u, mf_p, mf_d, nu, region=None):
-  """Assembly of matrices for the Stokes problem.
-  
-  :math:`-\\nu(x)\\Delta u + \\nabla p = 0`
-  :math:`\\nabla\\cdot u  = 0`
-  with :math:`\\nu` (`nu`), the fluid's dynamic viscosity.
-  
-  On output, `K` is the usual linear elasticity stiffness matrix with
-  :math:`\\lambda = 0` and
-  :math:`2\\mu = \\nu`. `B` is a matrix
-  corresponding to :math:`\\int p\\nabla\\cdot\\phi`.
-  
-  `K` and `B` are SpMat object's.
-  """
-  return getfem('asm', 'stokes', mim, mf_u, mf_p, mf_d, nu, region)
-
-
 def asm_helmholtz(mim, mf_u, mf_d, k, region=None):
   """Assembly of the matrix for the Helmholtz problem.
   
@@ -5751,7 +5882,7 @@ def compute_L2_norm(MF, U, mim, CVids=None):
   """Compute the L2 norm of the (real or complex) field `U`.
   
   If `CVids` is given, the norm will be computed only on the listed
-  convexes."""
+  elements."""
   return getfem('compute', MF, U, 'L2_norm', mim, CVids)
 
 
@@ -5759,7 +5890,7 @@ def compute_L2_dist(MF, U, mim, mf2, U2, CVids=None):
   """Compute the L2 distance between `U` and `U2`.
   
   If `CVids` is given, the norm will be computed only on the listed
-  convexes."""
+  elements."""
   return getfem('compute', MF, U, 'L2_dist', mim, mf2, U2, CVids)
 
 
@@ -5767,7 +5898,7 @@ def compute_H1_semi_norm(MF, U, mim, CVids=None):
   """Compute the L2 norm of grad(`U`).
   
   If `CVids` is given, the norm will be computed only on the listed
-  convexes."""
+  elements."""
   return getfem('compute', MF, U, 'H1_semi_norm', mim, CVids)
 
 
@@ -5775,7 +5906,7 @@ def compute_H1_semi_dist(MF, U, mim, mf2, U2, CVids=None):
   """Compute the semi H1 distance between `U` and `U2`.
   
   If `CVids` is given, the norm will be computed only on the listed
-  convexes."""
+  elements."""
   return getfem('compute', MF, U, 'H1_semi_dist', mim, mf2, U2, CVids)
 
 
@@ -5783,7 +5914,7 @@ def compute_H1_norm(MF, U, mim, CVids=None):
   """Compute the H1 norm of `U`.
   
   If `CVids` is given, the norm will be computed only on the listed
-  convexes."""
+  elements."""
   return getfem('compute', MF, U, 'H1_norm', mim, CVids)
 
 
@@ -5791,7 +5922,7 @@ def compute_H2_semi_norm(MF, U, mim, CVids=None):
   """Compute the L2 norm of D^2(`U`).
   
   If `CVids` is given, the norm will be computed only on the listed
-  convexes."""
+  elements."""
   return getfem('compute', MF, U, 'H2_semi_norm', mim, CVids)
 
 
@@ -5799,7 +5930,7 @@ def compute_H2_norm(MF, U, mim, CVids=None):
   """Compute the H2 norm of `U`.
   
   If `CVids` is given, the norm will be computed only on the listed
-  convexes."""
+  elements."""
   return getfem('compute', MF, U, 'H2_norm', mim, CVids)
 
 
@@ -6037,13 +6168,13 @@ def util_warning_level(level):
 
 
 def memstats():
-  print "*** GetFEM view of the workspace:"
+  print("*** GetFEM view of the workspace:")
   getfem('workspace','stats')
-  print "*** Python view of the workspace:"
-  for id,c in obj_count.iteritems():
+  print("*** Python view of the workspace:")
+  for id,c in obj_count.items():
     if (c):
       name=str(factory(id).__class__)
-      print "%s class %d, id %d : instances=%d" % (name,id.classid,id.objid,c)
+      print("%s class %d, id %d : instances=%d" % (name,id.classid,id.objid,c))
 
 def linsolve(what, *args):
   return getfem('linsolve', what, *args)
diff --git a/interface/src/python/getfem_python.c b/interface/src/python/getfem_python.c
index 89c5b59..e01c70e 100644
--- a/interface/src/python/getfem_python.c
+++ b/interface/src/python/getfem_python.c
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier.
+ Copyright (C) 2004-2017 Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -34,7 +34,16 @@
 #include "getfem_arch_config.h"
 #include <assert.h>
 
-
+#if PY_MAJOR_VERSION >= 3
+#define PyString_AsString(o) PyUnicode_AsUTF8(o)
+#define PyString_FromFormat(a,b,c) PyUnicode_FromFormat(a,b,c)
+#define PyString_Check(o) PyUnicode_Check(o)
+#define PyInt_Check(o) PyLong_Check(o)
+#define PyInt_AsLong(o) PyLong_AsLong(o)
+#define PyString_FromString(o) PyUnicode_FromString(o)
+#define PyString_FromStringAndSize(o,l) PyUnicode_FromStringAndSize(o,l)
+#define PyInt_FromLong(o) PyLong_FromLong(o)
+#endif
 
 static PyObject *call_getfem(PyObject *self, PyObject *args);
 static PyObject *getfem_env(PyObject *self, PyObject *args);
@@ -53,8 +62,7 @@ typedef struct PyGetfemObject {
 } PyGetfemObject;
 
 static PyObject *
-GetfemObject_name(PyGetfemObject *self)
-{
+GetfemObject_name(PyGetfemObject *self) {
   return PyString_FromFormat("getfem.GetfemObject(classid=%d,objid=%d)",
                              self->classid, self->objid);
 }
@@ -67,8 +75,24 @@ GetfemObject_hash(PyGetfemObject *key) {
 static int
 GetfemObject_compare(PyGetfemObject *self, PyGetfemObject *other) {
   if (self->classid < other->classid) return -1;
-  else if (self->objid < other->objid) return +1;
-  else return 0;
+  if (self->classid > other->classid) return +1;
+  if (self->objid < other->objid) return -1;
+  if (self->objid > other->objid) return +1;
+  return 0;
+}
+
+static PyObject *
+GfObject_richcompare(PyGetfemObject *self, PyGetfemObject *other, int op) {
+  int bc = GetfemObject_compare(self, other);
+  switch(op) {
+  case Py_LT : if (bc <  0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+  case Py_LE : if (bc <= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+  case Py_EQ : if (bc == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+  case Py_NE : if (bc != 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+  case Py_GT : if (bc == 1) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+  case Py_GE : if (bc >= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
+  }
+  return NULL;
 }
 
 static PyMethodDef module_methods[] = {
@@ -101,8 +125,12 @@ static PyMemberDef GetfemObject_members[] = {
 };
 
 static PyTypeObject PyGetfemObject_Type = {
+#if PY_MAJOR_VERSION >= 3
+    PyVarObject_HEAD_INIT(NULL, 0)
+#else
     PyObject_HEAD_INIT(NULL)
     0,                                 /* ob_size (deprecated) */
+#endif
     "_getfem.GetfemObject",            /* tp_name */
     sizeof(PyGetfemObject),            /* tp_basicsize */
     0,                                 /* tp_itemsize */
@@ -110,7 +138,11 @@ static PyTypeObject PyGetfemObject_Type = {
     0,                                 /* tp_print */
     0,                                 /* tp_getattr */
     0,                                 /* tp_setattr */
+#if PY_MAJOR_VERSION >= 3
+    GetfemObject_compare,              /* tp_compare, necessary for dictionary*/
+#else
     (cmpfunc)GetfemObject_compare,     /* tp_compare, necessary for dictionary*/
+#endif
     0,                                 /* tp_repr */
     0,                                 /* tp_as_number */
     0,                                 /* tp_as_sequence */
@@ -125,7 +157,7 @@ static PyTypeObject PyGetfemObject_Type = {
     "Generic GetFEM objects",          /* tp_doc */
     0,                                 /* tp_traverse */
     0,                                 /* tp_clear */
-    0,                                 /* tp_richcompare */
+    (richcmpfunc)GfObject_richcompare, /* tp_richcompare */
     0,                                 /* tp_weaklistoffset */
     0,                                 /* tp_iter */
     0,                                 /* tp_iternext */
@@ -153,6 +185,37 @@ static PyTypeObject PyGetfemObject_Type = {
 #ifndef PyMODINIT_FUNC        /* declarations for DLL import/export */
 #define PyMODINIT_FUNC void
 #endif
+
+#if PY_MAJOR_VERSION >= 3
+
+static struct PyModuleDef moduledef = {
+  PyModuleDef_HEAD_INIT,
+  "_getfem",     /* m_name */
+  "getfem-python3 interface module.",  /* m_doc */
+  -1,                  /* m_size */
+  module_methods,    /* m_methods */
+  NULL,                /* m_reload */
+  NULL,                /* m_traverse */
+  NULL,                /* m_clear */
+  NULL,                /* m_free */
+};
+
+PyMODINIT_FUNC
+PyInit__getfem(void)
+{
+  PyObject *m;
+  PyGetfemObject_Type.tp_new = PyType_GenericNew;
+  if (PyType_Ready(&PyGetfemObject_Type) < 0)
+    return NULL;
+  m = PyModule_Create(&moduledef);
+  import_array(); /* init Numpy */
+  Py_INCREF(&PyGetfemObject_Type);
+  PyModule_AddObject(m, "GetfemObject", (PyObject *)&PyGetfemObject_Type);
+  return m;
+}
+
+#else
+
 PyMODINIT_FUNC
 init_getfem(void)
 {
@@ -167,7 +230,7 @@ init_getfem(void)
   PyModule_AddObject(m, "GetfemObject", (PyObject *)&PyGetfemObject_Type);
 }
 
-
+#endif
 
 #define COLLECTCHUNK 2
 typedef struct ptr_collect {
@@ -278,7 +341,7 @@ PyObject_to_gfi_array(gcollect *gc, PyObject *o)
   if (PyString_Check(o)) {
     //printf("String\n");
     /* for strings, the pointer is shared, no copy */
-    int L = strlen(PyString_AsString(o));
+    int L = (int)(strlen(PyString_AsString(o)));
     char *s = PyString_AsString(o);
     gc_ref(gc, o, 0);
 
@@ -420,8 +483,8 @@ PyObject_to_gfi_array(gcollect *gc, PyObject *o)
     t->storage.type = GFI_CELL;
     t->dim.dim_len = 1; t->dim.dim_val = &TGFISTORE(cell,len);
 
-    if (PyTuple_Check(o)) TGFISTORE(cell,len) = PyTuple_GET_SIZE(o);
-    else TGFISTORE(cell,len) = PyList_GET_SIZE(o);
+    if (PyTuple_Check(o)) TGFISTORE(cell,len) = (unsigned)(PyTuple_GET_SIZE(o));
+    else TGFISTORE(cell,len) = (unsigned)(PyList_GET_SIZE(o));
 
     if (!(TGFISTORE(cell,val)
           = gc_alloc(gc,sizeof(gfi_array*)*TGFISTORE(cell,len)))) return NULL;
@@ -489,7 +552,7 @@ build_gfi_array_list(gcollect *gc, PyObject *tuple, char **pfunction_name,
     return NULL;
   }
   *pfunction_name = PyString_AsString(PyTuple_GET_ITEM(tuple,0));
-  *nb = PyTuple_GET_SIZE(tuple) - 1;
+  *nb = (int)(PyTuple_GET_SIZE(tuple) - 1);
   if (!(l = gc_alloc(gc, sizeof(gfi_array*) * *nb))) return NULL;
   for (i=0, j = 0; i < *nb; ++i) {
     PyObject *o = PyTuple_GET_ITEM(tuple,i+1);
@@ -715,7 +778,7 @@ getfem_env(PyObject *self, PyObject *args) {
     word_out = PyString_FromString("GetFEM++");
   } else if (strcmp(word_in,"copyright") == 0) {
     word_out = PyString_FromString
-    ("2004-2016 GetFEM++ project");
+    ("2004-2017 GetFEM++ project");
   } else if (strcmp(word_in,"authors") == 0) {
     word_out = PyString_FromString
     ("Yves Renard, Julien Pommier");
diff --git a/interface/src/python/setup.py.in b/interface/src/python/setup.py.in
index ec92237..7e79e13 100644
--- a/interface/src/python/setup.py.in
+++ b/interface/src/python/setup.py.in
@@ -1,5 +1,24 @@
 #!/usr/bin/env python
-# -*- coding: iso-8859-1 -*-
+# -*- coding: utf-8 -*-
+# Python GetFEM++ interface
+#
+# Copyright (C) 2004-2017 Julien Pommier.
+#
+# This file is a part of GetFEM++
+#
+# GetFEM++  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 along with the GCC Runtime Library
+# Exception either version 3.1 or (at your option) any later version.
+# This program  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 and GCC Runtime Library Exception for more details.
+# You  should  have received a copy of the GNU Lesser General Public License
+# along  with  this program;  if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+#
 """This is the getfem-python-interface module.
 
 """
@@ -42,14 +61,14 @@ libdirs = [l for l in libdirs if len(l.strip())]
 #print "libdirs = ", libdirs
 getfemmod = Extension('_getfem',
                       include_dirs = ['@top_srcdir@/src/getfem','../../../src/getfem','@srcdir@/..','@srcdir@',npy_include_dir],
-                      libraries = libnames, #['getfemint','getfem','stdc++','m'],
-                      library_dirs = libdirs, #['../src/.libs',
-#                                      '@GETFEM_STATICLIBS@'],
-                      sources = ['getfem_python_c.c'])
+                      libraries = libnames,
+                      library_dirs = libdirs,
+                      sources = ['getfem_python_c.c'],
+                      @PYTHON_EXTRA_EXT_PARAM@)
 
 setup (name = 'getfem-interface',
        license='LGPL',
-       version = '4.0',
+       version = '5.2',
        maintainer="Yves Renard",
        maintainer_email="Yves.Renard at insa-lyon.fr",
        description = "This is the getfem-python-interface module",
diff --git a/interface/tests/Makefile.am b/interface/tests/Makefile.am
old mode 100755
new mode 100644
index 2543374..e895194
--- a/interface/tests/Makefile.am
+++ b/interface/tests/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 
 if BUILDMEX
 subdirMATLAB=matlab
diff --git a/interface/tests/Makefile.in b/interface/tests/Makefile.in
index 300fcd8..02bb24c 100644
--- a/interface/tests/Makefile.in
+++ b/interface/tests/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -88,6 +95,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = interface/tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -103,7 +112,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -163,7 +171,6 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = meshes matlab python
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -256,7 +263,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -289,8 +295,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -371,7 +379,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -398,6 +405,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/tests/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/tests/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -692,8 +700,6 @@ uninstall-am:
 	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
 	ps ps-am tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/interface/tests/matlab/Makefile.am b/interface/tests/matlab/Makefile.am
index 9829aef..442c69a 100644
--- a/interface/tests/matlab/Makefile.am
+++ b/interface/tests/matlab/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 SUBDIRS = private
 
 if BUILDMEX
@@ -27,6 +44,7 @@ EXTRA_DIST=						\
 	demo_laplacian_DG.m 				\
 	demo_Mindlin_Reissner_plate.m 			\
 	demo_laplacian.m 				\
+	demo_laplacian_pyramid.m			\
 	demo_periodic_laplacian.m 			\
 	demo_nonlinear_elasticity.m 			\
 	demo_nonlinear_elasticity_anim.m 		\
diff --git a/interface/tests/matlab/Makefile.in b/interface/tests/matlab/Makefile.in
index 57440f0..1f37662 100644
--- a/interface/tests/matlab/Makefile.in
+++ b/interface/tests/matlab/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,18 +14,25 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -90,6 +97,8 @@ build_triplet = @build@
 host_triplet = @host@
 @BUILDMEX_TRUE at TESTS = $(abs_srcdir)/check_all.sh
 subdir = interface/tests/matlab
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -105,7 +114,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -370,8 +378,6 @@ TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
 DIST_SUBDIRS = $(SUBDIRS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs \
-	$(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -464,7 +470,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -497,8 +502,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -579,7 +586,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -609,6 +615,7 @@ EXTRA_DIST = \
 	demo_laplacian_DG.m 				\
 	demo_Mindlin_Reissner_plate.m 			\
 	demo_laplacian.m 				\
+	demo_laplacian_pyramid.m			\
 	demo_periodic_laplacian.m 			\
 	demo_nonlinear_elasticity.m 			\
 	demo_nonlinear_elasticity_anim.m 		\
@@ -670,6 +677,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/tests/matlab/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/tests/matlab/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -858,7 +866,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1171,8 +1179,6 @@ uninstall-am: uninstall-toolboxSCRIPTS
 	recheck tags tags-am uninstall uninstall-am \
 	uninstall-toolboxSCRIPTS
 
-.PRECIOUS: Makefile
-
 	PATH=@abs_top_builddir@/src:$(PATH)
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/interface/tests/matlab/axrot_matrix.m b/interface/tests/matlab/axrot_matrix.m
index decbe8c..9f38c74 100644
--- a/interface/tests/matlab/axrot_matrix.m
+++ b/interface/tests/matlab/axrot_matrix.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2004-2016 Julien Pommier.
+% Copyright (C) 2004-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_all.m b/interface/tests/matlab/check_all.m
index b1328f7..17764aa 100644
--- a/interface/tests/matlab/check_all.m
+++ b/interface/tests/matlab/check_all.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_asm.m b/interface/tests/matlab/check_asm.m
index e408e04..f141d94 100644
--- a/interface/tests/matlab/check_asm.m
+++ b/interface/tests/matlab/check_asm.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_fem.m b/interface/tests/matlab/check_fem.m
index 9428791..6e4914b 100644
--- a/interface/tests/matlab/check_fem.m
+++ b/interface/tests/matlab/check_fem.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_geotrans.m b/interface/tests/matlab/check_geotrans.m
index 6e2ab49..f6d617e 100644
--- a/interface/tests/matlab/check_geotrans.m
+++ b/interface/tests/matlab/check_geotrans.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_integ.m b/interface/tests/matlab/check_integ.m
index 2d24b0f..9254d90 100644
--- a/interface/tests/matlab/check_integ.m
+++ b/interface/tests/matlab/check_integ.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Yves Renard, Julien Pommier.
+% Copyright (C) 2005-2017 Yves Renard, Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_mesh_fem.m b/interface/tests/matlab/check_mesh_fem.m
index a20d7ec..5103dc6 100644
--- a/interface/tests/matlab/check_mesh_fem.m
+++ b/interface/tests/matlab/check_mesh_fem.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
@@ -167,11 +167,11 @@ function check_mesh_fem(iverbose,idebug)
 
   gf_mesh_fem_get(mf,'nbdof') % should be 99 or 100 (element 0 and 1 are not really neigbhor but can be viewed as such)
   d=gf_mesh_fem_get(mf,'basic dof from cv',[1 5])
-  gfassert(['d==[1 2 3 4 5 6 38 41 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58]']);
+  gfassert(['d==[1 2 3 4 5 6 29 32 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49]']);
   d=gf_mesh_fem_get(mf,'basic dof from cv',[1 5;1 2])
-  gfassert('d==[3 5 6 38 41 43 46 48 51 53 56 58]');
+  gfassert('d==[3 5 6 29 32 34 37 39 42 44 47 49]');
   d=gf_mesh_fem_get(mf,'basic dof from cvid',5)
-  gfassert('d==[38 44 45 46 47 48 41 49 50 51 52 53 43 54 55 56 57 58]');
+  gfassert('d==[29 35 36 37 38 39 32 40 41 42 43 44 34 45 46 47 48 49]');
   
   s2=gf_mesh_get(mf,'char');
   gfassert('length(s2)>500');
@@ -227,9 +227,9 @@ function check_mesh_fem(iverbose,idebug)
   gf_mesh_set(m, 'boundary', 7, [3 4; 3 2]);
   cl=[1:5 7 8];
   asserterr('gf_mesh_fem_get(mf_u, ''non conformal basic dof'')');
-  d=gf_mesh_fem_get(mf_u, 'non conformal basic dof',cl);
+  d=gf_mesh_fem_get(mf_u, 'non conformal basic dof',cl)
   %gf_plot_mesh(mf_u, 'dof', 'on');
-  gfassert('d==[11 12 13 14 15 16 21 22]');
+  gfassert('d==[19 20 21 22 23 24 29 30]');
 
   f=gf_mesh_fem_get(mf2, 'fem');
   f5=gf_mesh_fem_get(mf2, 'fem',5);
@@ -319,7 +319,7 @@ function check_mesh_fem(iverbose,idebug)
   gfassert('ncv < maxcvid');
 
   
-  gf_mesh_set(m,'optimize structure');
+  gf_mesh_set(m,'optimize structure', false);
 
   maxpid=gf_mesh_get(m,'max pid');
   maxcvid=gf_mesh_get(m,'max cvid');
diff --git a/interface/tests/matlab/check_oo.m b/interface/tests/matlab/check_oo.m
index 69ee28d..83d8614 100644
--- a/interface/tests/matlab/check_oo.m
+++ b/interface/tests/matlab/check_oo.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_plasticity.m b/interface/tests/matlab/check_plasticity.m
index 94ce787..f51360e 100644
--- a/interface/tests/matlab/check_plasticity.m
+++ b/interface/tests/matlab/check_plasticity.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2010-2016 Amandine Cottaz, Yves Renard, Farshid Dabaghi.
+% Copyright (C) 2010-2017 Amandine Cottaz, Yves Renard, Farshid Dabaghi.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_plot.m b/interface/tests/matlab/check_plot.m
index 1d931d4..8890df7 100644
--- a/interface/tests/matlab/check_plot.m
+++ b/interface/tests/matlab/check_plot.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_slices.m b/interface/tests/matlab/check_slices.m
index 46243fb..df5e915 100644
--- a/interface/tests/matlab/check_slices.m
+++ b/interface/tests/matlab/check_slices.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/check_spmat.m b/interface/tests/matlab/check_spmat.m
index 528a829..d5e2612 100644
--- a/interface/tests/matlab/check_spmat.m
+++ b/interface/tests/matlab/check_spmat.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
@@ -168,7 +168,8 @@ function check_spmat(iverbose,idebug)
   A=gf_asm('laplacian',mim,mf,mf,ones(1,gf_mesh_fem_get(mf,'nbdof')));
   A=A+.1*speye(size(A,1));
   B=rand(gf_mesh_fem_get(mf,'nbdof'),1);
-  [L,U]=luinc(A,'0');
+  setup.type='nofill';
+  [L,U]=ilu(A,setup);
   X1=gf_linsolve('cg',A,B);
   mm=gf_spmat('copy',inv(L));
   p=gf_precond('spmat',mm);
diff --git a/interface/tests/matlab/check_workspace.m b/interface/tests/matlab/check_workspace.m
index 413da61..f21271d 100644
--- a/interface/tests/matlab/check_workspace.m
+++ b/interface/tests/matlab/check_workspace.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_Mindlin_Reissner_plate.m b/interface/tests/matlab/demo_Mindlin_Reissner_plate.m
index 365641f..d308ebf 100644
--- a/interface/tests/matlab/demo_Mindlin_Reissner_plate.m
+++ b/interface/tests/matlab/demo_Mindlin_Reissner_plate.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2015-2016 FABRE Mathieu, SECK Mamadou, DALLERIT Valentin,
+% Copyright (C) 2015-2017 FABRE Mathieu, SECK Mamadou, DALLERIT Valentin,
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_Navier_Stokes.m b/interface/tests/matlab/demo_Navier_Stokes.m
index 6652948..cdb95d0 100644
--- a/interface/tests/matlab/demo_Navier_Stokes.m
+++ b/interface/tests/matlab/demo_Navier_Stokes.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2011-2016 Mariama Ndiaye, Yves Renard.
+% Copyright (C) 2011-2017 Mariama Ndiaye, Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_Nitsche_contact_by_hand.m b/interface/tests/matlab/demo_Nitsche_contact_by_hand.m
index 0f782fc..8075a97 100644
--- a/interface/tests/matlab/demo_Nitsche_contact_by_hand.m
+++ b/interface/tests/matlab/demo_Nitsche_contact_by_hand.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2015-2016 Rabii Mlika, Yves Renard.
+% Copyright (C) 2015-2017 Rabii Mlika, Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_bilaplacian.m b/interface/tests/matlab/demo_bilaplacian.m
index 9d3e2a2..a85407b 100644
--- a/interface/tests/matlab/demo_bilaplacian.m
+++ b/interface/tests/matlab/demo_bilaplacian.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Yves Renard, Julien Pommier.
+% Copyright (C) 2005-2017 Yves Renard, Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_contact_fictitious_domain_nitsche.m b/interface/tests/matlab/demo_contact_fictitious_domain_nitsche.m
index b7a4ada..54e8480 100644
--- a/interface/tests/matlab/demo_contact_fictitious_domain_nitsche.m
+++ b/interface/tests/matlab/demo_contact_fictitious_domain_nitsche.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2006-2016 Mathieu Fabre.
+% Copyright (C) 2006-2017 Mathieu Fabre.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_continuation.m b/interface/tests/matlab/demo_continuation.m
index bf5dcae..1e6015c 100644
--- a/interface/tests/matlab/demo_continuation.m
+++ b/interface/tests/matlab/demo_continuation.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2011-2016 Tomas Ligursky, Yves Renard.
+% Copyright (C) 2011-2017 Tomas Ligursky, Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_convection_rotating_cavity.m b/interface/tests/matlab/demo_convection_rotating_cavity.m
index d53a59a..530fdd1 100644
--- a/interface/tests/matlab/demo_convection_rotating_cavity.m
+++ b/interface/tests/matlab/demo_convection_rotating_cavity.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2009-2016 Yves Renard.
+% Copyright (C) 2009-2017 Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_crack.m b/interface/tests/matlab/demo_crack.m
index dc8e85c..71512de 100644
--- a/interface/tests/matlab/demo_crack.m
+++ b/interface/tests/matlab/demo_crack.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2009-2016 Luis Saavedra, Yves Renard.
+% Copyright (C) 2009-2017 Luis Saavedra, Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_dynamic_plasticity.m b/interface/tests/matlab/demo_dynamic_plasticity.m
index 94f6c8a..4ca49d6 100644
--- a/interface/tests/matlab/demo_dynamic_plasticity.m
+++ b/interface/tests/matlab/demo_dynamic_plasticity.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2010-2016 Yves Renard, Farshid Dabaghi.
+% Copyright (C) 2010-2017 Yves Renard, Farshid Dabaghi.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_elasticity.m b/interface/tests/matlab/demo_elasticity.m
index 2f91034..98d2ff7 100644
--- a/interface/tests/matlab/demo_elasticity.m
+++ b/interface/tests/matlab/demo_elasticity.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_fictitious_domains.m b/interface/tests/matlab/demo_fictitious_domains.m
index f41f57c..de5b0af 100644
--- a/interface/tests/matlab/demo_fictitious_domains.m
+++ b/interface/tests/matlab/demo_fictitious_domains.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+% Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_fictitious_domains_laplacian.m b/interface/tests/matlab/demo_fictitious_domains_laplacian.m
index b630044..70c10b1 100644
--- a/interface/tests/matlab/demo_fictitious_domains_laplacian.m
+++ b/interface/tests/matlab/demo_fictitious_domains_laplacian.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+% Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
@@ -54,7 +54,7 @@ end
 
 ls=gf_levelset(m, ls_degree);
 ls2s=gf_levelset(m, ls_degree, 'with_secondary');
-ls2=gf_levelset(m, ls_degree, 'with_secondary');
+ls2=gf_LevelSet(m, ls_degree, 'with_secondary');
 
 mf_ls=gfObject(gf_levelset_get(ls, 'mf'));
 mf_ls2=gfObject(gf_levelset_get(ls2, 'mf'));
@@ -195,21 +195,21 @@ if (N == 2)
   figure(1);
   gf_plot(mfu, U, 'mesh','on', 'refine', 2);
   xlabel('x'); ylabel('y');
-  title('Displasment solution');
+  title('Displacement solution');
   figure(2);
   gf_plot(mfu0, map_Error, 'mesh','on', 'refine', 2);
   xlabel('x'); ylabel('y');
   title('Map Error in displacement');
 else
  % gf_plot(mfu, U, 'mesh','on', 'cvlst', gf_mesh_get(m, 'outer faces'), 'refine', 2);
- %Plot displasment
+ %Plot displacement
   figure(1);
   sl=gf_slice({'boundary',{'intersection',{'ball', -1,[0;0;0], R},{'planar',1,[0;0;0],[0;0;1]}}},mfu,3);
   %sl=gf_slice({'boundary',{'intersection',{'ball',-1,[0;0;0],R}}},mfu,1);
   Usl=gf_compute(mfu,U,'interpolate on', sl);
   gf_plot_slice(sl,'mesh_faces','on','mesh','off','data',Usl,'mesh_slice_edges','on');
   xlabel('x'); ylabel('y'); zlabel('z');
-  title('Displasment solution');
+  title('Displacement solution');
   
   
   %plot exact solution
diff --git a/interface/tests/matlab/demo_laplacian.m b/interface/tests/matlab/demo_laplacian.m
index 4a55dc9..f070f78 100644
--- a/interface/tests/matlab/demo_laplacian.m
+++ b/interface/tests/matlab/demo_laplacian.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
@@ -36,6 +36,7 @@ if (quadrangles)
 else
   m=gf_mesh('import','structured',sprintf('GT="GT_PK(2,1)";SIZES=[1,1];NOISED=0;NSUBDIV=[%d,%d];', NX, NX));
 end
+gf_mesh_set(m, 'optimize structure')
 
 % Create a mesh_fem of for a field of dimension 1 (i.e. a scalar field)
 mf = gf_mesh_fem(m,1);
@@ -50,12 +51,13 @@ else
 end
 
 % Detect the border of the mesh
-border = gf_mesh_get(m,'outer faces');
+border = gf_mesh_get(m, 'outer faces');
 % Mark it as boundary GAMMAD=1
 GAMMAD=1;
 gf_mesh_set(m, 'region', GAMMAD, border);
 if (draw)
-  gf_plot_mesh(m, 'regions', [GAMMAD]); % the boundary edges appear in red
+  figure(1);
+  gf_plot_mesh(m, 'regions', [GAMMAD], 'convexes', 'on'); % the boundary edges appear in red
   pause(1);
 end
 
@@ -89,6 +91,7 @@ gf_model_get(md, 'solve');
 U = gf_model_get(md, 'variable', 'u');
 
 if (draw)
+  figure(2);
   subplot(2,1,1); gf_plot(mf,U,'mesh','off'); 
   colorbar; title('computed solution');
 
diff --git a/interface/tests/matlab/demo_laplacian_DG.m b/interface/tests/matlab/demo_laplacian_DG.m
index e025e36..035badf 100644
--- a/interface/tests/matlab/demo_laplacian_DG.m
+++ b/interface/tests/matlab/demo_laplacian_DG.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2015-2016 Yves Renard.
+% Copyright (C) 2015-2017 Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_laplacian_pyramid.m b/interface/tests/matlab/demo_laplacian_pyramid.m
new file mode 100644
index 0000000..520811d
--- /dev/null
+++ b/interface/tests/matlab/demo_laplacian_pyramid.m
@@ -0,0 +1,155 @@
+% Copyright (C) 2005-2017 Yves Renard, Julien Pommier.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+% Options for prescribing the Dirichlet condition
+clear all;
+dirichlet_version = 1; % 0 = simplification, 1 = with multipliers,
+                       % 2 = penalization,  3 = Nitsche's method
+theta = 1;       % Nitsche's method parameter theta
+gamma0 = 0.001;  % Nitsche's method parameter gamma0 (gamma = gamma0*h)
+r = 1e8;         % Penalization parameter
+draw = true;
+draw_mesh = false;
+with_pyramids = true;
+
+K = 2;           % Degree of the finite element method
+
+asize =  size(who('automatic_var654'));
+if (asize(1)) draw = false; end;
+
+% trace on;
+NX = 10;
+if (with_pyramids)
+  m = gf_mesh('pyramidal', [0:1/NX:1], [0:1/NX:1], [0:1/NX:1]);
+else
+  m = gf_mesh('regular simplices', [0:1/NX:1], [0:1/NX:1], [0:1/NX:1]);
+end
+
+% Create a mesh_fem of for a field of dimension 1 (i.e. a scalar field)
+mf = gf_mesh_fem(m,1);
+% Assign the pyramidal fem to all convexes of the mesh_fem, and define an
+% integration method
+if (with_pyramids)
+  gf_mesh_fem_set(mf,'fem',gf_fem(sprintf('FEM_PYRAMID_LAGRANGE(%d)', K)));
+  % mim = gf_mesh_im(m, gf_integ('IM_PYRAMID_COMPOSITE(IM_TETRAHEDRON(5))'));
+  mim = gf_mesh_im(m, gf_integ('IM_PYRAMID(IM_GAUSS_PARALLELEPIPED(3,5))'));
+  % mim = gf_mesh_im(m, gf_integ('IM_PYRAMID_COMPOSITE(IM_STRUCTURED_COMPOSITE(IM_TETRAHEDRON(5),3))'));
+else
+  gf_mesh_fem_set(mf,'fem',gf_fem(sprintf('FEM_PK(3,%d)', K)));
+  mim = gf_mesh_im(m, gf_integ('IM_TETRAHEDRON(5)'));
+end
+
+
+% Detect the border of the mesh
+border = gf_mesh_get(m, 'outer faces');
+% Mark it as boundary GAMMAD=1
+GAMMAD=1;
+gf_mesh_set(m, 'region', GAMMAD, border);
+if (draw_mesh)
+  figure(1);
+  gf_plot_mesh(m, 'regions', [GAMMAD], 'convexes', 'on'); % the boundary edges appear in red
+  pause(1);
+end
+
+% Interpolate the exact solution
+% Uexact = gf_mesh_fem_get(mf, 'eval', { '10*y.*(y-1).*x.*(x-1)+10*x.^5' });
+% Uexact = gf_mesh_fem_get(mf, 'eval', { 'x.*sin(2*pi*x).*sin(2*pi*y)' });
+Uexact = gf_mesh_fem_get(mf, 'eval', { 'sin(pi*x/2).*sin(pi*y/2).*sin(pi*z/2)' });
+% Opposite of its laplacian
+% F      = gf_mesh_fem_get(mf, 'eval', { '-(20*(x.^2+y.^2)-20*x-20*y+200*x.^3)' });
+% F      = gf_mesh_fem_get(mf, 'eval', { '4*pi*(2*pi*x.*sin(2*pi*x) - cos(2*pi*x)).*sin(2*pi*y)' });
+F = gf_mesh_fem_get(mf, 'eval', { '3*pi*pi*sin(pi*x/2).*sin(pi*y/2).*sin(pi*z/2)/4' });
+
+md=gf_model('real');
+gf_model_set(md, 'add fem variable', 'u', mf);
+gf_model_set(md, 'add linear generic assembly brick', mim, 'Grad_u.Grad_Test_u');
+% gf_model_set(md, 'add Laplacian brick', mim, 'u');
+gf_model_set(md, 'add initialized fem data', 'VolumicData', mf, F);
+gf_model_set(md, 'add source term brick', mim, 'u', 'VolumicData');
+gf_model_set(md, 'add initialized fem data', 'DirichletData', mf, Uexact);
+switch (dirichlet_version)
+  case 0,
+    gf_model_set(md, 'add Dirichlet condition with simplification', 'u', GAMMAD, 'DirichletData');   
+  case 1, 
+    gf_model_set(md, 'add Dirichlet condition with multipliers', mim, 'u', mf, GAMMAD, 'DirichletData');
+  case 2,
+    gf_model_set(md, 'add Dirichlet condition with penalization', mim, 'u', r, GAMMAD, 'DirichletData');
+  case 3,
+    gf_model_set(md, 'add initialized data', 'gamma0', [gamma0]);
+    expr = gf_model_get(md, 'Neumann term', 'u', GAMMAD);
+    gf_model_set(md, 'add Dirichlet condition with Nitsche method', mim, 'u', expr, 'gamma0', GAMMAD, theta, 'DirichletData');
+end
+gf_model_get(md, 'solve');
+U = gf_model_get(md, 'variable', 'u');
+if (draw)
+  figure(2);
+  subplot(2,1,1); gf_plot(mf,U,'mesh','off', 'cvlst', gf_mesh_get(m, 'outer faces'), 'refine', 4); 
+  colorbar; title('computed solution');
+
+  subplot(2,1,2); gf_plot(mf,Uexact,'mesh','on', 'cvlst', gf_mesh_get(m, 'outer faces'), 'refine', 4); 
+  colorbar;title('exact solution');
+end
+
+err = gf_compute(mf, Uexact-U, 'H1 norm', mim);
+
+disp(sprintf('H1 norm of error: %g', err));
+
+% M = gf_asm('mass matrix', mim, mf);
+% K = gf_asm('laplacian', mim, mf, mf, ones(1, gf_mesh_fem_get(mf, 'nbdof')));
+
+if (0) % Drawing the shape functions on the reference element
+  m2 = gf_mesh('empty', 3);
+  gf_mesh_set(m2, 'add convex', gf_geotrans('GT_PYRAMID(1)'), [-1 -1 0;  1, -1, 0; -1,  1, 0;  1,  1, 0;  0,  0, 1]');
+  % gf_mesh_set(m2, 'add convex', gf_geotrans('GT_PYRAMID(1)'), [-1 -1 2;  1, -1, 2; -1,  1, 2;  1,  1, 2;  0,  0, 1]');
+  % gf_mesh_set(m2, 'add convex', gf_geotrans('GT_PYRAMID(1)'), [ 1 -1 0; 1,  1, 0;   1, -1, 2;  1,  1, 2;  0,  0, 1]');
+  mf2 = gf_mesh_fem(m2,1);
+  gf_mesh_fem_set(mf2,'fem',gf_fem('FEM_PYRAMID_LAGRANGE(2)'));
+  Utest = zeros(1,gf_mesh_fem_get(mf2, 'nbdof'));
+  % gf_mesh_fem_get(mf2, 'basic dof nodes')
+  % mim2 = gf_mesh_im(m2, gf_integ('IM_PYRAMID_COMPOSITE(IM_TETRAHEDRON(2))'));
+  mim2 = gf_mesh_im(m2, gf_integ('IM_PYRAMID(IM_GAUSS_PARALLELEPIPED(3,7))'));
+  % mim2 = gf_mesh_im(m2, gf_integ('IM_PYRAMID_COMPOSITE(IM_STRUCTURED_COMPOSITE(IM_TETRAHEDRON(5),5))'));
+  format long
+  M2 = gf_asm('mass matrix', mim2, mf2)
+  K2 = gf_asm('laplacian', mim2, mf2, mf2, ones(1, gf_mesh_fem_get(mf2, 'nbdof')))
+  for i = 1:size(Utest,2)
+    Utest(i) = 1;
+    figure(3);
+    gf_plot(mf2,Utest,'mesh','on', 'cvlst', gf_mesh_get(m2, 'outer faces'), 'refine', 8); 
+    colorbar; title('shape function');
+    pause;
+    Utest(i) = 0;
+  end
+end
+
+if (0) % Drawing the shape functions on the whole mesh
+  Utest = U*0;
+  for i = 1:size(U,2)
+    Utest(i) = 1;
+    figure(3);
+    gf_plot(mf,Utest,'mesh','on', 'cvlst', gf_mesh_get(m, 'outer faces'), 'refine', 8); 
+    colorbar; title('shape function');
+    Utest(i) = 0;
+    pause;
+  end
+end
+
+if (err > 0.033)
+   error('Laplacian test: error to big');
+end
+
+
diff --git a/interface/tests/matlab/demo_large_sliding_contact.m b/interface/tests/matlab/demo_large_sliding_contact.m
index 4495665..308fd03 100644
--- a/interface/tests/matlab/demo_large_sliding_contact.m
+++ b/interface/tests/matlab/demo_large_sliding_contact.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2012-2016 Yves Renard.
+% Copyright (C) 2012-2017 Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_mesh_generation.m b/interface/tests/matlab/demo_mesh_generation.m
index 4997f46..a2805e2 100644
--- a/interface/tests/matlab/demo_mesh_generation.m
+++ b/interface/tests/matlab/demo_mesh_generation.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2011-2016 Yves Renard.
+% Copyright (C) 2011-2017 Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_mortar.m b/interface/tests/matlab/demo_mortar.m
index 0bb103c..984804b 100644
--- a/interface/tests/matlab/demo_mortar.m
+++ b/interface/tests/matlab/demo_mortar.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+% Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_nonlinear_elasticity.m b/interface/tests/matlab/demo_nonlinear_elasticity.m
index 58a66d7..709b631 100644
--- a/interface/tests/matlab/demo_nonlinear_elasticity.m
+++ b/interface/tests/matlab/demo_nonlinear_elasticity.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_nonlinear_elasticity_anim.m b/interface/tests/matlab/demo_nonlinear_elasticity_anim.m
index 217eca9..b8f8727 100644
--- a/interface/tests/matlab/demo_nonlinear_elasticity_anim.m
+++ b/interface/tests/matlab/demo_nonlinear_elasticity_anim.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_periodic_laplacian.m b/interface/tests/matlab/demo_periodic_laplacian.m
index 9c74e92..84634de 100644
--- a/interface/tests/matlab/demo_periodic_laplacian.m
+++ b/interface/tests/matlab/demo_periodic_laplacian.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
@@ -42,7 +42,7 @@ gf_mesh_fem_set(mf,'fem',gf_fem('FEM_QK(2,2)'));
 
 % create a mesh_fem of for a field of dimension 1 for the multiplier
 mf_lambda = gf_mesh_fem(m,1);
-% assign the Q1 fem to all convexes of the mesh_fem (only the boundary will be used),
+% assign the Q1 fem to all elements of the mesh_fem (only the boundary will be used),
 gf_mesh_fem_set(mf_lambda,'fem',gf_fem('FEM_QK(2,1)'));
 
 % Integration which will be used
diff --git a/interface/tests/matlab/demo_plasticity.m b/interface/tests/matlab/demo_plasticity.m
index c942340..78ff3d1 100644
--- a/interface/tests/matlab/demo_plasticity.m
+++ b/interface/tests/matlab/demo_plasticity.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2010-2016 Amandine Cottaz, Yves Renard, Farshid Dabaghi.
+% Copyright (C) 2010-2017 Amandine Cottaz, Yves Renard, Farshid Dabaghi.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_refine.m b/interface/tests/matlab/demo_refine.m
index e28b0c4..0a3008b 100644
--- a/interface/tests/matlab/demo_refine.m
+++ b/interface/tests/matlab/demo_refine.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Yves Renard, Julien Pommier.
+% Copyright (C) 2005-2017 Yves Renard, Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
@@ -73,7 +73,7 @@ for step=1:8,
   U = gf_model_get(md, 'variable', 'u');
   
   VM = gf_model_get(md, 'compute isotropic linearized Von Mises or Tresca', 'u', 'lambda', 'mu', mfdu);
-
+  
   if (N==3) opt = {'cvlst', get(m,'outer_faces')}; 
   else opt = {}; end;
   
@@ -97,7 +97,7 @@ for step=1:8,
     pause(1.5);
   end
   set(m, 'refine', find(ERR > 2e-6));
-  set(m, 'optimize structure');
+  set(m, 'optimize structure', false);
   norm(E)
 end;
 
diff --git a/interface/tests/matlab/demo_static_contact.m b/interface/tests/matlab/demo_static_contact.m
index adfbf42..b77de87 100644
--- a/interface/tests/matlab/demo_static_contact.m
+++ b/interface/tests/matlab/demo_static_contact.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2009-2016 Yves Renard.
+% Copyright (C) 2009-2017 Yves Renard.
 %
 % This file is a part of GetFEM++
 %
@@ -364,7 +364,7 @@ end
 % Solve the problem
 if (~solved)
   gf_model_get(md, 'test tangent matrix', 1e-6, 10, 0.1);
-  gf_model_get(md, 'solve', 'max_res', 1E-9, 'very noisy', 'max_iter', niter); % ,  'lsearch', 'simplest'); % , 'with pseudo potential');
+  gf_model_get(md, 'solve', 'max_res', 1E-9, 'very noisy', 'max_iter', niter); % ,  'lsearch', 'simplest');
 end;
 
 U = gf_model_get(md, 'variable', 'u');
diff --git a/interface/tests/matlab/demo_step_by_step.m b/interface/tests/matlab/demo_step_by_step.m
index 9f3afa3..d09de67 100644
--- a/interface/tests/matlab/demo_step_by_step.m
+++ b/interface/tests/matlab/demo_step_by_step.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_stokes_3D_tank.m b/interface/tests/matlab/demo_stokes_3D_tank.m
index 41efc57..fa3b62f 100644
--- a/interface/tests/matlab/demo_stokes_3D_tank.m
+++ b/interface/tests/matlab/demo_stokes_3D_tank.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_stokes_3D_tank_draw.m b/interface/tests/matlab/demo_stokes_3D_tank_draw.m
index acd8365..38a7dc8 100644
--- a/interface/tests/matlab/demo_stokes_3D_tank_draw.m
+++ b/interface/tests/matlab/demo_stokes_3D_tank_draw.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_structural_optimization.m b/interface/tests/matlab/demo_structural_optimization.m
index d13d4dd..75052c0 100644
--- a/interface/tests/matlab/demo_structural_optimization.m
+++ b/interface/tests/matlab/demo_structural_optimization.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2009-2016 Alassane SY, Yves Renard.
+% Copyright (C) 2009-2017 Alassane SY, Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_thermo_elasticity_electrical_coupling.m b/interface/tests/matlab/demo_thermo_elasticity_electrical_coupling.m
index a778f4b..a637069 100644
--- a/interface/tests/matlab/demo_thermo_elasticity_electrical_coupling.m
+++ b/interface/tests/matlab/demo_thermo_elasticity_electrical_coupling.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2015-2016 Yves Renard.
+% Copyright (C) 2015-2017 Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_topological_optimization.m b/interface/tests/matlab/demo_topological_optimization.m
index 5ee89b0..e7376d0 100644
--- a/interface/tests/matlab/demo_topological_optimization.m
+++ b/interface/tests/matlab/demo_topological_optimization.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2009-2016 Alassane SY, Yves Renard.
+% Copyright (C) 2009-2017 Alassane SY, Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_tripod.m b/interface/tests/matlab/demo_tripod.m
index ce66bf1..78ef090 100644
--- a/interface/tests/matlab/demo_tripod.m
+++ b/interface/tests/matlab/demo_tripod.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_tripod_alt.m b/interface/tests/matlab/demo_tripod_alt.m
index 0b9973c..07e0c38 100644
--- a/interface/tests/matlab/demo_tripod_alt.m
+++ b/interface/tests/matlab/demo_tripod_alt.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_tripod_slice_anim.m b/interface/tests/matlab/demo_tripod_slice_anim.m
index e381c71..7901539 100644
--- a/interface/tests/matlab/demo_tripod_slice_anim.m
+++ b/interface/tests/matlab/demo_tripod_slice_anim.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_wave2D.m b/interface/tests/matlab/demo_wave2D.m
index 6d61dc1..0df1ed9 100644
--- a/interface/tests/matlab/demo_wave2D.m
+++ b/interface/tests/matlab/demo_wave2D.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_wave2D_alt.m b/interface/tests/matlab/demo_wave2D_alt.m
index 73ed140..091cd06 100644
--- a/interface/tests/matlab/demo_wave2D_alt.m
+++ b/interface/tests/matlab/demo_wave2D_alt.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_wave_equation.m b/interface/tests/matlab/demo_wave_equation.m
index 5d12c65..5a6760d 100644
--- a/interface/tests/matlab/demo_wave_equation.m
+++ b/interface/tests/matlab/demo_wave_equation.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2008-2016 Yves Renard.
+% Copyright (C) 2008-2017 Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/demo_wheel_contact.m b/interface/tests/matlab/demo_wheel_contact.m
index f29e5ba..145bac5 100644
--- a/interface/tests/matlab/demo_wheel_contact.m
+++ b/interface/tests/matlab/demo_wheel_contact.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2015-2016 Yves Renard.
+% Copyright (C) 2015-2017 Yves Renard.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/private/Makefile.in b/interface/tests/matlab/private/Makefile.in
index 09ceec1..d7b413b 100644
--- a/interface/tests/matlab/private/Makefile.in
+++ b/interface/tests/matlab/private/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -15,17 +15,7 @@
 @SET_MAKE@
 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,6 +79,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = interface/tests/matlab/private
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -104,7 +96,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -158,7 +149,6 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -226,7 +216,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -259,8 +248,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -341,7 +332,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -368,6 +358,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/tests/matlab/private/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/tests/matlab/private/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -581,8 +572,6 @@ uninstall-am: uninstall-toolboxSCRIPTS
 	mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
 	uninstall-am uninstall-toolboxSCRIPTS
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/interface/tests/matlab/private/asserterr.m b/interface/tests/matlab/private/asserterr.m
index 5a77ef6..da1f55d 100644
--- a/interface/tests/matlab/private/asserterr.m
+++ b/interface/tests/matlab/private/asserterr.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2003-2016 Julien Pommier.
+% Copyright (C) 2003-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/private/gfassert.m b/interface/tests/matlab/private/gfassert.m
index 60e44f7..f20305f 100644
--- a/interface/tests/matlab/private/gfassert.m
+++ b/interface/tests/matlab/private/gfassert.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2003-2016 Julien Pommier.
+% Copyright (C) 2003-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/test_argyris.m b/interface/tests/matlab/test_argyris.m
index 2f40fbf..c03fff5 100644
--- a/interface/tests/matlab/test_argyris.m
+++ b/interface/tests/matlab/test_argyris.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Yves Renard, Julien Pommier.
+% Copyright (C) 2005-2017 Yves Renard, Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/tripod_anim.m b/interface/tests/matlab/tripod_anim.m
index f9ebe35..13fd556 100644
--- a/interface/tests/matlab/tripod_anim.m
+++ b/interface/tests/matlab/tripod_anim.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/matlab/tutorial1.m b/interface/tests/matlab/tutorial1.m
index 09b5cc3..e6ff588 100644
--- a/interface/tests/matlab/tutorial1.m
+++ b/interface/tests/matlab/tutorial1.m
@@ -1,4 +1,4 @@
-% Copyright (C) 2005-2016 Julien Pommier.
+% Copyright (C) 2005-2017 Julien Pommier.
 %
 % This file is a part of GetFEM++
 %
diff --git a/interface/tests/meshes/Makefile.am b/interface/tests/meshes/Makefile.am
old mode 100755
new mode 100644
index 1f740bb..1ab0c63
--- a/interface/tests/meshes/Makefile.am
+++ b/interface/tests/meshes/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 EXTRA_DIST= \
 	tank_quadratic_2500.GiD.msh \
         holed_disc_with_quadratic_2D_triangles.msh \
diff --git a/interface/tests/meshes/Makefile.in b/interface/tests/meshes/Makefile.in
index ee19cbd..c69562a 100644
--- a/interface/tests/meshes/Makefile.in
+++ b/interface/tests/meshes/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,18 +14,25 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -89,6 +96,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = interface/tests/meshes
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -104,7 +113,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -158,7 +166,6 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -226,7 +233,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -259,8 +265,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -341,7 +349,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -373,6 +380,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/tests/meshes/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/tests/meshes/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -586,8 +594,6 @@ uninstall-am: uninstall-meshesSCRIPTS
 	ps ps-am tags-am uninstall uninstall-am \
 	uninstall-meshesSCRIPTS
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/interface/tests/meshes/holed_disc_with_quadratic_2D_triangles.msh b/interface/tests/meshes/holed_disc_with_quadratic_2D_triangles.msh
old mode 100755
new mode 100644
diff --git a/interface/tests/meshes/tank_quadratic_2500.GiD.msh b/interface/tests/meshes/tank_quadratic_2500.GiD.msh
old mode 100755
new mode 100644
diff --git a/interface/tests/meshes/tripod.GiD.msh b/interface/tests/meshes/tripod.GiD.msh
old mode 100755
new mode 100644
diff --git a/interface/tests/meshes/tube_2D_spline.GiD.msh b/interface/tests/meshes/tube_2D_spline.GiD.msh
old mode 100755
new mode 100644
diff --git a/interface/tests/python/Makefile.am b/interface/tests/python/Makefile.am
index ad66400..150597e 100644
--- a/interface/tests/python/Makefile.am
+++ b/interface/tests/python/Makefile.am
@@ -1,3 +1,27 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+if QHULL
+optpy = check_levelset.py
+else
+optpy =
+endif
+
+
 EXTRA_DIST= 						\
 	check_export.py 				\
 	check_global_functions.py			\
@@ -5,7 +29,9 @@ EXTRA_DIST= 						\
 	demo_crack.py 					\
 	demo_fictitious_domains.py 			\
 	demo_laplacian.py 				\
+	demo_laplacian_pyramid.py			\
 	demo_laplacian_DG.py 				\
+	demo_laplacian_aposteriori.py			\
 	demo_mortar.py 					\
 	demo_plasticity.py              		\
 	demo_plate.py 					\
@@ -29,12 +55,12 @@ TESTS = 						\
 	check_global_functions.py			\
 	demo_wave.py					\
 	demo_laplacian.py				\
-	check_levelset.py
+	$(optpy)
 
 AM_TESTS_ENVIRONMENT = \
 	export PYTHONPATH=$(top_builddir)/interface/src/python; \
 	export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(top_builddir)/src/.libs;
-LOG_COMPILER = python
+LOG_COMPILER = $(PYTHON)
 endif
 
 CLEANFILES = *.vtk *.dx *.pyc tank_3D* tripod* plate* *.pos *.dx
diff --git a/interface/tests/python/Makefile.in b/interface/tests/python/Makefile.in
index 92c0cab..c9b84ca 100644
--- a/interface/tests/python/Makefile.in
+++ b/interface/tests/python/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -87,7 +94,12 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
+ at BUILDPYTHON_TRUE@TESTS = check_export.py check_global_functions.py \
+ at BUILDPYTHON_TRUE@	demo_wave.py demo_laplacian.py \
+ at BUILDPYTHON_TRUE@	$(am__EXEEXT_1)
 subdir = interface/tests/python
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -103,7 +115,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -312,6 +323,7 @@ am__set_TESTS_bases = \
   bases=`echo $$bases`
 RECHECK_LOGS = $(TEST_LOGS)
 AM_RECURSIVE_TARGETS = check recheck
+ at QHULL_TRUE@am__EXEEXT_1 = check_levelset.py
 TEST_SUITE_LOG = test-suite.log
 TEST_EXTENSIONS = @EXEEXT@ .test
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
@@ -332,8 +344,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs \
-	$(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -401,7 +411,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -434,8 +443,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -516,7 +527,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -525,6 +535,8 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
+ at QHULL_FALSE@optpy = 
+ at QHULL_TRUE@optpy = check_levelset.py
 EXTRA_DIST = \
 	check_export.py 				\
 	check_global_functions.py			\
@@ -532,7 +544,9 @@ EXTRA_DIST = \
 	demo_crack.py 					\
 	demo_fictitious_domains.py 			\
 	demo_laplacian.py 				\
+	demo_laplacian_pyramid.py			\
 	demo_laplacian_DG.py 				\
+	demo_laplacian_aposteriori.py			\
 	demo_mortar.py 					\
 	demo_plasticity.py              		\
 	demo_plate.py 					\
@@ -550,18 +564,11 @@ EXTRA_DIST = \
 	demo_wave_equation.py				\
 	getfem_tvtk.py
 
- at BUILDPYTHON_TRUE@TESTS = \
- at BUILDPYTHON_TRUE@	check_export.py					\
- at BUILDPYTHON_TRUE@	check_global_functions.py			\
- at BUILDPYTHON_TRUE@	demo_wave.py					\
- at BUILDPYTHON_TRUE@	demo_laplacian.py				\
- at BUILDPYTHON_TRUE@	check_levelset.py
-
 @BUILDPYTHON_TRUE at AM_TESTS_ENVIRONMENT = \
 @BUILDPYTHON_TRUE@	export PYTHONPATH=$(top_builddir)/interface/src/python; \
 @BUILDPYTHON_TRUE@	export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(top_builddir)/src/.libs;
 
- at BUILDPYTHON_TRUE@LOG_COMPILER = python
+ at BUILDPYTHON_TRUE@LOG_COMPILER = $(PYTHON)
 CLEANFILES = *.vtk *.dx *.pyc tank_3D* tripod* plate* *.pos *.dx
 all: all-am
 
@@ -579,6 +586,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/tests/python/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu interface/tests/python/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -639,7 +647,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -950,8 +958,6 @@ uninstall-am:
 	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \
 	uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/interface/tests/python/check_export.py b/interface/tests/python/check_export.py
index 9f0eb33..fc7e9f1 100644
--- a/interface/tests/python/check_export.py
+++ b/interface/tests/python/check_export.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2009 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -24,7 +24,7 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of python-getfem..
 
-  $Id: check_export.py 4035 2012-02-18 12:21:20Z renard $
+  $Id$
 """
 import getfem as gf
 import numpy as np
@@ -76,7 +76,7 @@ mf1.export_to_vtk('check_export3.vtk','ascii')
 try:
     m0.export_to_dx('check_export0.dx')
 except RuntimeError as detail:
-    print detail
+    print(detail)
 
 m1.export_to_dx('check_export0.dx','ascii','edges')
 m1.export_to_dx('check_export0.dx','ascii','append')
diff --git a/interface/tests/python/check_global_functions.py b/interface/tests/python/check_global_functions.py
index 04f5165..4e90f1b 100644
--- a/interface/tests/python/check_global_functions.py
+++ b/interface/tests/python/check_global_functions.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2009 Luis Saavedra.
+# Copyright (C) 2009-2017 Luis Saavedra.
 #
 # This file is a part of GetFEM++
 #
@@ -24,7 +24,7 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of python-getfem..
 
-  $Id: check_global_functions.py 4925 2015-03-30 16:12:19Z renard $
+  $Id$
 """
 import numpy as np
 import getfem as gf
diff --git a/interface/tests/python/check_levelset.py b/interface/tests/python/check_levelset.py
index a301f24..7c9d5fc 100644
--- a/interface/tests/python/check_levelset.py
+++ b/interface/tests/python/check_levelset.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2009 Yves Renard, Luis Saavedra.
+# Copyright (C) 2009-2017 Yves Renard, Luis Saavedra.
 #
 # This file is a part of GetFEM++
 #
@@ -24,7 +24,7 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of python-getfem..
 
-  $Id: check_levelset.py 4925 2015-03-30 16:12:19Z renard $
+  $Id$
 """
 import getfem as gf
 import numpy as np
@@ -56,7 +56,7 @@ if True:
   mls.add(ls3)
 mls.adapt()
 
-#print mls.linked_mesh()
+#print(mls.linked_mesh())
 
 lls = mls.levelsets()
 
diff --git a/interface/tests/python/demo_Mindlin_Reissner_plate.py b/interface/tests/python/demo_Mindlin_Reissner_plate.py
index 75f46c8..309fdf5 100644
--- a/interface/tests/python/demo_Mindlin_Reissner_plate.py
+++ b/interface/tests/python/demo_Mindlin_Reissner_plate.py
@@ -2,7 +2,7 @@
 # -*- coding: UTF8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2015-2015 FABRE Mathieu, SECK Mamadou, DALLERIT Valentin,
+# Copyright (C) 2015-2017 FABRE Mathieu, SECK Mamadou, DALLERIT Valentin,
 #                         Yves Renard.
 #
 # This file is a part of GetFEM++
diff --git a/interface/tests/python/demo_crack.py b/interface/tests/python/demo_crack.py
index 879e3ba..57a1524 100644
--- a/interface/tests/python/demo_crack.py
+++ b/interface/tests/python/demo_crack.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2009-2015 Luis Saavedra, Yves Renard.
+# Copyright (C) 2009-2017 Luis Saavedra, Yves Renard.
 #
 # This file is a part of GetFEM++
 #
@@ -24,7 +24,7 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of GetFEM++.
 
-  $Id: demo_crack.py 5102 2015-10-18 18:20:28Z logari81 $
+  $Id$
 """
 try:
   import getfem as gf
@@ -33,7 +33,7 @@ except ImportError:
   sys.path.append('../../src/python/')
   import getfem as gf
 else:
-  print "module getfem not found!"
+  print("module getfem not found!")
 
 import numpy as np
 import math
@@ -187,5 +187,5 @@ VM = md.compute_isotropic_linearized_Von_Mises_or_Tresca('u_cut', 'lambda', 'mu'
 
 mfv.export_to_pos('crack.pos', V, 'V', Ve, 'Ve', mfvm, VM, 'Von Mises')
 
-print 'You can view the solution with (for example):'
-print 'gmsh crack.pos'
+print('You can view the solution with (for example):')
+print('gmsh crack.pos')
diff --git a/interface/tests/python/demo_fictitious_domains.py b/interface/tests/python/demo_fictitious_domains.py
index bb95478..67302af 100644
--- a/interface/tests/python/demo_fictitious_domains.py
+++ b/interface/tests/python/demo_fictitious_domains.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2009 Yves Renard, Luis Saavedra.
+# Copyright (C) 2009-2017 Yves Renard, Luis Saavedra.
 #
 # This file is a part of GetFEM++
 #
@@ -25,7 +25,7 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of GetFEM++.
 
-  $Id: demo_fictitious_domains.py 3226 2009-10-14 01:28:01Z lsaavedr $
+  $Id$
 """
 import getfem as gf
 import numpy as np
@@ -51,8 +51,8 @@ y = P[1,:]
 ULS = 1000*np.ones(x.shape)
 
 if True:
-  for ix in xrange(0,5):
-    for iy in xrange(0,5):
+  for ix in range(0,5):
+    for iy in range(0,5):
       xc = (ix/4) * 0.8 - 0.4
       yc = (iy/4) * 0.8 - 0.4
       if (iy%2)==1:
@@ -62,7 +62,7 @@ if True:
       R = 0.03 + 0.005*iy
       ULS = np.minimum(ULS, ((x - xc)**2 + (y - yc)**2) - R**2);
 else:
-  for i in xrange(8):
+  for i in range(8):
     xc = rand() - 0.5
     yc = rand() - 0.5
     R = rand() * 0.09 + 0.02
@@ -71,7 +71,7 @@ ls.set_values(ULS)
 
 ULS2 = 1000*np.ones(x.shape);
 ULS2s = 1000*np.ones(x.shape);
-for i in xrange(1):
+for i in range(1):
   xc = 0.0 # rand() - 0.5
   yc = 0.0 # rand() - 0.5
   theta = np.pi/3 # np.pi*rand()
@@ -132,5 +132,5 @@ mfdu.export_to_pos('vm.pos', VM, 'Von Mises', mfu0, U, 'deformation')
 
 mf_ls.export_to_pos('ls.pos',ls.values(0),'ls values 0')
 
-print 'You can view the solution with (for instance):'
-print 'gmsh vm.pos ls.pos'
+print('You can view the solution with (for instance):')
+print('gmsh vm.pos ls.pos')
diff --git a/interface/tests/python/demo_laplacian.py b/interface/tests/python/demo_laplacian.py
index 6a2693f..377af37 100644
--- a/interface/tests/python/demo_laplacian.py
+++ b/interface/tests/python/demo_laplacian.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2015 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -24,7 +24,7 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of GetFEM++.
 
-  $Id: demo_laplacian.py 5193 2015-12-16 14:07:05Z renard $
+  $Id$
 """
 # Import basic modules
 import getfem as gf
@@ -126,16 +126,16 @@ md.solve()
 U = md.variable('u')
 L2error = gf.compute(mfu, U-Ue, 'L2 norm', mim)
 H1error = gf.compute(mfu, U-Ue, 'H1 norm', mim)
-print 'Error in L2 norm : ', L2error
-print 'Error in H1 norm : ', H1error
+print('Error in L2 norm : ', L2error)
+print('Error in H1 norm : ', H1error)
 
 # Export data
 mfu.export_to_pos('laplacian.pos', Ue,'Exact solution',
                                     U,'Computed solution')
-print 'You can view the solution with (for example):'
-print 'gmsh laplacian.pos'
+print('You can view the solution with (for example):')
+print('gmsh laplacian.pos')
 
 
 if (H1error > 1e-3):
-    print 'Error too large !'
+    print('Error too large !')
     exit(1)
diff --git a/interface/tests/python/demo_laplacian_DG.py b/interface/tests/python/demo_laplacian_DG.py
index 1462e2a..dccc575 100644
--- a/interface/tests/python/demo_laplacian_DG.py
+++ b/interface/tests/python/demo_laplacian_DG.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # Python GetFEM++ interface
 #
-# Copyright (C) 2015-2015 Yves Renard
+# Copyright (C) 2015-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
@@ -83,7 +83,7 @@ if (verify_neighbour_computation):
   TEST_FACES=5
   adjf = m.adjacent_face(42, 0);
   if (len(adjf) != 2):
-    print ('No adjacent edge found, change the element number')
+    print('No adjacent edge found, change the element number')
     exit(1)
   m.set_region(TEST_FACES, np.array([[42,adjf[0][0]], [0,adjf[1][0]]]));
   
@@ -156,14 +156,14 @@ md.solve()
 U = md.variable('u')
 L2error = gf.compute(mfu, U-Ue, 'L2 norm', mim)
 H1error = gf.compute(mfu, U-Ue, 'H1 norm', mim)
-print 'Error in L2 norm : ', L2error
-print 'Error in H1 norm : ', H1error
+print('Error in L2 norm : ', L2error)
+print('Error in H1 norm : ', H1error)
 
 # Export data
 mfu.export_to_pos('laplacian.pos', Ue,'Exact solution',
                                     U,'Computed solution')
-print 'You can view the solution with (for example):'
-print 'gmsh laplacian.pos'
+print('You can view the solution with (for example):')
+print('gmsh laplacian.pos')
 
 if (verify_neighbour_computation):
   A=gf.asm('generic', mim, 1, 'u*Test_u*(Normal.Normal)', TEST_FACES, md)
@@ -173,10 +173,10 @@ if (verify_neighbour_computation):
   B=gf.asm('generic', mim, 1, '(Interpolate(Grad_u,neighbour_elt).Normal)*(Interpolate(Grad_Test_u,neighbour_elt).Normal)', TEST_FACES, md)
   err_v = err_v + np.linalg.norm(A-B)
   if (err_v > 1E-13):
-    print 'Test on neighbour element computation: error to big: ', err_v
+    print('Test on neighbour element computation: error to big: ', err_v)
     exit(1)
   
 if (H1error > 1e-3):
-    print 'Error too large !'
+    print('Error too large !')
     exit(1)
 
diff --git a/interface/tests/python/demo_laplacian_aposteriori.py b/interface/tests/python/demo_laplacian_aposteriori.py
new file mode 100644
index 0000000..ea229cd
--- /dev/null
+++ b/interface/tests/python/demo_laplacian_aposteriori.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Python GetFEM++ interface
+#
+# Copyright (C) 2015-2017 Yves Renard
+#
+# This file is a part of GetFEM++
+#
+# GetFEM++  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 2.1 of the License,  or
+# (at your option) any later version.
+# This program  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  this program;  if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+############################################################################
+"""  2D Poisson problem test.
+
+  Poisson problem solved a refined with an a posteriori error estimate
+  Example of integration on edges of normal derivative jump.
+
+  $Id: demo_laplacian_aposteriori.py 4429 2013-10-01 13:15:15Z renard $
+"""
+# Import basic modules
+import getfem as gf
+import numpy as np
+
+## Parameters
+h = 4.                             # Mesh parameter.
+Dirichlet_with_multipliers = True  # Dirichlet condition with multipliers
+                                   # or penalization
+dirichlet_coefficient = 1e10       # Penalization coefficient
+export_mesh = True                 # Draw the mesh after mesh generation or not
+
+
+# Create a mesh
+mo1 = gf.MesherObject('rectangle', [0., 50.], [100., 100.])
+mo2 = gf.MesherObject('rectangle', [50., 0.], [100., 100.])
+mo3 = gf.MesherObject('union', mo1, mo2)
+mo4 = gf.MesherObject('ball', [25., 75], 8.)
+mo5 = gf.MesherObject('ball', [75., 25.], 8.)
+mo6 = gf.MesherObject('ball', [75., 75.], 8.)
+mo7 = gf.MesherObject('union', mo4, mo5, mo6)
+mo  = gf.MesherObject('set minus', mo3, mo7)
+
+gf.util('trace level', 2)   # No trace for mesh generation
+mesh = gf.Mesh('generate', mo, h, 3)
+
+#
+# Boundary selection
+#
+fb1 = mesh.outer_faces_with_direction([-1., 0.], 0.01) # Left   (Dirichlet)
+fb2 = mesh.outer_faces_with_direction([0., -1.], 0.01) # Bottom (Neumann)
+fb3 = mesh.outer_faces_in_box([-1., 10.], [101., 101.]) 
+fb4 = mesh.outer_faces_in_box([10., -1.], [101., 101.]) 
+LEFT_BOUND=1; BOTTOM_BOUND=2; AUX_BOUND1 = 3; AUX_BOUND2 = 4; 
+mesh.set_region(  LEFT_BOUND, fb1)
+mesh.set_region(BOTTOM_BOUND, fb2)
+mesh.set_region(  AUX_BOUND1, fb3)
+mesh.set_region(  AUX_BOUND2, fb4)
+mesh.region_subtract(  LEFT_BOUND, AUX_BOUND2)
+mesh.region_subtract(BOTTOM_BOUND, AUX_BOUND1)
+
+# Create a MeshFem for u and rhs fields of dimension 1 (i.e. a scalar field)
+mfu  = gf.MeshFem(mesh, 1)
+mfP0 = gf.MeshFem(mesh, 1)
+# Assign the discontinuous P2 fem to all convexes of the both MeshFem
+mfu.set_fem(gf.Fem('FEM_PK(2,2)'))
+mfP0.set_fem(gf.Fem('FEM_PK(2,0)'))
+
+# Integration method used
+mim = gf.MeshIm(mesh, gf.Integ('IM_TRIANGLE(4)'))
+
+# Inner edges for the computation of the normal derivative jump
+in_faces = mesh.inner_faces()
+INNER_FACES=18
+mesh.set_region(INNER_FACES, in_faces)
+
+# Model
+md = gf.Model('real')
+
+# Main unknown
+md.add_fem_variable('u', mfu)
+
+# Laplacian term on u
+md.add_Laplacian_brick(mim, 'u')
+
+# Volumic source term
+# md.add_initialized_fem_data('VolumicData', mfrhs, F1)
+# md.add_source_term_brick(mim, 'u', 'VolumicData')
+
+# Neumann condition.
+md.add_initialized_data('NeumannData', [0.001])
+md.add_source_term_brick(mim, 'u', 'NeumannData', BOTTOM_BOUND)
+
+# Dirichlet condition on the left.
+if (Dirichlet_with_multipliers):
+  md.add_Dirichlet_condition_with_multipliers(mim, 'u', mfu, LEFT_BOUND)
+else:
+  md.add_Dirichlet_condition_with_penalization(mim, 'u', dirichlet_coefficient,
+                                               LEFT_BOUND)
+
+for refiter in range(5):
+    
+    if (export_mesh):
+      mesh.export_to_vtk('mesh%d.vtk' % refiter)
+    
+    print('\nYou can view the mesh for instance with')
+    print('mayavi2 -d mesh%d.vtk -f ExtractEdges -m Surface \n'%refiter)
+    
+    # Assembly of the linear system and solve.
+    md.solve()
+    
+    # Main unknown
+    U = md.variable('u')
+    
+    # Residual a posteriori estimator
+    
+    grad_jump = '( (Grad_u-Interpolate(Grad_u,neighbour_elt)).Normal )'
+
+    bulkresidual = 'sqr(element_size*Trace(Hess_u))*Test_psi'
+    edgeresidual = '0.25*element_size*sqr(%s)*(Test_psi + Interpolate(Test_psi,neighbour_elt))'%grad_jump
+
+    ETA1tmp = gf.asm('generic',mim,1,bulkresidual,-1,md,'psi',1,mfP0,np.zeros(mfP0.nbdof()))
+    ETA1 = ETA1tmp [ ETA1tmp.size - mfP0.nbdof() : ETA1tmp.size ]
+    ETA2tmp = gf.asm('generic',mim,1,edgeresidual,INNER_FACES,md,'psi',1,mfP0,np.zeros(mfP0.nbdof()))
+    ETA2 = ETA2tmp [ ETA2tmp.size - mfP0.nbdof() : ETA2tmp.size ]
+    ETA  = np.sqrt ( ETA1 + ETA2 )
+    
+    # Export data
+    mfu.export_to_pos('laplacian%d.pos'%refiter, U, 'Computed solution')
+    print('You can view the solution with (for example):')
+    print('gmsh laplacian%d.pos'%refiter)
+    
+    mfP0.export_to_pos('eta1_%d.pos'%refiter, ETA1, 'Bulk residual')
+    print('You can view eta1 with (for example):')
+    print('gmsh eta1_%d.pos'%refiter)
+    
+    mfP0.export_to_pos('eta2_%d.pos'%refiter, ETA2, 'Edge residual')
+    print('You can view eta2 with (for example):')
+    print('gmsh eta2_%d.pos'%refiter)
+    
+    mfu.export_to_vtk('laplacian%d.vtk'%refiter, mfu, U, 'u', mfP0, ETA1, 'eta1', mfP0, ETA2, 'eta2')
+    print('mayavi2 -d laplacian%d.vtk -f WarpScalar -m Surface'%refiter)
+    
+    # Refine the mesh
+    dd=mfP0.basic_dof_from_cvid()
+    
+    ETAElt = np.zeros(dd[0].size)
+    for i in range(dd[0].size):
+        ETAElt[i] = ETA[ dd[0][i] ] 
+    
+    mesh.refine(np.where( ETAElt > 0.6*np.max(ETA) ))
+    mesh.optimize_structure()
+
+
+
+
+
+
+
diff --git a/interface/tests/python/demo_laplacian.py b/interface/tests/python/demo_laplacian_pyramid.py
similarity index 68%
copy from interface/tests/python/demo_laplacian.py
copy to interface/tests/python/demo_laplacian_pyramid.py
index 6a2693f..50abe33 100644
--- a/interface/tests/python/demo_laplacian.py
+++ b/interface/tests/python/demo_laplacian_pyramid.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2015 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -19,36 +19,54 @@
 # Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 #
 ############################################################################
-"""  2D Poisson problem test.
+"""  3D Poisson problem test with pyramidal elements.
 
   This program is used to check that python-getfem is working. This is
   also a good example of use of GetFEM++.
 
-  $Id: demo_laplacian.py 5193 2015-12-16 14:07:05Z renard $
+  This programs aims at verifying the convergence on a Poisson problem
+  with 3D pyramidal finite element.
+
+  $Id$
 """
+
 # Import basic modules
 import getfem as gf
 import numpy as np
 
+export_mesh = True;
+
 ## Parameters
-NX = 100                           # Mesh parameter.
+NX = 10                            # Mesh parameter.
 Dirichlet_with_multipliers = True  # Dirichlet condition with multipliers
                                    # or penalization
 dirichlet_coefficient = 1e10       # Penalization coefficient
 
 # Create a simple cartesian mesh
-m = gf.Mesh('regular_simplices', np.arange(0,1+1./NX,1./NX),
-            np.arange(0,1+1./NX,1./NX))
+m = gf.Mesh('pyramidal', np.arange(0,1+1./NX,1./NX),
+            np.arange(0,1+1./NX,1./NX), np.arange(0,1+1./NX,1./NX) )
+# m = gf.Mesh('regular_simplices', np.arange(0,1+1./NX,1./NX),
+#            np.arange(0,1+1./NX,1./NX), np.arange(0,1+1./NX,1./NX) )
 
 # Create a MeshFem for u and rhs fields of dimension 1 (i.e. a scalar field)
 mfu   = gf.MeshFem(m, 1)
 mfrhs = gf.MeshFem(m, 1)
-# assign the P2 fem to all convexes of the both MeshFem
-mfu.set_fem(gf.Fem('FEM_PK(2,2)'))
-mfrhs.set_fem(gf.Fem('FEM_PK(2,2)'))
+# assign the Lagrange linear fem to all pyramids of the both MeshFem
+mfu.set_fem(gf.Fem('FEM_PYRAMID_LAGRANGE(2)'))
+mfrhs.set_fem(gf.Fem('FEM_PYRAMID_LAGRANGE(2)'))
+# mfu.set_fem(gf.Fem('FEM_PK(3,1)'))
+# mfrhs.set_fem(gf.Fem('FEM_PK(3,1)'))
+
+if (export_mesh):
+  m.export_to_vtk('mesh.vtk');
+  print('\nYou can view the mesh for instance with');
+  print('mayavi2 -d mesh.vtk -f ExtractEdges -m Surface \n');
+
 
 #  Integration method used
-mim = gf.MeshIm(m, gf.Integ('IM_TRIANGLE(4)'))
+# mim = gf.MeshIm(m, gf.Integ('IM_PYRAMID_COMPOSITE(IM_TETRAHEDRON(6))'))
+mim = gf.MeshIm(m, gf.Integ('IM_PYRAMID(IM_GAUSS_PARALLELEPIPED(3,3))'))
+# mim = gf.MeshIm(m, gf.Integ('IM_TETRAHEDRON(5)'))
 
 # Boundary selection
 flst  = m.outer_faces()
@@ -72,7 +90,7 @@ Ue = mfu.eval('y*(y-1)*x*(x-1)+x*x*x*x*x')
 
 # Interpolate the source term
 F1 = mfrhs.eval('-(2*(x*x+y*y)-2*x-2*y+20*x*x*x)')
-F2 = mfrhs.eval('[y*(y-1)*(2*x-1) + 5*x*x*x*x, x*(x-1)*(2*y-1)]')
+F2 = mfrhs.eval('[y*(y-1)*(2*x-1) + 5*x*x*x*x, x*(x-1)*(2*y-1), 0]')
 
 # Model
 md = gf.Model('real')
@@ -115,7 +133,7 @@ else:
   md.add_Dirichlet_condition_with_penalization(mim, 'u', dirichlet_coefficient,
                                                DIRICHLET_BOUNDARY_NUM2,
                                                'DirichletData')
-gf.memstats()
+# gf.memstats()
 # md.listvar()
 # md.listbricks()
 
@@ -126,16 +144,22 @@ md.solve()
 U = md.variable('u')
 L2error = gf.compute(mfu, U-Ue, 'L2 norm', mim)
 H1error = gf.compute(mfu, U-Ue, 'H1 norm', mim)
-print 'Error in L2 norm : ', L2error
-print 'Error in H1 norm : ', H1error
+print('Error in L2 norm : ', L2error)
+print('Error in H1 norm : ', H1error)
+UU = np.zeros(U.size);
+UU[4] = 1.;
 
 # Export data
-mfu.export_to_pos('laplacian.pos', Ue,'Exact solution',
-                                    U,'Computed solution')
-print 'You can view the solution with (for example):'
-print 'gmsh laplacian.pos'
+mfu.export_to_pos('laplacian.pos', Ue, 'Exact solution',
+                  U, 'Computed solution', UU, 'Test field')
+print('You can view the solution with (for example):')
+print('gmsh laplacian.pos')
+
+mfu.export_to_vtk('laplacian.vtk', mfu, Ue, 'Exact solution', mfu, U, 'Computed solution', mfu, UU, 'Test field');
+print('\nYou can view the solution for instance with');
+print('mayavi2 -d laplacian.vtk -m Surface \n');
 
 
-if (H1error > 1e-3):
-    print 'Error too large !'
+if (H1error > 0.09):
+    print('Error too large !')
     exit(1)
diff --git a/interface/tests/python/demo_mortar.py b/interface/tests/python/demo_mortar.py
index b13e507..045911e 100644
--- a/interface/tests/python/demo_mortar.py
+++ b/interface/tests/python/demo_mortar.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2011 Yves Renard.
+# Copyright (C) 2011-2017 Yves Renard.
 #
 # This file is a part of GetFEM++
 #
diff --git a/interface/tests/python/demo_nonlinear_elasticity.py b/interface/tests/python/demo_nonlinear_elasticity.py
index 5f14782..6d2c6ab 100644
--- a/interface/tests/python/demo_nonlinear_elasticity.py
+++ b/interface/tests/python/demo_nonlinear_elasticity.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2012-2016 Yves Renard.
+# Copyright (C) 2012-2017 Yves Renard.
 #
 # This file is a part of GetFEM++
 #
@@ -30,7 +30,7 @@ gf.util_trace_level(1)
 dirichlet_version = 2          # 1 = simplification, 2 = penalisation
 test_tangent_matrix = False    # Test or not tangent system validity
 incompressible = False;        # Incompressibility option
-explicit_potential = True;     # Elasticity law with explicit potential
+explicit_potential = False;    # Elasticity law with explicit potential
 
 # lawname = 'Ciarlet Geymonat'
 # params = [1.,1.,0.25]
@@ -81,7 +81,7 @@ md.add_initialized_data('params', params)
 if (not(explicit_potential)):
     md.add_finite_strain_elasticity_brick(mim, lawname, 'u', 'params')
 else:
-    print "Explicit elastic potential"
+    print("Explicit elastic potential")
     K = 1.2; mu = 3.0;
     _F_ = "(Id(3)+Grad_u)"
     _J_= "Det{F}".format(F=_F_)
diff --git a/interface/tests/python/demo_plasticity.py b/interface/tests/python/demo_plasticity.py
index 6514a4d..c2baa7a 100644
--- a/interface/tests/python/demo_plasticity.py
+++ b/interface/tests/python/demo_plasticity.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2016 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -25,7 +25,7 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of GetFEM++.
 
-  $Id: demo_plasticity.py 5359 2016-08-01 08:53:57Z logari81 $
+  $Id$
 """
 
 import getfem as gf
@@ -36,7 +36,7 @@ with_graphics=True
 try:
     import getfem_tvtk
 except:
-    print "\n** Could NOT import getfem_tvtk -- graphical output disabled **\n"
+    print("\n** Could NOT import getfem_tvtk -- graphical output disabled **\n")
     import time
     time.sleep(2)
     with_graphics=False
@@ -94,9 +94,9 @@ md.add_Dirichlet_condition_with_multipliers(mim, 'u', mfu, 1)
 F=np.array([[0,-4.],[0, -5.], [0, -4.], [0, 2.], [0, 0]])
 nbstep = F.shape[0]
 
-print 'nbstep:', nbstep
+print('nbstep:', nbstep)
 for step in range(0, nbstep):
-    print 'step %d' % (step,)
+    print('step %d' % (step,))
     md.set_variable('VolumicData', [F[step,0],F[step,1]])
     md.solve('noisy', 'lsearch', 'simplest',  'alpha min', 0.8, 'max_iter', 100, 'max_res', 1e-6)
     U = md.variable('u')
@@ -111,5 +111,5 @@ for step in range(0, nbstep):
     if with_graphics:
         fig = getfem_tvtk.Figure()
         fig.show(mfu, deformation=U, deformation_scale=1, data=(mfdu,VM))
-        print "Press Q to continue.."
+        print("Press Q to continue..")
         fig.loop()
diff --git a/interface/tests/python/demo_plate.py b/interface/tests/python/demo_plate.py
index 24b325f..d8a26ce 100644
--- a/interface/tests/python/demo_plate.py
+++ b/interface/tests/python/demo_plate.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python
-# -*- coding: UTF8 -*-
+# -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2015 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -24,7 +24,7 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of GetFEM++.
 
-  $Id: demo_plate.py 4918 2015-03-28 15:57:20Z renard $
+  $Id$
 """
 import getfem as gf
 import numpy as np
@@ -78,9 +78,9 @@ md.add_Dirichlet_condition_with_multipliers(mim, 'u3', mfu3, SIMPLE_SUPPORT_BOUN
                                              
 
 
-print 'running solve...'
+print('running solve...')
 md.solve()
-print 'solve done!'
+print('solve done!')
 
 
 u3 = md.variable('u3')
@@ -90,7 +90,7 @@ sl=gf.Slice(('none',), mfu3, 4)
 sl.export_to_vtk('plate.vtk', mfu3, u3, 'Displacement')
 sl.export_to_pos('plate.pos', mfu3, u3, 'Displacement')
 
-print 'You can view the solution with (for example):'
-print 'mayavi2 -d plate.vtk -f WarpScalar -m Surface'
-print 'or'
-print 'gmsh plate.pos'
+print('You can view the solution with (for example):')
+print('mayavi2 -d plate.vtk -f WarpScalar -m Surface')
+print('or')
+print('gmsh plate.pos')
diff --git a/interface/tests/python/demo_static_contact.py b/interface/tests/python/demo_static_contact.py
index ea589d0..17e0808 100644
--- a/interface/tests/python/demo_static_contact.py
+++ b/interface/tests/python/demo_static_contact.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python
-# -*- coding: UTF8 -*-
+# -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2011 Yves Renard.
+# Copyright (C) 2011-2017 Yves Renard.
 #
 # This file is a part of GetFEM++
 #
@@ -243,7 +243,7 @@ elif version == 9: # The integral version, Uzawa on the augmented Lagrangian
      (mim_friction, 'u', 'obstacle', 'r', GAMMAC, 2, 'lambda_n')
 
    for ii in range(100):
-      print 'iteration %d' % (ii+1)
+      print('iteration %d' % (ii+1))
       md.solve('max_res', 1E-9, 'max_iter', niter)
       U = md.get('variable', 'u')
       lambda_n_old = lambda_n
@@ -251,7 +251,7 @@ elif version == 9: # The integral version, Uzawa on the augmented Lagrangian
       lambda_n = sol[0].transpose()
       md.set_variable('lambda_n', lambda_n)
       difff = max(abs(lambda_n-lambda_n_old))[0]/max(abs(lambda_n))[0]
-      print 'diff : %g' % difff
+      print('diff : %g' % difff)
       if difff < penalty_parameter:
          break
 
@@ -287,7 +287,7 @@ elif version == 14: # The integral version, Uzawa on the augmented Lagrangian wi
      (mim_friction, 'u', 'obstacle', 'r', 'friction_coeff', GAMMAC, 2, 'lambda')
 
    for ii in range(100):
-      print 'iteration %d' % (ii+1)
+      print('iteration %d' % (ii+1))
       md.solve('max_res', 1E-9, 'max_iter', niter)
       U = md.get('variable', 'u')
       lambda_nt_old = lambda_nt
@@ -297,7 +297,7 @@ elif version == 14: # The integral version, Uzawa on the augmented Lagrangian wi
       lambda_nt = sol[0].transpose()
       md.set_variable('lambda', lambda_nt)
       difff = max(abs(lambda_nt-lambda_nt_old))[0]/max(abs(lambda_nt))[0]
-      print 'diff : %g' % difff
+      print('diff : %g' % difff)
       if difff < penalty_parameter:
          break
  
@@ -313,7 +313,7 @@ elif version == 15:
      (mim_friction, 'u', 'obstacle', 'r', 'friction_coeff', GAMMAC)
 
 else:
-   print 'Inexistent version'
+   print('Inexistent version')
 
 # Solve the problem
 if not solved:
diff --git a/interface/tests/python/demo_step_by_step.py b/interface/tests/python/demo_step_by_step.py
index 233cfe0..d8347d0 100644
--- a/interface/tests/python/demo_step_by_step.py
+++ b/interface/tests/python/demo_step_by_step.py
@@ -1,5 +1,24 @@
 #!/usr/bin/env python
-# -*- coding: UTF8 -*-
+# -*- coding: utf-8 -*-
+# Python GetFEM++ interface
+#
+# Copyright (C) 2004-2017 Julien Pommier.
+#
+# This file is a part of GetFEM++
+#
+# GetFEM++  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 2.1 of the License,  or
+# (at your option) any later version.
+# This program  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  this program;  if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+############################################################################
 
 # import basic modules
 import getfem as gf
@@ -14,7 +33,7 @@ mf = gf.MeshFem(m, 1)
 mf.set_fem(gf.Fem('FEM_QK(2,2)'))
 
 # view the expression of its basis functions on the reference convex
-print gf.Fem('FEM_QK(2,2)').poly_str()
+print(gf.Fem('FEM_QK(2,2)').poly_str())
 
 # an exact integration will be used
 mim = gf.MeshIm(m, gf.Integ('IM_GAUSS_PARALLELEPIPED(2,4)'))
diff --git a/interface/tests/python/demo_stokes_3D_tank.py b/interface/tests/python/demo_stokes_3D_tank.py
index a765483..1567fba 100644
--- a/interface/tests/python/demo_stokes_3D_tank.py
+++ b/interface/tests/python/demo_stokes_3D_tank.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python
-# -*- coding: UTF8 -*-
+# -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2009 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -22,13 +22,13 @@
 from getfem import *
 from numpy import *
 
-print '3D stokes demonstration on a quadratic mesh -- 512MB needed for the solve.'
+print('3D stokes demonstration on a quadratic mesh')
 
 viscosity = 10
 
 
 m=Mesh('import','GiD','../meshes/tank_quadratic_2500.GiD.msh')
-print 'mesh loaded!'
+print('mesh loaded!')
 mfu=MeshFem(m,3) # velocity
 mfulag=MeshFem(m,3)
 mfp=MeshFem(m,1) # pressure
@@ -41,8 +41,8 @@ mfd.set_fem(Fem('FEM_PK(3,2)'))
 mfp.set_fem(Fem('FEM_PK(3,1)'))
 mfe.set_fem(Fem('FEM_PK_DISCONTINUOUS(3,1,0.01)'))
 
-print 'nbcvs=%d, nbpts=%d, qdim=%d, fem = %s, nbdof=%d' % \
-      (m.nbcvs(), m.nbpts(), mfu.qdim(), mfu.fem()[0].char(), mfu.nbdof())
+print('nbcvs=%d, nbpts=%d, qdim=%d, fem = %s, nbdof=%d' % \
+      (m.nbcvs(), m.nbpts(), mfu.qdim(), mfu.fem()[0].char(), mfu.nbdof()))
 
 
 P=m.pts()
@@ -89,9 +89,9 @@ md.add_Dirichlet_condition_with_multipliers(mim, 'u', mfu, 2, 'Dir2data');
 md.add_Dirichlet_condition_with_multipliers(mim, 'u', mfu, 3);
 md.add_Dirichlet_condition_with_multipliers(mim, 'u', mfu, 4);
 
-print 'running solve...'
+print('running solve...')
 md.solve('noisy', 'lsolver','superlu')
-print 'solve done!'
+print('solve done!')
 
 
 U = md.variable('u');
diff --git a/interface/tests/python/demo_stokes_3D_tank_draw.py b/interface/tests/python/demo_stokes_3D_tank_draw.py
index ede7298..a6e2e65 100644
--- a/interface/tests/python/demo_stokes_3D_tank_draw.py
+++ b/interface/tests/python/demo_stokes_3D_tank_draw.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python
-# -*- coding: UTF8 -*-
+# -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2009 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -30,9 +30,9 @@ P = fromfile('tank_3D.P', 'd')
 
 sl=getfem.Slice(('boundary',('intersection',('planar',+1,[0,0,0],[0,1,0]),('planar',+1,[0,0,0],[1,0,0]))),m,3);
 
-print "importing tvtk.."
+print("importing tvtk..")
 import getfem_tvtk
-print "import done"
+print("import done")
 
 fig = getfem_tvtk.Figure(gui='tvtk')
 
@@ -48,7 +48,7 @@ sl=getfem.Slice(('boundary',('intersection',('planar',+1,[0,0,6],[0,0,-1]),
 fig.show(sl, data=(mfp, P), scalar_bar=True, edges=False)
 fig.scalar_range((-40,40));
 
-#print fig.scalar_range()
+#print(fig.scalar_range())
 
 m.set_region(42, m.outer_faces());
 m.region_subtract(42, 3);
diff --git a/interface/tests/python/demo_thermo_elasticity_electrical_coupling.py b/interface/tests/python/demo_thermo_elasticity_electrical_coupling.py
index ebc7231..1b00445 100644
--- a/interface/tests/python/demo_thermo_elasticity_electrical_coupling.py
+++ b/interface/tests/python/demo_thermo_elasticity_electrical_coupling.py
@@ -1,231 +1,231 @@
-#!/usr/bin/env python
-# -*- coding: UTF8 -*-
-# Python GetFEM++ interface
-#
-# Copyright (C)  2015-2015 Yves Renard.
-#
-# This file is a part of GetFEM++
-#
-# GetFEM++  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 along with the GCC Runtime Library
-# Exception either version 3.1 or (at your option) any later version.
-# This program  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 and GCC Runtime Library Exception for more details.
-# You  should  have received a copy of the GNU Lesser General Public License
-# along  with  this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
-#
-############################################################################
-
-import getfem as gf
-import numpy as np
-
-# Deformation of a plate under the coupling of thermal, elasticity, and
-# electric effects.
-#
-#
-#     ______________________________________
-#   /|         __       __       __         |->
-#   /|        /  \     /  \     /  \        |->
-#   /|       |    |   |    |   |    |       |-> F
-#   /|        \__/     \__/     \__/        |->
-#   /|______________________________________|->
-#     
-#
-# Elastic problem: The plate is clamped at rhe left boundary and a
-#   traction density of force F is prescribed at the right boundary.
-# Electric problem: The potential is prescribed to be 0V at the right
-#   boundary and 0.1V at the left boundary.
-# Thermal problem: A thermal insulation condition is prescribed at the
-#   left and hole boudnaries. The remaining boundary and the plate itself
-#   is supposed to be submitted to heat transfer with respect to the
-#   air at 20oC.
-# Coupling terms:
-#   - Joule heating: source term  sigma|Grad_V|^2
-#   - Dependance of the thermal conductivity in temperature :
-#     sigma = 1/(rho_0(1+alpha(theta-T0)))
-#     with T0 = 20oC, rho_0 the resistance temperature coefficient at T0
-#     and alpha the second resistance temperature coefficient.
-#   - Thermal expansion:
-#     stress_tensor = clambdastar div(u) I + 2 cmu epsilon(u) - beta theta I
-#     with beta = alpha_th E/(1-2nu), alpha_th being the thermal
-#     expansion coefficient.
-# The first two coupling terms are nonlinear ones.
-
-
-#
-# Physical parameters
-#
-epsilon = 1.       # Thickness of the plate (cm)
-E = 21E6           # Young Modulus (N/cm^2)
-nu = 0.3           # Poisson ratio
-clambda = E*nu/((1+nu)*(1-2*nu)) # First Lame coefficient (N/cm^2)
-cmu = E/(2*(1+nu))               # Second Lame coefficient (N/cm^2)
-clambdastar = 2*clambda*cmu/(clambda+2*cmu) # Lame coefficient for Plane stress (N/cm^2)
-F = 100E2          # Force density at the right boundary (N/cm^2)
-kappa = 4.         # Thermal conductivity (W/(cm K))
-D = 10.            # Heat transfer coefficient (W/(K cm^2))
-air_temp = 20.     # Temperature of the air in oC.
-alpha_th = 16.6E-6 # Thermal expansion coefficient (/K).
-T0 = 20.           # Reference temperature in oC.
-rho_0 = 1.754E-8   # Resistance temperature coefficient at T0 = 20oC
-alpha = 0.0039     # Second resistance temperature coefficient.
-
-#
-# Numerical parameters
-#
-h = 2.                     # Approximate mesh size
-elements_degree = 2        # Degree of the finite element methods
-export_mesh = True         # Draw the mesh after mesh generation or not
-solve_in_two_steps = True  # Solve the elasticity problem separately or not
-
-#
-# Mesh generation. Meshes can also been imported from several formats.
-#
-mo1 = gf.MesherObject('rectangle', [0., 0.], [100., 25.])
-mo2 = gf.MesherObject('ball', [25., 12.5], 8.)
-mo3 = gf.MesherObject('ball', [50., 12.5], 8.)
-mo4 = gf.MesherObject('ball', [75., 12.5], 8.)
-mo5 = gf.MesherObject('union', mo2, mo3, mo4)
-mo  = gf.MesherObject('set minus', mo1, mo5)
-
-print 'Mesh generation';
-gf.util('trace level', 2)   # No trace for mesh generation
-mesh = gf.Mesh('generate', mo, h, 2)
-
-#
-# Boundary selection
-#
-fb1 = mesh.outer_faces_in_box([1., 1.], [99., 24.])    # Boundary of the holes
-fb2 = mesh.outer_faces_with_direction([ 1., 0.], 0.01) # Right boundary
-fb3 = mesh.outer_faces_with_direction([-1., 0.], 0.01) # Left boundary
-fb4 = mesh.outer_faces_with_direction([0.,  1.], 0.01) # Top boundary
-fb5 = mesh.outer_faces_with_direction([0., -1.], 0.01) # Bottom boundary
-
-RIGHT_BOUND=1; LEFT_BOUND=2; TOP_BOUND=3; BOTTOM_BOUND=4; HOLE_BOUND=5;
-
-mesh.set_region( RIGHT_BOUND, fb2)
-mesh.set_region(  LEFT_BOUND, fb3)
-mesh.set_region(   TOP_BOUND, fb4)
-mesh.set_region(BOTTOM_BOUND, fb5)
-mesh.set_region(  HOLE_BOUND, fb1)
-mesh.region_subtract( RIGHT_BOUND, HOLE_BOUND)
-mesh.region_subtract(  LEFT_BOUND, HOLE_BOUND)
-mesh.region_subtract(   TOP_BOUND, HOLE_BOUND)
-mesh.region_subtract(BOTTOM_BOUND, HOLE_BOUND)
-
-if (export_mesh):
-    mesh.export_to_vtk('mesh.vtk');
-    print ('\nYou can view the mesh for instance with');
-    print ('mayavi2 -d mesh.vtk -f ExtractEdges -m Surface \n');
-
-#
-# Definition of finite elements methods and integration method
-#
-
-mfu = gf.MeshFem(mesh, 2)  # Finite element for the elastic displacement
-mfu.set_classical_fem(elements_degree)
-mft = gf.MeshFem(mesh, 1)  # Finite element for temperature and electrical field
-mft.set_classical_fem(elements_degree)
-mfvm = gf.MeshFem(mesh, 1) # Finite element for Von Mises stress interpolation
-mfvm.set_classical_discontinuous_fem(elements_degree)
-mim = gf.MeshIm(mesh, pow(elements_degree,2))   # Integration method
-
-
-#
-# Model definition
-#
-
-md=gf.Model('real');
-md.add_fem_variable('u', mfu)       # Displacement of the structure
-md.add_fem_variable('theta', mft)   # Temperature
-md.add_fem_variable('V', mft)       # Electric potential
-
-# Membrane elastic deformation
-md.add_initialized_data('cmu', [cmu])
-md.add_initialized_data('clambdastar', [clambdastar])
-md.add_isotropic_linearized_elasticity_brick(mim, 'u', 'clambdastar', 'cmu')
-
-md.add_Dirichlet_condition_with_multipliers(mim, 'u', elements_degree-1, LEFT_BOUND)
-md.add_initialized_data('Fdata', [F*epsilon, 0])
-md.add_source_term_brick(mim, 'u', 'Fdata', RIGHT_BOUND)
-
-# Electrical field
-sigmaeps = '(eps/(rho_0*(1+alpha*(theta-T0))))'
-md.add_initialized_data('eps', [epsilon])
-md.add_initialized_data('rho_0', [rho_0])
-md.add_initialized_data('alpha', [alpha])
-md.add_initialized_data('T0', [T0])
-md.add_nonlinear_generic_assembly_brick(mim, sigmaeps+'*(Grad_V.Grad_Test_V)')
-md.add_Dirichlet_condition_with_multipliers(mim, 'V', elements_degree-1, RIGHT_BOUND)
-md.add_initialized_data('DdataV', [0.1])
-md.add_Dirichlet_condition_with_multipliers(mim, 'V', elements_degree-1, LEFT_BOUND, 'DdataV')
-
-# Thermal problem
-md.add_initialized_data('kaeps', [kappa*epsilon])
-md.add_generic_elliptic_brick(mim, 'theta', 'kaeps')
-md.add_initialized_data('D2', [D*2])
-md.add_initialized_data('D2airt', [air_temp*D*2])
-md.add_mass_brick(mim, 'theta', 'D2')
-md.add_source_term_brick(mim, 'theta', 'D2airt')
-md.add_initialized_data('Deps', [D/epsilon])
-md.add_initialized_data('Depsairt', [air_temp*D/epsilon])
-md.add_Fourier_Robin_brick(mim, 'theta', 'Deps', TOP_BOUND)
-md.add_source_term_brick(mim, 'theta', 'Depsairt', TOP_BOUND)
-md.add_Fourier_Robin_brick(mim, 'theta', 'Deps', BOTTOM_BOUND)
-md.add_source_term_brick(mim, 'theta', 'Depsairt', BOTTOM_BOUND)
-
-# Joule heating term
-md.add_nonlinear_generic_assembly_brick(mim, '-'+sigmaeps+'*Norm_sqr(Grad_V)*Test_theta')
-
-# Thermal expansion term
-md.add_initialized_data('beta', [alpha_th*E/(1-2*nu)])
-md.add_linear_generic_assembly_brick(mim, 'beta*(T0-theta)*Trace(Grad_Test_u)')
-
-
-#
-# Model solve
-#
-if (solve_in_two_steps):
-  md.disable_variable('u')
-  print 'First problem with', md.nbdof(), ' dofs'
-  md.solve('max_res', 1E-9, 'max_iter', 100, 'noisy')
-  md.enable_variable('u')
-  md.disable_variable('theta')
-  md.disable_variable('V')
-  print 'Second problem with ', md.nbdof(), ' dofs'
-  md.solve('max_res', 1E-9, 'max_iter', 100, 'noisy')
-else:
-  print 'Global problem with ', md.nbdof(), ' dofs'
-  md.solve('max_res', 1E-9, 'max_iter', 100, 'noisy')
-
-
-#
-# Solution export
-#  
-U = md.variable('u')
-V = md.variable('V')
-THETA = md.variable('theta')
-VM = md.compute_isotropic_linearized_Von_Mises_or_Tresca('u', 'clambdastar', 'cmu', mfvm)
-CO = np.reshape(md.interpolation('-'+sigmaeps+'*Grad_V', mfvm), (2, mfvm.nbdof()), 'F')
-
-mfvm.export_to_vtk('displacement_with_von_mises.vtk', mfvm,  VM, 'Von Mises Stresses', mfu, U, 'Displacements')
-print ('You can view solutions with for instance:\nmayavi2 -d displacement_with_von_mises.vtk -f WarpVector -m Surface')
-mft.export_to_vtk('temperature.vtk', mft, THETA, 'Temperature')
-print ('mayavi2 -d temperature.vtk -f WarpScalar -m Surface')
-mft.export_to_vtk('electric_potential.vtk', mft, V, 'Electric potential')
-print ('mayavi2 -d electric_potential.vtk -f WarpScalar -m Surface')
-
-
-
-
-
-
-
-
-
-
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Python GetFEM++ interface
+#
+# Copyright (C)  2015-2017 Yves Renard.
+#
+# This file is a part of GetFEM++
+#
+# GetFEM++  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 along with the GCC Runtime Library
+# Exception either version 3.1 or (at your option) any later version.
+# This program  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 and GCC Runtime Library Exception for more details.
+# You  should  have received a copy of the GNU Lesser General Public License
+# along  with  this program;  if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+############################################################################
+
+import getfem as gf
+import numpy as np
+
+# Deformation of a plate under the coupling of thermal, elasticity, and
+# electric effects.
+#
+#
+#     ______________________________________
+#   /|         __       __       __         |->
+#   /|        /  \     /  \     /  \        |->
+#   /|       |    |   |    |   |    |       |-> F
+#   /|        \__/     \__/     \__/        |->
+#   /|______________________________________|->
+#     
+#
+# Elastic problem: The plate is clamped at rhe left boundary and a
+#   traction density of force F is prescribed at the right boundary.
+# Electric problem: The potential is prescribed to be 0V at the right
+#   boundary and 0.1V at the left boundary.
+# Thermal problem: A thermal insulation condition is prescribed at the
+#   left and hole boudnaries. The remaining boundary and the plate itself
+#   is supposed to be submitted to heat transfer with respect to the
+#   air at 20oC.
+# Coupling terms:
+#   - Joule heating: source term  sigma|Grad_V|^2
+#   - Dependance of the thermal conductivity in temperature :
+#     sigma = 1/(rho_0(1+alpha(theta-T0)))
+#     with T0 = 20oC, rho_0 the resistance temperature coefficient at T0
+#     and alpha the second resistance temperature coefficient.
+#   - Thermal expansion:
+#     stress_tensor = clambdastar div(u) I + 2 cmu epsilon(u) - beta theta I
+#     with beta = alpha_th E/(1-2nu), alpha_th being the thermal
+#     expansion coefficient.
+# The first two coupling terms are nonlinear ones.
+
+
+#
+# Physical parameters
+#
+epsilon = 1.       # Thickness of the plate (cm)
+E = 21E6           # Young Modulus (N/cm^2)
+nu = 0.3           # Poisson ratio
+clambda = E*nu/((1+nu)*(1-2*nu)) # First Lame coefficient (N/cm^2)
+cmu = E/(2*(1+nu))               # Second Lame coefficient (N/cm^2)
+clambdastar = 2*clambda*cmu/(clambda+2*cmu) # Lame coefficient for Plane stress (N/cm^2)
+F = 100E2          # Force density at the right boundary (N/cm^2)
+kappa = 4.         # Thermal conductivity (W/(cm K))
+D = 10.            # Heat transfer coefficient (W/(K cm^2))
+air_temp = 20.     # Temperature of the air in oC.
+alpha_th = 16.6E-6 # Thermal expansion coefficient (/K).
+T0 = 20.           # Reference temperature in oC.
+rho_0 = 1.754E-8   # Resistance temperature coefficient at T0 = 20oC
+alpha = 0.0039     # Second resistance temperature coefficient.
+
+#
+# Numerical parameters
+#
+h = 2.                     # Approximate mesh size
+elements_degree = 2        # Degree of the finite element methods
+export_mesh = True         # Draw the mesh after mesh generation or not
+solve_in_two_steps = True  # Solve the elasticity problem separately or not
+
+#
+# Mesh generation. Meshes can also been imported from several formats.
+#
+mo1 = gf.MesherObject('rectangle', [0., 0.], [100., 25.])
+mo2 = gf.MesherObject('ball', [25., 12.5], 8.)
+mo3 = gf.MesherObject('ball', [50., 12.5], 8.)
+mo4 = gf.MesherObject('ball', [75., 12.5], 8.)
+mo5 = gf.MesherObject('union', mo2, mo3, mo4)
+mo  = gf.MesherObject('set minus', mo1, mo5)
+
+print('Mesh generation')
+gf.util('trace level', 2)   # No trace for mesh generation
+mesh = gf.Mesh('generate', mo, h, 2)
+
+#
+# Boundary selection
+#
+fb1 = mesh.outer_faces_in_box([1., 1.], [99., 24.])    # Boundary of the holes
+fb2 = mesh.outer_faces_with_direction([ 1., 0.], 0.01) # Right boundary
+fb3 = mesh.outer_faces_with_direction([-1., 0.], 0.01) # Left boundary
+fb4 = mesh.outer_faces_with_direction([0.,  1.], 0.01) # Top boundary
+fb5 = mesh.outer_faces_with_direction([0., -1.], 0.01) # Bottom boundary
+
+RIGHT_BOUND=1; LEFT_BOUND=2; TOP_BOUND=3; BOTTOM_BOUND=4; HOLE_BOUND=5;
+
+mesh.set_region( RIGHT_BOUND, fb2)
+mesh.set_region(  LEFT_BOUND, fb3)
+mesh.set_region(   TOP_BOUND, fb4)
+mesh.set_region(BOTTOM_BOUND, fb5)
+mesh.set_region(  HOLE_BOUND, fb1)
+mesh.region_subtract( RIGHT_BOUND, HOLE_BOUND)
+mesh.region_subtract(  LEFT_BOUND, HOLE_BOUND)
+mesh.region_subtract(   TOP_BOUND, HOLE_BOUND)
+mesh.region_subtract(BOTTOM_BOUND, HOLE_BOUND)
+
+if (export_mesh):
+    mesh.export_to_vtk('mesh.vtk');
+    print('\nYou can view the mesh for instance with');
+    print('mayavi2 -d mesh.vtk -f ExtractEdges -m Surface \n');
+
+#
+# Definition of finite elements methods and integration method
+#
+
+mfu = gf.MeshFem(mesh, 2)  # Finite element for the elastic displacement
+mfu.set_classical_fem(elements_degree)
+mft = gf.MeshFem(mesh, 1)  # Finite element for temperature and electrical field
+mft.set_classical_fem(elements_degree)
+mfvm = gf.MeshFem(mesh, 1) # Finite element for Von Mises stress interpolation
+mfvm.set_classical_discontinuous_fem(elements_degree)
+mim = gf.MeshIm(mesh, pow(elements_degree,2))   # Integration method
+
+
+#
+# Model definition
+#
+
+md=gf.Model('real');
+md.add_fem_variable('u', mfu)       # Displacement of the structure
+md.add_fem_variable('theta', mft)   # Temperature
+md.add_fem_variable('V', mft)       # Electric potential
+
+# Membrane elastic deformation
+md.add_initialized_data('cmu', [cmu])
+md.add_initialized_data('clambdastar', [clambdastar])
+md.add_isotropic_linearized_elasticity_brick(mim, 'u', 'clambdastar', 'cmu')
+
+md.add_Dirichlet_condition_with_multipliers(mim, 'u', elements_degree-1, LEFT_BOUND)
+md.add_initialized_data('Fdata', [F*epsilon, 0])
+md.add_source_term_brick(mim, 'u', 'Fdata', RIGHT_BOUND)
+
+# Electrical field
+sigmaeps = '(eps/(rho_0*(1+alpha*(theta-T0))))'
+md.add_initialized_data('eps', [epsilon])
+md.add_initialized_data('rho_0', [rho_0])
+md.add_initialized_data('alpha', [alpha])
+md.add_initialized_data('T0', [T0])
+md.add_nonlinear_generic_assembly_brick(mim, sigmaeps+'*(Grad_V.Grad_Test_V)')
+md.add_Dirichlet_condition_with_multipliers(mim, 'V', elements_degree-1, RIGHT_BOUND)
+md.add_initialized_data('DdataV', [0.1])
+md.add_Dirichlet_condition_with_multipliers(mim, 'V', elements_degree-1, LEFT_BOUND, 'DdataV')
+
+# Thermal problem
+md.add_initialized_data('kaeps', [kappa*epsilon])
+md.add_generic_elliptic_brick(mim, 'theta', 'kaeps')
+md.add_initialized_data('D2', [D*2])
+md.add_initialized_data('D2airt', [air_temp*D*2])
+md.add_mass_brick(mim, 'theta', 'D2')
+md.add_source_term_brick(mim, 'theta', 'D2airt')
+md.add_initialized_data('Deps', [D/epsilon])
+md.add_initialized_data('Depsairt', [air_temp*D/epsilon])
+md.add_Fourier_Robin_brick(mim, 'theta', 'Deps', TOP_BOUND)
+md.add_source_term_brick(mim, 'theta', 'Depsairt', TOP_BOUND)
+md.add_Fourier_Robin_brick(mim, 'theta', 'Deps', BOTTOM_BOUND)
+md.add_source_term_brick(mim, 'theta', 'Depsairt', BOTTOM_BOUND)
+
+# Joule heating term
+md.add_nonlinear_generic_assembly_brick(mim, '-'+sigmaeps+'*Norm_sqr(Grad_V)*Test_theta')
+
+# Thermal expansion term
+md.add_initialized_data('beta', [alpha_th*E/(1-2*nu)])
+md.add_linear_generic_assembly_brick(mim, 'beta*(T0-theta)*Trace(Grad_Test_u)')
+
+
+#
+# Model solve
+#
+if (solve_in_two_steps):
+  md.disable_variable('u')
+  print('First problem with', md.nbdof(), ' dofs')
+  md.solve('max_res', 1E-9, 'max_iter', 100, 'noisy')
+  md.enable_variable('u')
+  md.disable_variable('theta')
+  md.disable_variable('V')
+  print('Second problem with ', md.nbdof(), ' dofs')
+  md.solve('max_res', 1E-9, 'max_iter', 100, 'noisy')
+else:
+  print('Global problem with ', md.nbdof(), ' dofs')
+  md.solve('max_res', 1E-9, 'max_iter', 100, 'noisy')
+
+
+#
+# Solution export
+#  
+U = md.variable('u')
+V = md.variable('V')
+THETA = md.variable('theta')
+VM = md.compute_isotropic_linearized_Von_Mises_or_Tresca('u', 'clambdastar', 'cmu', mfvm)
+CO = np.reshape(md.interpolation('-'+sigmaeps+'*Grad_V', mfvm), (2, mfvm.nbdof()), 'F')
+
+mfvm.export_to_vtk('displacement_with_von_mises.vtk', mfvm,  VM, 'Von Mises Stresses', mfu, U, 'Displacements')
+print('You can view solutions with for instance:\nmayavi2 -d displacement_with_von_mises.vtk -f WarpVector -m Surface')
+mft.export_to_vtk('temperature.vtk', mft, THETA, 'Temperature')
+print('mayavi2 -d temperature.vtk -f WarpScalar -m Surface')
+mft.export_to_vtk('electric_potential.vtk', mft, V, 'Electric potential')
+print('mayavi2 -d electric_potential.vtk -f WarpScalar -m Surface')
+
+
+
+
+
+
+
+
+
+
diff --git a/interface/tests/python/demo_tripod.py b/interface/tests/python/demo_tripod.py
index a2268d2..158911a 100644
--- a/interface/tests/python/demo_tripod.py
+++ b/interface/tests/python/demo_tripod.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2009 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -25,7 +25,7 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of GetFEM++.
 
-  $Id: demo_tripod.py 5312 2016-04-29 10:44:26Z renard $
+  $Id$
 """
 
 import getfem as gf
@@ -35,14 +35,14 @@ with_graphics=True
 try:
     import getfem_tvtk
 except:
-    print "\n** Could NOT import getfem_tvtk -- graphical output disabled **\n"
+    print("\n** Could NOT import getfem_tvtk -- graphical output disabled **\n")
     import time
     time.sleep(2)
     with_graphics=False
 
 
 m=gf.Mesh('import','gid','../meshes/tripod.GiD.msh')
-print 'done!'
+print('done!')
 mfu=gf.MeshFem(m,3) # displacement
 mfp=gf.MeshFem(m,1) # pressure
 mfd=gf.MeshFem(m,1) # data
@@ -55,11 +55,11 @@ mfu.set_fem(gf.Fem('FEM_PK(3,%d)' % (degree,)))
 mfd.set_fem(gf.Fem('FEM_PK(3,0)'))
 mfp.set_fem(gf.Fem('FEM_PK_DISCONTINUOUS(3,0)'))
 
-print 'nbcvs=%d, nbpts=%d, qdim=%d, fem = %s, nbdof=%d' % \
-      (m.nbcvs(), m.nbpts(), mfu.qdim(), mfu.fem()[0].char(), mfu.nbdof())
+print('nbcvs=%d, nbpts=%d, qdim=%d, fem = %s, nbdof=%d' % \
+      (m.nbcvs(), m.nbpts(), mfu.qdim(), mfu.fem()[0].char(), mfu.nbdof()))
 
 P=m.pts()
-print 'test', P[1,:]
+print('test', P[1,:])
 ctop=(abs(P[1,:] - 13) < 1e-6)
 cbot=(abs(P[1,:] + 10) < 1e-6)
 pidtop=np.compress(ctop, range(0, m.nbpts()))
@@ -106,10 +106,10 @@ md.add_source_term_brick(mim, 'u', 'VolumicData');
 # Attach the tripod to the ground
 md.add_Dirichlet_condition_with_multipliers(mim, 'u', mfu, 2);
 
-print 'running solve...'
+print('running solve...')
 md.solve('noisy', 'max iter', 1);
 U = md.variable('u');
-print 'solve done!'
+print('solve done!')
 
 
 mfdu=gf.MeshFem(m,1)
@@ -122,7 +122,7 @@ else:
 # post-processing
 sl=gf.Slice(('boundary',), mfu, degree)
 
-print 'Von Mises range: ', VM.min(), VM.max()
+print('Von Mises range: ', VM.min(), VM.max())
 
 # export results to VTK
 sl.export_to_vtk('tripod.vtk', 'ascii', mfdu,  VM, 'Von Mises Stress', mfu, U, 'Displacement')
@@ -130,10 +130,10 @@ sl.export_to_pos('tripod.pos', mfdu, VM, 'Von Mises Stress', mfu, U, 'Displaceme
 
 gf.memstats()
 
-print 'You can view the tripod with (for example) mayavi:'
-print 'mayavi2 -d tripod.vtk -f WarpVector -m Surface'
-print 'or'
-print 'gmsh tripod.pos'
+print('You can view the tripod with (for example) mayavi:')
+print('mayavi2 -d tripod.vtk -f WarpVector -m Surface')
+print('or')
+print('gmsh tripod.pos')
 
 # mfu.save('tripod.mf', 'with_mesh')
 # U.tofile('tripod.U')
@@ -143,6 +143,6 @@ print 'gmsh tripod.pos'
 if with_graphics:
   fig = getfem_tvtk.Figure()
   fig.show(mfu, deformation=U, data=(mfdu,VM), deformation_scale='20%')
-  print "Press Q to continue.."
+  print("Press Q to continue..")
   fig.set_colormap('tripod')
   fig.loop()
diff --git a/interface/tests/python/demo_tripod_alt.py b/interface/tests/python/demo_tripod_alt.py
index dfd48fc..50ca518 100644
--- a/interface/tests/python/demo_tripod_alt.py
+++ b/interface/tests/python/demo_tripod_alt.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2016 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -26,14 +26,14 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of GetFEM++.
 
-  $Id: demo_tripod_alt.py 5192 2015-12-15 14:40:17Z renard $
+  $Id$
 """
 from getfem import *
 from numpy import *
 
-print 'importing the mesh..',
+print('importing the mesh..',)
 m=Mesh('import','gid','../meshes/tripod.GiD.msh')
-print 'done!'
+print('done!')
 mfu=MeshFem(m,3)
 mfd=MeshFem(m,1)
 mfe=MeshFem(m,1)
@@ -43,8 +43,8 @@ mfu.set_fem(Fem('FEM_PK(3,%d)' % (degree,)));
 mfe.set_fem(Fem('FEM_PK_DISCONTINUOUS(3,%d,0.01)' % (degree,)))
 mfd.set_fem(Fem('FEM_PK(3,0)'))
 
-print 'nbcvs=%d, nbpts=%d, qdim=%d, fem = %s, nbdof=%d' % \
-      (m.nbcvs(), m.nbpts(), mfu.qdim(), mfu.fem()[0].char(), mfu.nbdof())
+print('nbcvs=%d, nbpts=%d, qdim=%d, fem = %s, nbdof=%d' % \
+      (m.nbcvs(), m.nbpts(), mfu.qdim(), mfu.fem()[0].char(), mfu.nbdof()))
 
 P=m.pts()
 
@@ -80,11 +80,11 @@ KK=Nt*K*N
 FF=Nt*F
 
 # solve ...
-print "preconditioner.."
+print("preconditioner..")
 P=Precond('ildlt',KK)
-print "solving...",
+print("solving..."),
 UU=linsolve_cg(KK,FF,P)
-print "done!"
+print("done!")
 U=N*UU+U0
 
 # post-processing
@@ -101,7 +101,7 @@ for i in range(0, DU.shape[2]):
   Sigma[:,:,i]=E
   VM[i] = sum(E.ravel()**2) - (1./3.)*sum(diagonal(E))**2
 
-print 'Von Mises range: ', VM.min(), VM.max()
+print('Von Mises range: ', VM.min(), VM.max())
 
 # export results to VTK you can use
 # i.e. with  "mayavi2 -d tripod.vtk -f WarpScalar -m Surface"
@@ -118,7 +118,7 @@ sl.export_to_vtk('tripod_ev.vtk', mfu, U, 'Displacement', SigmaSL, 'stress')
 # export to Gmsh POS
 sl.export_to_pos('tripod.pos', mfe, VM, 'Von Mises Stress', mfu, U, 'Displacement')
 
-print 'You can view the tripod with (for example) mayavi:'
-print 'mayavi2 -d tripod.vtk -f WarpScalar -m Surface'
-print 'or'
-print 'gmsh tripod.pos'
+print('You can view the tripod with (for example) mayavi:')
+print('mayavi2 -d tripod.vtk -f WarpScalar -m Surface')
+print('or')
+print('gmsh tripod.pos')
diff --git a/interface/tests/python/demo_wave.py b/interface/tests/python/demo_wave.py
index 53d2381..ec76aa9 100644
--- a/interface/tests/python/demo_wave.py
+++ b/interface/tests/python/demo_wave.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python
-# -*- coding: UTF8 -*-
+# -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2009 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -24,13 +24,13 @@
   This program is used to check that python-getfem is working. This is
   also a good example of use of GetFEM++.
 
-  $Id: demo_wave.py 3809 2011-09-26 20:38:56Z logari81 $
+  $Id$
 """
 from numpy import *
 from getfem import *
 import os
 
-make_check=os.environ.has_key('srcdir');
+make_check=('srcdir' in os.environ);
 
 filename='../meshes/holed_disc_with_quadratic_2D_triangles.msh';
 if (make_check):
@@ -89,5 +89,5 @@ if (not(make_check)):
     sl.export_to_vtk('wave.vtk', mfu, real(U), 'rWave',
                      mfu, imag(U), 'iWave')
 
-    print 'You can view the solution with (for instance):'
-    print 'mayavi2 -d wave.vtk -f WarpScalar -m Surface'
+    print('You can view the solution with (for instance):')
+    print('mayavi2 -d wave.vtk -f WarpScalar -m Surface')
diff --git a/interface/tests/python/demo_wave_equation.py b/interface/tests/python/demo_wave_equation.py
index 6e9e6f4..ace88eb 100644
--- a/interface/tests/python/demo_wave_equation.py
+++ b/interface/tests/python/demo_wave_equation.py
@@ -2,7 +2,7 @@
 # -*- coding: UTF8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2015-2015 FABRE Mathieu, SECK Mamadou, DALLERIT Valentin,
+# Copyright (C) 2015-2017 FABRE Mathieu, SECK Mamadou, DALLERIT Valentin,
 #                         Yves Renard.
 #
 # This file is a part of GetFEM++
diff --git a/interface/tests/python/demo_wheel_contact.py b/interface/tests/python/demo_wheel_contact.py
index 711a484..0aea7a0 100644
--- a/interface/tests/python/demo_wheel_contact.py
+++ b/interface/tests/python/demo_wheel_contact.py
@@ -1,168 +1,168 @@
-#!/usr/bin/env python
-# -*- coding: UTF8 -*-
-# Python GetFEM++ interface
-#
-# Copyright (C)  2015-2015 Yves Renard.
-#
-# This file is a part of GetFEM++
-#
-# GetFEM++  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 along with the GCC Runtime Library
-# Exception either version 3.1 or (at your option) any later version.
-# This program  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 and GCC Runtime Library Exception for more details.
-# You  should  have received a copy of the GNU Lesser General Public License
-# along  with  this program;  if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
-#
-############################################################################
-#
-# Contact of a deformable 'wheel' onto a plane deformable obstacle.
-#
-############################################################################
-
-import getfem as gf
-import numpy as np
-gf.util('trace level', 1)    # No trace for mesh generation nor for assembly
-
-export_mesh = True;
-Dirichlet_version = False; # Use a dirichlet condition instead of a global load
-
-#
-# Physical parameters
-#
-E = 21E6                         # Young Modulus (N/cm^2)
-nu = 0.3                         # Poisson ratio
-clambda = E*nu/((1+nu)*(1-2*nu)) # First Lame coefficient (N/cm^2)
-cmu = E/(2*(1+nu))               # Second Lame coefficient (N/cm^2)
-clambdastar = 2*clambda*cmu/(clambda+2*cmu) # Lame coefficient for Plane stress
-applied_force = 1E7              # Force at the hole boundary (N)
-
-
-#
-# Numerical parameters
-#
-h = 1                    # Approximate mesh size
-elements_degree = 2      # Degree of the finite element methods
-gamma0 = 1./E;           # Augmentation parameter for the augmented Lagrangian 
-
-#
-# Mesh generation. Meshes can also been imported from several formats.
-#
-mo1 = gf.MesherObject('ball', [0., 15.], 15.)
-mo2 = gf.MesherObject('ball', [0., 15.], 8.)
-mo3 = gf.MesherObject('set minus', mo1, mo2)
-
-print ('Meshes generation')
-mesh1 = gf.Mesh('generate', mo3, h, 2)
-mesh2 = gf.Mesh('import','structured','GT="GT_PK(2,1)";SIZES=[30,10];NOISED=0;NSUBDIV=[%d,%d];' % (int(30/h)+1, int(10/h)+1));
-mesh2.translate([-15.,-10.])
-
-
-if (export_mesh):
-  mesh1.export_to_vtk('mesh1.vtk')
-  mesh2.export_to_vtk('mesh2.vtk')
-  print ('\nYou can view the meshes for instance with')
-  print ('mayavi2  -d mesh1.vtk -f ExtractEdges -m Surface -d mesh2.vtk -f ExtractEdges -m Surface \n')
-
-
-#
-# Boundary selection
-#
-fb1 = mesh1.outer_faces_in_box([-8.1, 6.9], [8.1, 23.1])  # Boundary of the hole
-fb2 = mesh1.outer_faces_with_direction([0., -1.], np.pi/4.5) # Contact boundary of the wheel
-fb3 = mesh2.outer_faces_with_direction([0., -1.], 0.01)   # Bottom boundary of the foundation
-
-HOLE_BOUND=1; CONTACT_BOUND=2; BOTTOM_BOUND=3;
-
-mesh1.set_region(HOLE_BOUND, fb1)
-mesh1.set_region(CONTACT_BOUND, fb2)
-mesh1.region_subtract(CONTACT_BOUND, HOLE_BOUND)
-mesh2.set_region(BOTTOM_BOUND, fb3)
-
-
-#
-# Definition of finite elements methods and integration method
-#
-
-mfu1 = gf.MeshFem(mesh1, 2)
-mfu1.set_classical_fem(elements_degree)
-mflambda = gf.MeshFem(mesh1, 2)
-mflambda.set_classical_fem(elements_degree-1)
-mflambda_C = gf.MeshFem(mesh1, 1)
-mflambda_C.set_classical_fem(elements_degree-1)
-mfu2 = gf.MeshFem(mesh2, 2)
-mfu2.set_classical_fem(elements_degree)
-mfvm1 = gf.MeshFem(mesh1, 1)
-mfvm1.set_classical_discontinuous_fem(elements_degree)
-mfvm2 = gf.MeshFem(mesh2, 1)
-mfvm2.set_classical_discontinuous_fem(elements_degree)
-mim1 = gf.MeshIm(mesh1, 4)
-mim1c = gf.MeshIm(mesh1, gf.Integ('IM_STRUCTURED_COMPOSITE(IM_TRIANGLE(4),2)'))
-mim2 = gf.MeshIm(mesh2, 4)
-
-
-#
-# Model definition
-#
-
-md=gf.Model('real');
-md.add_fem_variable('u1', mfu1)       # Displacement of the structure 1
-md.add_fem_variable('u2', mfu2)       # Displacement of the structure 2
-
-md.add_initialized_data('cmu', [cmu])
-md.add_initialized_data('clambdastar', [clambdastar])
-md.add_isotropic_linearized_elasticity_brick(mim1, 'u1', 'clambdastar', 'cmu')
-md.add_isotropic_linearized_elasticity_brick(mim2, 'u2', 'clambdastar', 'cmu')
-md.add_Dirichlet_condition_with_multipliers(mim2, 'u2', elements_degree-1, BOTTOM_BOUND)
-
-
-
-# Contact condition (augmented Lagrangian)
-md.add_initialized_data('gamma0', [gamma0])
-md.add_interpolate_transformation_from_expression('Proj1', mesh1, mesh2, '[X(1);0]')
-md.add_filtered_fem_variable('lambda1', mflambda_C, CONTACT_BOUND)
-md.add_nonlinear_generic_assembly_brick(mim1c, 'lambda1*(Test_u1.[0;1])'
-                                        '-lambda1*(Interpolate(Test_u2,Proj1).[0;1])', CONTACT_BOUND)
-md.add_nonlinear_generic_assembly_brick(mim1c, '-(gamma0*element_size)*(lambda1 + neg_part(lambda1+(1/(gamma0*element_size))*((u1-Interpolate(u2,Proj1)+X-Interpolate(X,Proj1)).[0;1])))*Test_lambda1', CONTACT_BOUND);
-
-# Prescribed force in the hole
-if (Dirichlet_version):
-  md.add_initialized_data('DData', [0., -1.0])
-  md.add_Dirichlet_condition_with_multipliers(mim1, 'u1', elements_degree-1, HOLE_BOUND, 'DData');
-else:
-  md.add_filtered_fem_variable('lambda_D', mflambda, HOLE_BOUND)
-  md.add_initialized_data('F', [applied_force/(8*2*np.pi)])
-  md.add_variable('alpha_D', 1)
-  md.add_linear_generic_assembly_brick(mim1, '-lambda_D.Test_u1 + (alpha_D*[0;1] - u1).Test_lambda_D + (lambda_D.[0;1] + F)*Test_alpha_D + 1E-6*alpha_D*Test_alpha_D', HOLE_BOUND)
-  # The small penalization 1E-6*alpha_D*Test_alpha_D seems necessary to have
-  # a convergence in all cases. Why ?
-
-
-#
-# Model solve
-#
-
-print 'Solve problem with ', md.nbdof(), ' dofs'
-md.solve('max_res', 1E-9, 'max_iter', 40, 'noisy') # , 'lsearch', 'simplest',  'alpha min', 0.8)
-if not(Dirichlet_version):
-  print 'alpha_D = ', md.variable('alpha_D')[0]
-# print 'Contact multiplier ', md.variable('lambda1')
-
-#
-# Solution export
-#  
-U1 = md.variable('u1')
-U2 = md.variable('u2')
-VM1 = md.compute_isotropic_linearized_Von_Mises_or_Tresca('u1', 'clambdastar', 'cmu', mfvm1)
-VM2 = md.compute_isotropic_linearized_Von_Mises_or_Tresca('u2', 'clambdastar', 'cmu', mfvm2)
-
-mfvm1.export_to_vtk('displacement_with_von_mises1.vtk', mfvm1,  VM1, 'Von Mises Stresses', mfu1, U1, 'Displacements')
-
-mfvm2.export_to_vtk('displacement_with_von_mises2.vtk', mfvm2,  VM2, 'Von Mises Stresses', mfu2, U2, 'Displacements')
-print ('You can view solutions with for instance:\nmayavi2 -d displacement_with_von_mises1.vtk -f WarpVector -m Surface -d displacement_with_von_mises2.vtk -f WarpVector -m Surface')
-
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Python GetFEM++ interface
+#
+# Copyright (C)  2015-2017 Yves Renard.
+#
+# This file is a part of GetFEM++
+#
+# GetFEM++  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 along with the GCC Runtime Library
+# Exception either version 3.1 or (at your option) any later version.
+# This program  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 and GCC Runtime Library Exception for more details.
+# You  should  have received a copy of the GNU Lesser General Public License
+# along  with  this program;  if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+############################################################################
+#
+# Contact of a deformable 'wheel' onto a plane deformable obstacle.
+#
+############################################################################
+
+import getfem as gf
+import numpy as np
+gf.util('trace level', 1)    # No trace for mesh generation nor for assembly
+
+export_mesh = True;
+Dirichlet_version = False; # Use a dirichlet condition instead of a global load
+
+#
+# Physical parameters
+#
+E = 21E6                         # Young Modulus (N/cm^2)
+nu = 0.3                         # Poisson ratio
+clambda = E*nu/((1+nu)*(1-2*nu)) # First Lame coefficient (N/cm^2)
+cmu = E/(2*(1+nu))               # Second Lame coefficient (N/cm^2)
+clambdastar = 2*clambda*cmu/(clambda+2*cmu) # Lame coefficient for Plane stress
+applied_force = 1E7              # Force at the hole boundary (N)
+
+
+#
+# Numerical parameters
+#
+h = 1                    # Approximate mesh size
+elements_degree = 2      # Degree of the finite element methods
+gamma0 = 1./E;           # Augmentation parameter for the augmented Lagrangian 
+
+#
+# Mesh generation. Meshes can also been imported from several formats.
+#
+mo1 = gf.MesherObject('ball', [0., 15.], 15.)
+mo2 = gf.MesherObject('ball', [0., 15.], 8.)
+mo3 = gf.MesherObject('set minus', mo1, mo2)
+
+print('Meshes generation')
+mesh1 = gf.Mesh('generate', mo3, h, 2)
+mesh2 = gf.Mesh('import','structured','GT="GT_PK(2,1)";SIZES=[30,10];NOISED=0;NSUBDIV=[%d,%d];' % (int(30/h)+1, int(10/h)+1));
+mesh2.translate([-15.,-10.])
+
+
+if (export_mesh):
+  mesh1.export_to_vtk('mesh1.vtk')
+  mesh2.export_to_vtk('mesh2.vtk')
+  print('\nYou can view the meshes for instance with')
+  print('mayavi2  -d mesh1.vtk -f ExtractEdges -m Surface -d mesh2.vtk -f ExtractEdges -m Surface \n')
+
+
+#
+# Boundary selection
+#
+fb1 = mesh1.outer_faces_in_box([-8.1, 6.9], [8.1, 23.1])  # Boundary of the hole
+fb2 = mesh1.outer_faces_with_direction([0., -1.], np.pi/4.5) # Contact boundary of the wheel
+fb3 = mesh2.outer_faces_with_direction([0., -1.], 0.01)   # Bottom boundary of the foundation
+
+HOLE_BOUND=1; CONTACT_BOUND=2; BOTTOM_BOUND=3;
+
+mesh1.set_region(HOLE_BOUND, fb1)
+mesh1.set_region(CONTACT_BOUND, fb2)
+mesh1.region_subtract(CONTACT_BOUND, HOLE_BOUND)
+mesh2.set_region(BOTTOM_BOUND, fb3)
+
+
+#
+# Definition of finite elements methods and integration method
+#
+
+mfu1 = gf.MeshFem(mesh1, 2)
+mfu1.set_classical_fem(elements_degree)
+mflambda = gf.MeshFem(mesh1, 2)
+mflambda.set_classical_fem(elements_degree-1)
+mflambda_C = gf.MeshFem(mesh1, 1)
+mflambda_C.set_classical_fem(elements_degree-1)
+mfu2 = gf.MeshFem(mesh2, 2)
+mfu2.set_classical_fem(elements_degree)
+mfvm1 = gf.MeshFem(mesh1, 1)
+mfvm1.set_classical_discontinuous_fem(elements_degree)
+mfvm2 = gf.MeshFem(mesh2, 1)
+mfvm2.set_classical_discontinuous_fem(elements_degree)
+mim1 = gf.MeshIm(mesh1, 4)
+mim1c = gf.MeshIm(mesh1, gf.Integ('IM_STRUCTURED_COMPOSITE(IM_TRIANGLE(4),2)'))
+mim2 = gf.MeshIm(mesh2, 4)
+
+
+#
+# Model definition
+#
+
+md=gf.Model('real');
+md.add_fem_variable('u1', mfu1)       # Displacement of the structure 1
+md.add_fem_variable('u2', mfu2)       # Displacement of the structure 2
+
+md.add_initialized_data('cmu', [cmu])
+md.add_initialized_data('clambdastar', [clambdastar])
+md.add_isotropic_linearized_elasticity_brick(mim1, 'u1', 'clambdastar', 'cmu')
+md.add_isotropic_linearized_elasticity_brick(mim2, 'u2', 'clambdastar', 'cmu')
+md.add_Dirichlet_condition_with_multipliers(mim2, 'u2', elements_degree-1, BOTTOM_BOUND)
+
+
+
+# Contact condition (augmented Lagrangian)
+md.add_initialized_data('gamma0', [gamma0])
+md.add_interpolate_transformation_from_expression('Proj1', mesh1, mesh2, '[X(1);0]')
+md.add_filtered_fem_variable('lambda1', mflambda_C, CONTACT_BOUND)
+md.add_nonlinear_generic_assembly_brick(mim1c, 'lambda1*(Test_u1.[0;1])'
+                                        '-lambda1*(Interpolate(Test_u2,Proj1).[0;1])', CONTACT_BOUND)
+md.add_nonlinear_generic_assembly_brick(mim1c, '-(gamma0*element_size)*(lambda1 + neg_part(lambda1+(1/(gamma0*element_size))*((u1-Interpolate(u2,Proj1)+X-Interpolate(X,Proj1)).[0;1])))*Test_lambda1', CONTACT_BOUND);
+
+# Prescribed force in the hole
+if (Dirichlet_version):
+  md.add_initialized_data('DData', [0., -1.0])
+  md.add_Dirichlet_condition_with_multipliers(mim1, 'u1', elements_degree-1, HOLE_BOUND, 'DData');
+else:
+  md.add_filtered_fem_variable('lambda_D', mflambda, HOLE_BOUND)
+  md.add_initialized_data('F', [applied_force/(8*2*np.pi)])
+  md.add_variable('alpha_D', 1)
+  md.add_linear_generic_assembly_brick(mim1, '-lambda_D.Test_u1 + (alpha_D*[0;1] - u1).Test_lambda_D + (lambda_D.[0;1] + F)*Test_alpha_D + 1E-6*alpha_D*Test_alpha_D', HOLE_BOUND)
+  # The small penalization 1E-6*alpha_D*Test_alpha_D seems necessary to have
+  # a convergence in all cases. Why ?
+
+
+#
+# Model solve
+#
+
+print('Solve problem with ', md.nbdof(), ' dofs')
+md.solve('max_res', 1E-9, 'max_iter', 40, 'noisy') # , 'lsearch', 'simplest',  'alpha min', 0.8)
+if not(Dirichlet_version):
+  print('alpha_D = ', md.variable('alpha_D')[0])
+# print('Contact multiplier ', md.variable('lambda1'))
+
+#
+# Solution export
+#  
+U1 = md.variable('u1')
+U2 = md.variable('u2')
+VM1 = md.compute_isotropic_linearized_Von_Mises_or_Tresca('u1', 'clambdastar', 'cmu', mfvm1)
+VM2 = md.compute_isotropic_linearized_Von_Mises_or_Tresca('u2', 'clambdastar', 'cmu', mfvm2)
+
+mfvm1.export_to_vtk('displacement_with_von_mises1.vtk', mfvm1,  VM1, 'Von Mises Stresses', mfu1, U1, 'Displacements')
+
+mfvm2.export_to_vtk('displacement_with_von_mises2.vtk', mfvm2,  VM2, 'Von Mises Stresses', mfu2, U2, 'Displacements')
+print('You can view solutions with for instance:\nmayavi2 -d displacement_with_von_mises1.vtk -f WarpVector -m Surface -d displacement_with_von_mises2.vtk -f WarpVector -m Surface')
+
diff --git a/interface/tests/python/getfem_tvtk.py b/interface/tests/python/getfem_tvtk.py
index c37cfcc..9351738 100644
--- a/interface/tests/python/getfem_tvtk.py
+++ b/interface/tests/python/getfem_tvtk.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python
-# -*- coding: UTF8 -*-
+# -*- coding: utf-8 -*-
 # Python GetFEM++ interface
 #
-# Copyright (C) 2004-2009 Yves Renard, Julien Pommier.
+# Copyright (C) 2004-2017 Yves Renard, Julien Pommier.
 #
 # This file is a part of GetFEM++
 #
@@ -27,13 +27,13 @@
   It requires installation of the TVTK module from enthought
   https://svn.enthought.com/enthought/wiki/TVTK
 
-  $Id: getfem_tvtk.py 4918 2015-03-28 15:57:20Z renard $
+  $Id$
 """
 try:
     from tvtk.api import tvtk
 except:
-    print "\n\n** Could not load tvtk. Did you install it ?\n"
-    print "   ( https://svn.enthought.com/enthought/wiki/TVTK ) **\n\n"
+    print("\n\n** Could not load tvtk. Did you install it ?\n")
+    print("   ( https://svn.enthought.com/enthought/wiki/TVTK ) **\n\n")
     raise
 
 import os
@@ -216,7 +216,7 @@ class FigureItem:
                 scale = float(scale[:-1]) * 0.01 * a/b;
         P=P + scale * deform
         self.sl.set_pts(P)
-        #print "deformation!", repr(mf), U.size(), repr(self.sl), "\nDEFORM=",self.deform,"\n"
+        #print("deformation!", repr(mf), U.size(), repr(self.sl), "\nDEFORM=",self.deform,"\n")
         sys.stdout.flush()
 
 
@@ -510,7 +510,7 @@ class Figure:
 ##    E1.transpose()
 ##    edges=tvtk.PolyData(points=array(Pe),polys=array(E1))
 
-##    print mesh.get()
+##    print(mesh.get())
 
 
 ##    #data = array([[0,0,0,10], [1,0,0,20],
@@ -555,7 +555,7 @@ class Figure:
 ##    # across the entire range of colors
 ##    mapper = tvtk.PolyDataMapper(input=mesh);
 ##    mapper_edges = tvtk.PolyDataMapper(input=edges);
-##    print mapper
+##    print(mapper)
 
 ##    #mapper = tvtk.PolyDataMapper(input=mesh)
 ##    #mapper.scalar_range = min(temperature), max(temperature)
@@ -588,7 +588,7 @@ class Figure:
 ##    gui.start_event_loop()
 
 
-##    print "finished!"
+##    print("finished!")
 
 
 ##    #f=mlab.figure()
diff --git a/m4/Makefile.am b/m4/Makefile.am
old mode 100755
new mode 100644
index 447ae8a..6c1fbd7
--- a/m4/Makefile.am
+++ b/m4/Makefile.am
@@ -1,2 +1,19 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 EXTRA_DIST=acx_blas.m4  ax_check_cxx_flag.m4  ax_prefix_config_h.m4
 
diff --git a/m4/Makefile.in b/m4/Makefile.in
index c349033..e4f7132 100644
--- a/m4/Makefile.in
+++ b/m4/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -88,6 +95,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = m4
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -103,7 +112,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -128,7 +136,6 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -196,7 +203,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -229,8 +235,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -311,7 +319,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -336,6 +343,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu m4/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -510,8 +518,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/m4/ac_python_devel.m4 b/m4/ac_python_devel.m4
index d6495be..acfb21e 100644
--- a/m4/ac_python_devel.m4
+++ b/m4/ac_python_devel.m4
@@ -51,8 +51,8 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
 	#
 	AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
 	ac_supports_python_ver=`$PYTHON -c "import sys, string; \
-		ver = string.split(sys.version)[[0]]; \
-		print int(ver >= '2.1.0')"`
+		ver =(sys.version.split())[[0]]; \
+		print(int(ver >= '2.1.0'))"`
 	if test "$ac_supports_python_ver" != "1"; then
 		if test -z "$PYTHON_NOVERSIONCHECK"; then
 			AC_MSG_RESULT([no])
@@ -78,8 +78,8 @@ to something else than an empty string.
 	if test -n "$1"; then
 		AC_MSG_CHECKING([for a version of Python $1])
 		ac_supports_python_ver=`$PYTHON -c "import sys, string; \
-			ver = string.split(sys.version)[[0]]; \
-			print ver $1"`
+			ver = (sys.version.split())[[0]]; \
+			print(ver $1)"`
 		if test "$ac_supports_python_ver" = "True"; then
 	   	   AC_MSG_RESULT([yes])
 		else
@@ -113,7 +113,7 @@ $ac_distutils_result])
 	AC_MSG_CHECKING([for Python include path])
 	if test -z "$PYTHON_CPPFLAGS"; then
 		python_path=`$PYTHON -c "import distutils.sysconfig; \
-           		print distutils.sysconfig.get_python_inc();"`
+           		print(distutils.sysconfig.get_python_inc());"`
 		if test -n "${python_path}"; then
 		   	python_path="-I$python_path"
 		fi
@@ -130,21 +130,20 @@ $ac_distutils_result])
 		# (makes two attempts to ensure we've got a version number
 		# from the interpreter)
 		py_version=`$PYTHON -c "from distutils.sysconfig import *; \
-			from string import join; \
-			print join(get_config_vars('VERSION'))"`
+			import string; \
+			print(get_config_vars('VERSION')[[0]])"`
 		if test "$py_version" == "[None]"; then
 			if test -n "$PYTHON_VERSION"; then
 				py_version=$PYTHON_VERSION
 			else
 				py_version=`$PYTHON -c "import sys; \
-					print sys.version[[:3]]"`
+					print(sys.version[[:3]])"`
 			fi
 		fi
 
 		PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
-			from string import join; \
-			print '-L' + get_python_lib(0,1), \
-		      	'-lpython';"`$py_version
+			print('-L' + get_python_lib(0,1), \
+		      	'-lpython');"`$py_version
 	fi		
 	AC_MSG_RESULT([$PYTHON_LDFLAGS])
 	AC_SUBST([PYTHON_LDFLAGS])
@@ -155,7 +154,7 @@ $ac_distutils_result])
 	AC_MSG_CHECKING([for Python site-packages path])
 	if test -z "$PYTHON_SITE_PKG"; then
 		PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
-		        print distutils.sysconfig.get_python_lib(0,0);"`
+		        print(distutils.sysconfig.get_python_lib(0,0));"`
 	fi
 	AC_MSG_RESULT([$PYTHON_SITE_PKG])
 	AC_SUBST([PYTHON_SITE_PKG])
@@ -167,7 +166,7 @@ $ac_distutils_result])
 	if test -z "$PYTHON_EXTRA_LIBS"; then
 	   PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
                 conf = distutils.sysconfig.get_config_var; \
-                print conf('LOCALMODLIBS'), conf('LIBS')"`
+                print(conf('LOCALMODLIBS'), conf('LIBS'))"`
 	fi
 	AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
 	AC_SUBST(PYTHON_EXTRA_LIBS)
@@ -179,7 +178,7 @@ $ac_distutils_result])
 	if test -z "$PYTHON_EXTRA_LDFLAGS"; then
 		PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
 			conf = distutils.sysconfig.get_config_var; \
-			print conf('LINKFORSHARED')"`
+			print(conf('LINKFORSHARED'))"`
 	fi
 	AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
 	AC_SUBST(PYTHON_EXTRA_LDFLAGS)
diff --git a/m4/acx_blas.m4 b/m4/acx_blas.m4
old mode 100755
new mode 100644
index 048c78b..fd1cd69
--- a/m4/acx_blas.m4
+++ b/m4/acx_blas.m4
@@ -1,3 +1,7 @@
+dnl ACX_BLAS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+dnl @author Steven G. Johnson <stevenj at alum.mit.edu>
+dnl @license GPLWithACException
+
 AC_DEFUN([ACX_BLAS], [
 AC_PREREQ(2.50)
 
diff --git a/m4/ax_check_cxx_flag.m4 b/m4/ax_check_cxx_flag.m4
index e0f8d65..8a288d3 100644
--- a/m4/ax_check_cxx_flag.m4
+++ b/m4/ax_check_cxx_flag.m4
@@ -1,5 +1,18 @@
-dnl based on http://www.gnu.org/software/ac-archive/htmldoc/ac_check_cc_opt.html
-dnl from Guido Draheim <guidod at gmx.de>
+dnl Copyright (C) 2004-2017 Julien Pommier
+dnl 
+dnl This file is  free software;  you  can  redistribute  it  and/or modify it
+dnl under  the  terms  of the  GNU  Lesser General Public License as published
+dnl by  the  Free Software Foundation;  either version 3 of the License,  or
+dnl (at your option) any later version along with the GCC Runtime Library
+dnl Exception either version 3.1 or (at your option) any later version.
+dnl This program  is  distributed  in  the  hope  that it will be useful,  but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or  FITNESS  FOR  A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+dnl License and GCC Runtime Library Exception for more details.
+dnl You  should  have received a copy of the GNU Lesser General Public License
+dnl along  with  this program;  if not, write to the Free Software Foundation,
+dnl Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 AC_DEFUN([AC_CHECK_CXX_FLAG],
 [AC_MSG_CHECKING([whether ${CXX} accepts $1])
 
diff --git a/m4/ax_prefix_config_h.m4 b/m4/ax_prefix_config_h.m4
old mode 100755
new mode 100644
index a3773cc..2c662ef
--- a/m4/ax_prefix_config_h.m4
+++ b/m4/ax_prefix_config_h.m4
@@ -79,9 +79,10 @@ dnl   #ifndef _testpkg_const
 dnl   #define _testpkg_const const
 dnl   #endif
 dnl
-dnl @version $Id: ax_prefix_config_h.m4 1867 2005-01-27 14:04:04Z pommier $
+dnl @version $Id$
 dnl @author  Guiodo Draheim <guidod at gmx.de>
-dnl
+dnl @License GPLV3
+
 AC_DEFUN([AX_PREFIX_CONFIG_H],[AC_REQUIRE([AC_CONFIG_HEADER])
 AC_CONFIG_COMMANDS([ifelse($1,,$PACKAGE-config.h,$1)],[dnl
 AS_VAR_PUSHDEF([_OUT],[ac_prefix_conf_OUT])dnl
diff --git a/m4/libtool.m4 b/m4/libtool.m4
index 10ab284..d7c043f 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -1,6 +1,8 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
-#   Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 # This file is free software; the Free Software Foundation gives
@@ -8,30 +10,36 @@
 # modifications, as long as this notice is preserved.
 
 m4_define([_LT_COPYING], [dnl
-# Copyright (C) 2014 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions.  There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# GNU Libtool is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
-# (at your option) any later version.
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
 #
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program or library that is built
-# using GNU Libtool, you may include this file under the  same
-# distribution terms that you use for the rest of that program.
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
 #
-# GNU Libtool is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
+# GNU Libtool 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 General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 ])
 
-# serial 58 LT_INIT
+# serial 57 LT_INIT
 
 
 # LT_PREREQ(VERSION)
@@ -59,7 +67,7 @@ esac
 # LT_INIT([OPTIONS])
 # ------------------
 AC_DEFUN([LT_INIT],
-[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
 AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
 AC_BEFORE([$0], [LT_LANG])dnl
 AC_BEFORE([$0], [LT_OUTPUT])dnl
@@ -83,7 +91,7 @@ dnl Parse OPTIONS
 _LT_SET_OPTIONS([$0], [$1])
 
 # This can be used to rebuild libtool when needed
-LIBTOOL_DEPS=$ltmain
+LIBTOOL_DEPS="$ltmain"
 
 # Always use our own libtool.
 LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -103,43 +111,26 @@ dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
 dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
 
 
-# _LT_PREPARE_CC_BASENAME
-# -----------------------
-m4_defun([_LT_PREPARE_CC_BASENAME], [
-# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
-func_cc_basename ()
-{
-    for cc_temp in @S|@*""; do
-      case $cc_temp in
-        compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
-        distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
-        \-*) ;;
-        *) break;;
-      esac
-    done
-    func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
-}
-])# _LT_PREPARE_CC_BASENAME
-
-
 # _LT_CC_BASENAME(CC)
 # -------------------
-# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
-# but that macro is also expanded into generated libtool script, which
-# arranges for $SED and $ECHO to be set by different means.
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
 m4_defun([_LT_CC_BASENAME],
-[m4_require([_LT_PREPARE_CC_BASENAME])dnl
-AC_REQUIRE([_LT_DECL_SED])dnl
-AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
-func_cc_basename $1
-cc_basename=$func_cc_basename_result
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 ])
 
 
 # _LT_FILEUTILS_DEFAULTS
 # ----------------------
 # It is okay to use these file commands and assume they have been set
-# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
 m4_defun([_LT_FILEUTILS_DEFAULTS],
 [: ${CP="cp -f"}
 : ${MV="mv -f"}
@@ -186,16 +177,15 @@ m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
 m4_require([_LT_CMD_OLD_ARCHIVE])dnl
 m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
 m4_require([_LT_WITH_SYSROOT])dnl
-m4_require([_LT_CMD_TRUNCATE])dnl
 
 _LT_CONFIG_LIBTOOL_INIT([
-# See if we are running on zsh, and set the options that allow our
+# See if we are running on zsh, and set the options which allow our
 # commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}"; then
+if test -n "\${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 ])
-if test -n "${ZSH_VERSION+set}"; then
+if test -n "${ZSH_VERSION+set}" ; then
    setopt NO_GLOB_SUBST
 fi
 
@@ -208,7 +198,7 @@ aix3*)
   # AIX sometimes has problems with the GCC collect2 program.  For some
   # reason, if we set the COLLECT_NAMES environment variable, the problems
   # vanish in a puff of smoke.
-  if test set != "${COLLECT_NAMES+set}"; then
+  if test "X${COLLECT_NAMES+set}" != Xset; then
     COLLECT_NAMES=
     export COLLECT_NAMES
   fi
@@ -219,14 +209,14 @@ esac
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
 # which needs '.lib').
 libext=a
 
-with_gnu_ld=$lt_cv_prog_gnu_ld
+with_gnu_ld="$lt_cv_prog_gnu_ld"
 
-old_CC=$CC
-old_CFLAGS=$CFLAGS
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
 
 # Set sane defaults for various variables
 test -z "$CC" && CC=cc
@@ -279,14 +269,14 @@ no_glob_subst='s/\*/\\\*/g'
 
 # _LT_PROG_LTMAIN
 # ---------------
-# Note that this code is called both from 'configure', and 'config.status'
+# Note that this code is called both from `configure', and `config.status'
 # now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
-# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
 # so we pass a copy along to make sure it has a sensible value anyway.
 m4_defun([_LT_PROG_LTMAIN],
 [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
 _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
-ltmain=$ac_aux_dir/ltmain.sh
+ltmain="$ac_aux_dir/ltmain.sh"
 ])# _LT_PROG_LTMAIN
 
 
@@ -296,7 +286,7 @@ ltmain=$ac_aux_dir/ltmain.sh
 
 # So that we can recreate a full libtool script including additional
 # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
-# in macros and then make a single call at the end using the 'libtool'
+# in macros and then make a single call at the end using the `libtool'
 # label.
 
 
@@ -431,8 +421,8 @@ m4_define([_lt_decl_all_varnames],
 
 # _LT_CONFIG_STATUS_DECLARE([VARNAME])
 # ------------------------------------
-# Quote a variable value, and forward it to 'config.status' so that its
-# declaration there will have the same value as in 'configure'.  VARNAME
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
 # must have a single quote delimited value for this to work.
 m4_define([_LT_CONFIG_STATUS_DECLARE],
 [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
@@ -456,7 +446,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
 # Output comment and list of tags supported by the script
 m4_defun([_LT_LIBTOOL_TAGS],
 [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
-available_tags='_LT_TAGS'dnl
+available_tags="_LT_TAGS"dnl
 ])
 
 
@@ -484,7 +474,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
 # _LT_LIBTOOL_CONFIG_VARS
 # -----------------------
 # Produce commented declarations of non-tagged libtool config variables
-# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
 # script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
 # section) are produced by _LT_LIBTOOL_TAG_VARS.
 m4_defun([_LT_LIBTOOL_CONFIG_VARS],
@@ -510,8 +500,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
 # Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
 # variables for single and double quote escaping we saved from calls
 # to _LT_DECL, we can put quote escaped variables declarations
-# into 'config.status', and then the shell code to quote escape them in
-# for loops in 'config.status'.  Finally, any additional code accumulated
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
 # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
 m4_defun([_LT_CONFIG_COMMANDS],
 [AC_PROVIDE_IFELSE([LT_OUTPUT],
@@ -557,7 +547,7 @@ for var in lt_decl_all_varnames([[ \
 ]], lt_decl_quote_varnames); do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -570,7 +560,7 @@ for var in lt_decl_all_varnames([[ \
 ]], lt_decl_dquote_varnames); do
     case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -586,7 +576,7 @@ _LT_OUTPUT_LIBTOOL_INIT
 # Generate a child script FILE with all initialization necessary to
 # reuse the environment learned by the parent script, and make the
 # file executable.  If COMMENT is supplied, it is inserted after the
-# '#!' sequence but before initialization text begins.  After this
+# `#!' sequence but before initialization text begins.  After this
 # macro, additional text can be appended to FILE to form the body of
 # the child script.  The macro ends with non-zero status if the
 # file could not be fully written (such as if the disk is full).
@@ -608,7 +598,7 @@ AS_SHELL_SANITIZE
 _AS_PREPARE
 exec AS_MESSAGE_FD>&1
 _ASEOF
-test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+test $lt_write_fail = 0 && chmod +x $1[]dnl
 m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
 
 # LT_OUTPUT
@@ -631,7 +621,7 @@ exec AS_MESSAGE_LOG_FD>>config.log
 } >&AS_MESSAGE_LOG_FD
 
 lt_cl_help="\
-'$as_me' creates a local libtool stub from the current configuration,
+\`$as_me' creates a local libtool stub from the current configuration,
 for use in further configure time tests before the real libtool is
 generated.
 
@@ -653,7 +643,7 @@ Copyright (C) 2011 Free Software Foundation, Inc.
 This config.lt script is free software; the Free Software Foundation
 gives unlimited permision to copy, distribute and modify it."
 
-while test 0 != $[#]
+while test $[#] != 0
 do
   case $[1] in
     --version | --v* | -V )
@@ -666,10 +656,10 @@ do
       lt_cl_silent=: ;;
 
     -*) AC_MSG_ERROR([unrecognized option: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
 
     *) AC_MSG_ERROR([unrecognized argument: $[1]
-Try '$[0] --help' for more information.]) ;;
+Try \`$[0] --help' for more information.]) ;;
   esac
   shift
 done
@@ -695,7 +685,7 @@ chmod +x "$CONFIG_LT"
 # open by configure.  Here we exec the FD to /dev/null, effectively closing
 # config.log, so it can be properly (re)opened and appended to by config.lt.
 lt_cl_success=:
-test yes = "$silent" &&
+test "$silent" = yes &&
   lt_config_lt_args="$lt_config_lt_args --quiet"
 exec AS_MESSAGE_LOG_FD>/dev/null
 $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
@@ -715,31 +705,27 @@ m4_defun([_LT_CONFIG],
 _LT_CONFIG_SAVE_COMMANDS([
   m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
   m4_if(_LT_TAG, [C], [
-    # See if we are running on zsh, and set the options that allow our
+    # See if we are running on zsh, and set the options which allow our
     # commands through without removal of \ escapes.
-    if test -n "${ZSH_VERSION+set}"; then
+    if test -n "${ZSH_VERSION+set}" ; then
       setopt NO_GLOB_SUBST
     fi
 
-    cfgfile=${ofile}T
+    cfgfile="${ofile}T"
     trap "$RM \"$cfgfile\"; exit 1" 1 2 15
     $RM "$cfgfile"
 
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
-# Generated automatically by $as_me ($PACKAGE) $VERSION
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
 # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
-
-# Provide generalized library-building support services.
-# Written by Gordon Matzigkeit, 1996
-
+#
 _LT_COPYING
 _LT_LIBTOOL_TAGS
 
-# Configured defaults for sys_lib_dlsearch_path munging.
-: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
-
 # ### BEGIN LIBTOOL CONFIG
 _LT_LIBTOOL_CONFIG_VARS
 _LT_LIBTOOL_TAG_VARS
@@ -747,24 +733,13 @@ _LT_LIBTOOL_TAG_VARS
 
 _LT_EOF
 
-    cat <<'_LT_EOF' >> "$cfgfile"
-
-# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_PREPARE_MUNGE_PATH_LIST
-_LT_PREPARE_CC_BASENAME
-
-# ### END FUNCTIONS SHARED WITH CONFIGURE
-
-_LT_EOF
-
   case $host_os in
   aix3*)
     cat <<\_LT_EOF >> "$cfgfile"
 # AIX sometimes has problems with the GCC collect2 program.  For some
 # reason, if we set the COLLECT_NAMES environment variable, the problems
 # vanish in a puff of smoke.
-if test set != "${COLLECT_NAMES+set}"; then
+if test "X${COLLECT_NAMES+set}" != Xset; then
   COLLECT_NAMES=
   export COLLECT_NAMES
 fi
@@ -781,6 +756,8 @@ _LT_EOF
   sed '$q' "$ltmain" >> "$cfgfile" \
      || (rm -f "$cfgfile"; exit 1)
 
+  _LT_PROG_REPLACE_SHELLFNS
+
    mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
@@ -798,6 +775,7 @@ _LT_EOF
 [m4_if([$1], [], [
     PACKAGE='$PACKAGE'
     VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
     RM='$RM'
     ofile='$ofile'], [])
 ])dnl /_LT_CONFIG_SAVE_COMMANDS
@@ -996,7 +974,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 
     AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
       [lt_cv_apple_cc_single_mod=no
-      if test -z "$LT_MULTI_MODULE"; then
+      if test -z "${LT_MULTI_MODULE}"; then
 	# By default we will add the -single_module flag. You can override
 	# by either setting the environment variable LT_MULTI_MODULE
 	# non-empty at configure time, or by adding -multi_module to the
@@ -1014,7 +992,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 	  cat conftest.err >&AS_MESSAGE_LOG_FD
 	# Otherwise, if the output was created with a 0 exit code from
 	# the compiler, it worked.
-	elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
 	  lt_cv_apple_cc_single_mod=yes
 	else
 	  cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1032,7 +1010,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
       AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
 	[lt_cv_ld_exported_symbols_list=yes],
 	[lt_cv_ld_exported_symbols_list=no])
-	LDFLAGS=$save_LDFLAGS
+	LDFLAGS="$save_LDFLAGS"
     ])
 
     AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
@@ -1054,7 +1032,7 @@ _LT_EOF
       _lt_result=$?
       if test -s conftest.err && $GREP force_load conftest.err; then
 	cat conftest.err >&AS_MESSAGE_LOG_FD
-      elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
 	lt_cv_ld_force_load=yes
       else
 	cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1064,32 +1042,32 @@ _LT_EOF
     ])
     case $host_os in
     rhapsody* | darwin1.[[012]])
-      _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
     darwin1.*)
-      _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
     darwin*) # darwin 5.x on
       # if running on 10.5 or later, the deployment target defaults
       # to the OS version, if on x86, and 10.4, the deployment
       # target defaults to 10.4. Don't you love it?
       case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
 	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
-	10.[[012]][[,.]]*)
-	  _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
 	10.*)
-	  _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
       esac
     ;;
   esac
-    if test yes = "$lt_cv_apple_cc_single_mod"; then
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
       _lt_dar_single_mod='$single_module'
     fi
-    if test yes = "$lt_cv_ld_exported_symbols_list"; then
-      _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
     else
-      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
     fi
-    if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
       _lt_dsymutil='~$DSYMUTIL $lib || :'
     else
       _lt_dsymutil=
@@ -1109,29 +1087,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
   _LT_TAGVAR(hardcode_direct, $1)=no
   _LT_TAGVAR(hardcode_automatic, $1)=yes
   _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-  if test yes = "$lt_cv_ld_force_load"; then
-    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
     m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
                   [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
   else
     _LT_TAGVAR(whole_archive_flag_spec, $1)=''
   fi
   _LT_TAGVAR(link_all_deplibs, $1)=yes
-  _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
   case $cc_basename in
-     ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+     ifort*) _lt_dar_can_shared=yes ;;
      *) _lt_dar_can_shared=$GCC ;;
   esac
-  if test yes = "$_lt_dar_can_shared"; then
+  if test "$_lt_dar_can_shared" = "yes"; then
     output_verbose_link_cmd=func_echo_all
-    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
-    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
-    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
-    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
     m4_if([$1], [CXX],
-[   if test yes != "$lt_cv_apple_cc_single_mod"; then
-      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
-      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
     fi
 ],[])
   else
@@ -1151,7 +1129,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
 # Allow to override them for all tags through lt_cv_aix_libpath.
 m4_defun([_LT_SYS_MODULE_PATH_AIX],
 [m4_require([_LT_DECL_SED])dnl
-if test set = "${lt_cv_aix_libpath+set}"; then
+if test "${lt_cv_aix_libpath+set}" = set; then
   aix_libpath=$lt_cv_aix_libpath
 else
   AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
@@ -1169,7 +1147,7 @@ else
     _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
   fi],[])
   if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
-    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
   fi
   ])
   aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
@@ -1189,8 +1167,8 @@ m4_define([_LT_SHELL_INIT],
 # -----------------------
 # Find how we can fake an echo command that does not interpret backslash.
 # In particular, with Autoconf 2.60 or later we add some code to the start
-# of the generated configure script that will find a shell with a builtin
-# printf (that we can use as an echo command).
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
 m4_defun([_LT_PROG_ECHO_BACKSLASH],
 [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
 ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
@@ -1218,10 +1196,10 @@ fi
 # Invoke $ECHO with all args, space-separated.
 func_echo_all ()
 {
-    $ECHO "$*"
+    $ECHO "$*" 
 }
 
-case $ECHO in
+case "$ECHO" in
   printf*) AC_MSG_RESULT([printf]) ;;
   print*) AC_MSG_RESULT([print -r]) ;;
   *) AC_MSG_RESULT([cat]) ;;
@@ -1247,17 +1225,16 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
 AC_DEFUN([_LT_WITH_SYSROOT],
 [AC_MSG_CHECKING([for sysroot])
 AC_ARG_WITH([sysroot],
-[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
-  [Search for dependent libraries within DIR (or the compiler's sysroot
-   if not specified).])],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
 [], [with_sysroot=no])
 
 dnl lt_sysroot will always be passed unquoted.  We quote it here
 dnl in case the user passed a directory name.
 lt_sysroot=
-case $with_sysroot in #(
+case ${with_sysroot} in #(
  yes)
-   if test yes = "$GCC"; then
+   if test "$GCC" = yes; then
      lt_sysroot=`$CC --print-sysroot 2>/dev/null`
    fi
    ;; #(
@@ -1267,14 +1244,14 @@ case $with_sysroot in #(
  no|'')
    ;; #(
  *)
-   AC_MSG_RESULT([$with_sysroot])
+   AC_MSG_RESULT([${with_sysroot}])
    AC_MSG_ERROR([The sysroot must be an absolute path.])
    ;;
 esac
 
  AC_MSG_RESULT([${lt_sysroot:-no}])
 _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
-[dependent libraries, and where our libraries should be installed.])])
+[dependent libraries, and in which our libraries should be installed.])])
 
 # _LT_ENABLE_LOCK
 # ---------------
@@ -1282,33 +1259,31 @@ m4_defun([_LT_ENABLE_LOCK],
 [AC_ARG_ENABLE([libtool-lock],
   [AS_HELP_STRING([--disable-libtool-lock],
     [avoid locking (might break parallel builds)])])
-test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 
 # Some flags need to be propagated to the compiler or linker for good
 # libtool support.
 case $host in
 ia64-*-hpux*)
-  # Find out what ABI is being produced by ac_compile, and set mode
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.$ac_objext` in
       *ELF-32*)
-	HPUX_IA64_MODE=32
+	HPUX_IA64_MODE="32"
 	;;
       *ELF-64*)
-	HPUX_IA64_MODE=64
+	HPUX_IA64_MODE="64"
 	;;
     esac
   fi
   rm -rf conftest*
   ;;
 *-*-irix6*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
-    if test yes = "$lt_cv_prog_gnu_ld"; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
       case `/usr/bin/file conftest.$ac_objext` in
 	*32-bit*)
 	  LD="${LD-ld} -melf32bsmip"
@@ -1337,46 +1312,9 @@ ia64-*-hpux*)
   rm -rf conftest*
   ;;
 
-mips64*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
-  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
-  if AC_TRY_EVAL(ac_compile); then
-    emul=elf
-    case `/usr/bin/file conftest.$ac_objext` in
-      *32-bit*)
-	emul="${emul}32"
-	;;
-      *64-bit*)
-	emul="${emul}64"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *MSB*)
-	emul="${emul}btsmip"
-	;;
-      *LSB*)
-	emul="${emul}ltsmip"
-	;;
-    esac
-    case `/usr/bin/file conftest.$ac_objext` in
-      *N32*)
-	emul="${emul}n32"
-	;;
-    esac
-    LD="${LD-ld} -m $emul"
-  fi
-  rm -rf conftest*
-  ;;
-
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
 s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.  Note that the listed cases only cover the
-  # situations where additional linker options are needed (such as when
-  # doing 32-bit compilation for a host where ld defaults to 64-bit, or
-  # vice versa); the common cases where no linker options are needed do
-  # not appear in the list.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
@@ -1395,10 +1333,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 		;;
 	    esac
 	    ;;
-	  powerpc64le-*linux*)
+	  powerpc64le-*)
 	    LD="${LD-ld} -m elf32lppclinux"
 	    ;;
-	  powerpc64-*linux*)
+	  powerpc64-*)
 	    LD="${LD-ld} -m elf32ppclinux"
 	    ;;
 	  s390x-*linux*)
@@ -1417,10 +1355,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 	  x86_64-*linux*)
 	    LD="${LD-ld} -m elf_x86_64"
 	    ;;
-	  powerpcle-*linux*)
+	  powerpcle-*)
 	    LD="${LD-ld} -m elf64lppc"
 	    ;;
-	  powerpc-*linux*)
+	  powerpc-*)
 	    LD="${LD-ld} -m elf64ppc"
 	    ;;
 	  s390*-*linux*|s390*-*tpf*)
@@ -1438,20 +1376,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 
 *-*-sco3.2v5*)
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
-  SAVE_CFLAGS=$CFLAGS
+  SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
     [AC_LANG_PUSH(C)
      AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
      AC_LANG_POP])
-  if test yes != "$lt_cv_cc_needs_belf"; then
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
     # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
-    CFLAGS=$SAVE_CFLAGS
+    CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
 *-*solaris*)
-  # Find out what ABI is being produced by ac_compile, and set linker
-  # options accordingly.
+  # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
@@ -1459,7 +1396,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
       case $lt_cv_prog_gnu_ld in
       yes*)
         case $host in
-        i?86-*-solaris*|x86_64-*-solaris*)
+        i?86-*-solaris*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
         sparc*-*-solaris*)
@@ -1468,7 +1405,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
         esac
         # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
         if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
-          LD=${LD-ld}_sol2
+          LD="${LD-ld}_sol2"
         fi
         ;;
       *)
@@ -1484,7 +1421,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
   ;;
 esac
 
-need_locks=$enable_libtool_lock
+need_locks="$enable_libtool_lock"
 ])# _LT_ENABLE_LOCK
 
 
@@ -1503,11 +1440,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
      [echo conftest.$ac_objext > conftest.lst
       lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
       AC_TRY_EVAL([lt_ar_try])
-      if test 0 -eq "$ac_status"; then
+      if test "$ac_status" -eq 0; then
 	# Ensure the archiver fails upon bogus file names.
 	rm -f conftest.$ac_objext libconftest.a
 	AC_TRY_EVAL([lt_ar_try])
-	if test 0 -ne "$ac_status"; then
+	if test "$ac_status" -ne 0; then
           lt_cv_ar_at_file=@
         fi
       fi
@@ -1515,7 +1452,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
      ])
   ])
 
-if test no = "$lt_cv_ar_at_file"; then
+if test "x$lt_cv_ar_at_file" = xno; then
   archiver_list_spec=
 else
   archiver_list_spec=$lt_cv_ar_at_file
@@ -1546,7 +1483,7 @@ old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
   case $host_os in
-  bitrig* | openbsd*)
+  openbsd*)
     old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
@@ -1582,7 +1519,7 @@ AC_CACHE_CHECK([$1], [$2],
   [$2=no
    m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-   lt_compiler_flag="$3"  ## exclude from sc_useless_quotes_in_assignment
+   lt_compiler_flag="$3"
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
@@ -1609,7 +1546,7 @@ AC_CACHE_CHECK([$1], [$2],
    $RM conftest*
 ])
 
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
     m4_if([$5], , :, [$5])
 else
     m4_if([$6], , :, [$6])
@@ -1631,7 +1568,7 @@ AC_DEFUN([_LT_LINKER_OPTION],
 m4_require([_LT_DECL_SED])dnl
 AC_CACHE_CHECK([$1], [$2],
   [$2=no
-   save_LDFLAGS=$LDFLAGS
+   save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS $3"
    echo "$lt_simple_link_test_code" > conftest.$ac_ext
    if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -1650,10 +1587,10 @@ AC_CACHE_CHECK([$1], [$2],
      fi
    fi
    $RM -r conftest*
-   LDFLAGS=$save_LDFLAGS
+   LDFLAGS="$save_LDFLAGS"
 ])
 
-if test yes = "[$]$2"; then
+if test x"[$]$2" = xyes; then
     m4_if([$4], , :, [$4])
 else
     m4_if([$5], , :, [$5])
@@ -1674,7 +1611,7 @@ AC_DEFUN([LT_CMD_MAX_LEN],
 AC_MSG_CHECKING([the maximum length of command line arguments])
 AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
   i=0
-  teststring=ABCD
+  teststring="ABCD"
 
   case $build_os in
   msdosdjgpp*)
@@ -1714,7 +1651,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -1765,22 +1702,22 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
   *)
     lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
     if test -n "$lt_cv_sys_max_cmd_len" && \
-       test undefined != "$lt_cv_sys_max_cmd_len"; then
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
       lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
     else
       # Make teststring a little bigger before we do anything with it.
       # a 1K string should be a reasonable start.
-      for i in 1 2 3 4 5 6 7 8; do
+      for i in 1 2 3 4 5 6 7 8 ; do
         teststring=$teststring$teststring
       done
       SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
 	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
-	      test 17 != "$i" # 1/2 MB should be enough
+	      test $i != 17 # 1/2 MB should be enough
       do
         i=`expr $i + 1`
         teststring=$teststring$teststring
@@ -1796,7 +1733,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     ;;
   esac
 ])
-if test -n "$lt_cv_sys_max_cmd_len"; then
+if test -n $lt_cv_sys_max_cmd_len ; then
   AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
 else
   AC_MSG_RESULT(none)
@@ -1824,7 +1761,7 @@ m4_defun([_LT_HEADER_DLFCN],
 # ----------------------------------------------------------------
 m4_defun([_LT_TRY_DLOPEN_SELF],
 [m4_require([_LT_HEADER_DLFCN])dnl
-if test yes = "$cross_compiling"; then :
+if test "$cross_compiling" = yes; then :
   [$4]
 else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -1871,9 +1808,9 @@ else
 #  endif
 #endif
 
-/* When -fvisibility=hidden is used, assume the code has been annotated
+/* When -fvisbility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 int fnord () __attribute__((visibility("default")));
 #endif
 
@@ -1899,7 +1836,7 @@ int main ()
   return status;
 }]
 _LT_EOF
-  if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
     (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
     lt_status=$?
     case x$lt_status in
@@ -1920,7 +1857,7 @@ rm -fr conftest*
 # ------------------
 AC_DEFUN([LT_SYS_DLOPEN_SELF],
 [m4_require([_LT_HEADER_DLFCN])dnl
-if test yes != "$enable_dlopen"; then
+if test "x$enable_dlopen" != xyes; then
   enable_dlopen=unknown
   enable_dlopen_self=unknown
   enable_dlopen_self_static=unknown
@@ -1930,52 +1867,44 @@ else
 
   case $host_os in
   beos*)
-    lt_cv_dlopen=load_add_on
+    lt_cv_dlopen="load_add_on"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ;;
 
   mingw* | pw32* | cegcc*)
-    lt_cv_dlopen=LoadLibrary
+    lt_cv_dlopen="LoadLibrary"
     lt_cv_dlopen_libs=
     ;;
 
   cygwin*)
-    lt_cv_dlopen=dlopen
+    lt_cv_dlopen="dlopen"
     lt_cv_dlopen_libs=
     ;;
 
   darwin*)
-    # if libdl is installed we need to link against it
+  # if libdl is installed we need to link against it
     AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
-    lt_cv_dlopen=dyld
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
     lt_cv_dlopen_libs=
     lt_cv_dlopen_self=yes
     ])
     ;;
 
-  tpf*)
-    # Don't try to run any link tests for TPF.  We know it's impossible
-    # because TPF is a cross-compiler, and we know how we open DSOs.
-    lt_cv_dlopen=dlopen
-    lt_cv_dlopen_libs=
-    lt_cv_dlopen_self=no
-    ;;
-
   *)
     AC_CHECK_FUNC([shl_load],
-	  [lt_cv_dlopen=shl_load],
+	  [lt_cv_dlopen="shl_load"],
       [AC_CHECK_LIB([dld], [shl_load],
-	    [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
 	[AC_CHECK_FUNC([dlopen],
-	      [lt_cv_dlopen=dlopen],
+	      [lt_cv_dlopen="dlopen"],
 	  [AC_CHECK_LIB([dl], [dlopen],
-		[lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
 	    [AC_CHECK_LIB([svld], [dlopen],
-		  [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
 	      [AC_CHECK_LIB([dld], [dld_link],
-		    [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
 	      ])
 	    ])
 	  ])
@@ -1984,21 +1913,21 @@ else
     ;;
   esac
 
-  if test no = "$lt_cv_dlopen"; then
-    enable_dlopen=no
-  else
+  if test "x$lt_cv_dlopen" != xno; then
     enable_dlopen=yes
+  else
+    enable_dlopen=no
   fi
 
   case $lt_cv_dlopen in
   dlopen)
-    save_CPPFLAGS=$CPPFLAGS
-    test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
 
-    save_LDFLAGS=$LDFLAGS
+    save_LDFLAGS="$LDFLAGS"
     wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
 
-    save_LIBS=$LIBS
+    save_LIBS="$LIBS"
     LIBS="$lt_cv_dlopen_libs $LIBS"
 
     AC_CACHE_CHECK([whether a program can dlopen itself],
@@ -2008,7 +1937,7 @@ else
 	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
     ])
 
-    if test yes = "$lt_cv_dlopen_self"; then
+    if test "x$lt_cv_dlopen_self" = xyes; then
       wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
       AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
 	  lt_cv_dlopen_self_static, [dnl
@@ -2018,9 +1947,9 @@ else
       ])
     fi
 
-    CPPFLAGS=$save_CPPFLAGS
-    LDFLAGS=$save_LDFLAGS
-    LIBS=$save_LIBS
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
     ;;
   esac
 
@@ -2112,8 +2041,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS],
 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 _LT_COMPILER_C_O([$1])
 
-hard_links=nottested
-if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
   # do not overwrite the value of need_locks provided by the user
   AC_MSG_CHECKING([if we can lock with hard links])
   hard_links=yes
@@ -2123,8 +2052,8 @@ if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_loc
   ln conftest.a conftest.b 2>&5 || hard_links=no
   ln conftest.a conftest.b 2>/dev/null && hard_links=no
   AC_MSG_RESULT([$hard_links])
-  if test no = "$hard_links"; then
-    AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
     need_locks=warn
   fi
 else
@@ -2151,8 +2080,8 @@ objdir=$lt_cv_objdir
 _LT_DECL([], [objdir], [0],
          [The name of the directory that contains temporary libtool files])dnl
 m4_pattern_allow([LT_OBJDIR])dnl
-AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
-  [Define to the sub-directory where libtool stores uninstalled libraries.])
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
 ])# _LT_CHECK_OBJDIR
 
 
@@ -2164,15 +2093,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
 _LT_TAGVAR(hardcode_action, $1)=
 if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
    test -n "$_LT_TAGVAR(runpath_var, $1)" ||
-   test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
 
   # We can hardcode non-existent directories.
-  if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
      # If the only mechanism to avoid hardcoding is shlibpath_var, we
      # have to relink, otherwise we might link with an installed library
      # when we should be linking with a yet-to-be-installed one
-     ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
-     test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
     # Linking always hardcodes the temporary library directory.
     _LT_TAGVAR(hardcode_action, $1)=relink
   else
@@ -2186,12 +2115,12 @@ else
 fi
 AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
 
-if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
-   test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
   # Fast installation is not supported
   enable_fast_install=no
-elif test yes = "$shlibpath_overrides_runpath" ||
-     test no = "$enable_shared"; then
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
   # Fast installation is not necessary
   enable_fast_install=needless
 fi
@@ -2215,7 +2144,7 @@ else
 # FIXME - insert some real tests, host_os isn't really good enough
   case $host_os in
   darwin*)
-    if test -n "$STRIP"; then
+    if test -n "$STRIP" ; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       AC_MSG_RESULT([yes])
@@ -2233,47 +2162,6 @@ _LT_DECL([], [striplib], [1])
 ])# _LT_CMD_STRIPLIB
 
 
-# _LT_PREPARE_MUNGE_PATH_LIST
-# ---------------------------
-# Make sure func_munge_path_list() is defined correctly.
-m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
-[[# func_munge_path_list VARIABLE PATH
-# -----------------------------------
-# VARIABLE is name of variable containing _space_ separated list of
-# directories to be munged by the contents of PATH, which is string
-# having a format:
-# "DIR[:DIR]:"
-#       string "DIR[ DIR]" will be prepended to VARIABLE
-# ":DIR[:DIR]"
-#       string "DIR[ DIR]" will be appended to VARIABLE
-# "DIRP[:DIRP]::[DIRA:]DIRA"
-#       string "DIRP[ DIRP]" will be prepended to VARIABLE and string
-#       "DIRA[ DIRA]" will be appended to VARIABLE
-# "DIR[:DIR]"
-#       VARIABLE will be replaced by "DIR[ DIR]"
-func_munge_path_list ()
-{
-    case x at S|@2 in
-    x)
-        ;;
-    *:)
-        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
-        ;;
-    x:*)
-        eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
-        ;;
-    *::*)
-        eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
-        eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
-        ;;
-    *)
-        eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
-        ;;
-    esac
-}
-]])# _LT_PREPARE_PATH_LIST
-
-
 # _LT_SYS_DYNAMIC_LINKER([TAG])
 # -----------------------------
 # PORTME Fill in your ld.so characteristics
@@ -2284,18 +2172,17 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_OBJDUMP])dnl
 m4_require([_LT_DECL_SED])dnl
 m4_require([_LT_CHECK_SHELL_FEATURES])dnl
-m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
 AC_MSG_CHECKING([dynamic linker characteristics])
 m4_if([$1],
 	[], [
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $host_os in
-    darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
-    *) lt_awk_arg='/^libraries:/' ;;
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
   esac
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
-    *) lt_sed_strip_eq='s|=/|/|g' ;;
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
   case $lt_search_path_spec in
@@ -2311,35 +2198,28 @@ if test yes = "$GCC"; then
     ;;
   esac
   # Ok, now we have the path, separated by spaces, we can step through it
-  # and add multilib dir if necessary...
+  # and add multilib dir if necessary.
   lt_tmp_lt_search_path_spec=
-  lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
-  # ...but if some path component already ends with the multilib dir we assume
-  # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
-  case "$lt_multi_os_dir; $lt_search_path_spec " in
-  "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
-    lt_multi_os_dir=
-    ;;
-  esac
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
   for lt_sys_path in $lt_search_path_spec; do
-    if test -d "$lt_sys_path$lt_multi_os_dir"; then
-      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
-    elif test -n "$lt_multi_os_dir"; then
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
       test -d "$lt_sys_path" && \
 	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
   lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS = " "; FS = "/|\n";} {
-  lt_foo = "";
-  lt_count = 0;
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
   for (lt_i = NF; lt_i > 0; lt_i--) {
     if ($lt_i != "" && $lt_i != ".") {
       if ($lt_i == "..") {
         lt_count++;
       } else {
         if (lt_count == 0) {
-          lt_foo = "/" $lt_i lt_foo;
+          lt_foo="/" $lt_i lt_foo;
         } else {
           lt_count--;
         }
@@ -2353,7 +2233,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # for these hosts.
   case $host_os in
     mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
-      $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
@@ -2362,7 +2242,7 @@ fi])
 library_names_spec=
 libname_spec='lib$name'
 soname_spec=
-shrext_cmds=.so
+shrext_cmds=".so"
 postinstall_cmds=
 postuninstall_cmds=
 finish_cmds=
@@ -2379,17 +2259,14 @@ hardcode_into_libs=no
 # flags to be left without arguments
 need_version=unknown
 
-AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
-[User-defined run-time library search path.])
-
 case $host_os in
 aix3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
   # AIX 3 has no versioning support, so we append a major version to the name.
-  soname_spec='$libname$release$shared_ext$major'
+  soname_spec='${libname}${release}${shared_ext}$major'
   ;;
 
 aix[[4-9]]*)
@@ -2397,91 +2274,41 @@ aix[[4-9]]*)
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     # AIX 5 supports IA64
-    library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
     shlibpath_var=LD_LIBRARY_PATH
   else
     # With GCC up to 2.95.x, collect2 would create an import file
     # for dependence libraries.  The import file would start with
-    # the line '#! .'.  This would cause the generated library to
-    # depend on '.', always an invalid library.  This was fixed in
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
     # development snapshots of GCC prior to 3.0.
     case $host_os in
       aix4 | aix4.[[01]] | aix4.[[01]].*)
       if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
 	   echo ' yes '
-	   echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
 	:
       else
 	can_build_shared=no
       fi
       ;;
     esac
-    # Using Import Files as archive members, it is possible to support
-    # filename-based versioning of shared library archives on AIX. While
-    # this would work for both with and without runtime linking, it will
-    # prevent static linking of such archives. So we do filename-based
-    # shared library versioning with .so extension only, which is used
-    # when both runtime linking and shared linking is enabled.
-    # Unfortunately, runtime linking may impact performance, so we do
-    # not want this to be the default eventually. Also, we use the
-    # versioned .so libs for executables only if there is the -brtl
-    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
-    # To allow for filename-based versioning support, we need to create
-    # libNAME.so.V as an archive file, containing:
-    # *) an Import File, referring to the versioned filename of the
-    #    archive as well as the shared archive member, telling the
-    #    bitwidth (32 or 64) of that shared object, and providing the
-    #    list of exported symbols of that shared object, eventually
-    #    decorated with the 'weak' keyword
-    # *) the shared object with the F_LOADONLY flag set, to really avoid
-    #    it being seen by the linker.
-    # At run time we better use the real file rather than another symlink,
-    # but for link time we create the symlink libNAME.so -> libNAME.so.V
-
-    case $with_aix_soname,$aix_use_runtimelinking in
-    # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    aix,yes) # traditional libtool
-      dynamic_linker='AIX unversionable lib.so'
+    if test "$aix_use_runtimelinking" = yes; then
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      ;;
-    aix,no) # traditional AIX only
-      dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      ;;
-    svr4,*) # full svr4 only
-      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,yes) # both, prefer svr4
-      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
-      library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
-      # unpreferred sharedlib libNAME.a needs extra handling
-      postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
-      postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
-      # We do not specify a path in Import Files, so LIBPATH fires.
-      shlibpath_overrides_runpath=yes
-      ;;
-    *,no) # both, prefer aix
-      dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
-      library_names_spec='$libname$release.a $libname.a'
-      soname_spec='$libname$release$shared_ext$major'
-      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
-      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
-      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
-      ;;
-    esac
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -2491,18 +2318,18 @@ amigaos*)
   powerpc)
     # Since July 2007 AmigaOS4 officially supports .so libraries.
     # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
     ;;
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
 
 beos*)
-  library_names_spec='$libname$shared_ext'
+  library_names_spec='${libname}${shared_ext}'
   dynamic_linker="$host_os ld.so"
   shlibpath_var=LIBRARY_PATH
   ;;
@@ -2510,8 +2337,8 @@ beos*)
 bsdi[[45]]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -2523,7 +2350,7 @@ bsdi[[45]]*)
 
 cygwin* | mingw* | pw32* | cegcc*)
   version_type=windows
-  shrext_cmds=.dll
+  shrext_cmds=".dll"
   need_version=no
   need_lib_prefix=no
 
@@ -2532,8 +2359,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname~
@@ -2549,17 +2376,17 @@ cygwin* | mingw* | pw32* | cegcc*)
     case $host_os in
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
-      soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
 m4_if([$1], [],[
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
-      soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
-      library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
     dynamic_linker='Win32 ld.exe'
@@ -2568,8 +2395,8 @@ m4_if([$1], [],[
   *,cl*)
     # Native MSVC
     libname_spec='$name'
-    soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
-    library_names_spec='$libname.dll.lib'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
 
     case $build_os in
     mingw*)
@@ -2596,7 +2423,7 @@ m4_if([$1], [],[
       sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
       ;;
     *)
-      sys_lib_search_path_spec=$LIB
+      sys_lib_search_path_spec="$LIB"
       if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
         # It is most probably a Windows format PATH.
         sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -2609,8 +2436,8 @@ m4_if([$1], [],[
     esac
 
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
-    postinstall_cmds='base_file=`basename \$file`~
-      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
       dldir=$destdir/`dirname \$dlpath`~
       test -d \$dldir || mkdir -p \$dldir~
       $install_prog $dir/$dlname \$dldir/$dlname'
@@ -2623,7 +2450,7 @@ m4_if([$1], [],[
 
   *)
     # Assume MSVC wrapper
-    library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
   esac
@@ -2636,8 +2463,8 @@ darwin* | rhapsody*)
   version_type=darwin
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$major$shared_ext'
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
   shlibpath_overrides_runpath=yes
   shlibpath_var=DYLD_LIBRARY_PATH
   shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -2650,8 +2477,8 @@ dgux*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -2669,13 +2496,12 @@ freebsd* | dragonfly*)
   version_type=freebsd-$objformat
   case $version_type in
     freebsd-elf*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-      soname_spec='$libname$release$shared_ext$major'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
       need_version=no
       need_lib_prefix=no
       ;;
     freebsd-*)
-      library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
       need_version=yes
       ;;
   esac
@@ -2705,10 +2531,10 @@ haiku*)
   need_lib_prefix=no
   need_version=no
   dynamic_linker="$host_os runtime_loader"
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LIBRARY_PATH
-  shlibpath_overrides_runpath=no
+  shlibpath_overrides_runpath=yes
   sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
@@ -2726,15 +2552,14 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.so"
     shlibpath_var=LD_LIBRARY_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
-    if test 32 = "$HPUX_IA64_MODE"; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
       sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux32
     else
       sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
-      sys_lib_dlsearch_path_spec=/usr/lib/hpux64
     fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
   hppa*64*)
     shrext_cmds='.sl'
@@ -2742,8 +2567,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
     ;;
@@ -2752,8 +2577,8 @@ hpux9* | hpux10* | hpux11*)
     dynamic_linker="$host_os dld.sl"
     shlibpath_var=SHLIB_PATH
     shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
   # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -2766,8 +2591,8 @@ interix[[3-9]]*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -2778,7 +2603,7 @@ irix5* | irix6* | nonstopux*)
   case $host_os in
     nonstopux*) version_type=nonstopux ;;
     *)
-	if test yes = "$lt_cv_prog_gnu_ld"; then
+	if test "$lt_cv_prog_gnu_ld" = yes; then
 		version_type=linux # correct to gnu/linux during the next big refactor
 	else
 		version_type=irix
@@ -2786,8 +2611,8 @@ irix5* | irix6* | nonstopux*)
   esac
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
   case $host_os in
   irix5* | nonstopux*)
     libsuff= shlibsuff=
@@ -2806,8 +2631,8 @@ irix5* | irix6* | nonstopux*)
   esac
   shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
   shlibpath_overrides_runpath=no
-  sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
-  sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
   hardcode_into_libs=yes
   ;;
 
@@ -2816,33 +2641,13 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-linux*android*)
-  version_type=none # Android doesn't support versioned libraries.
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='$libname$release$shared_ext'
-  soname_spec='$libname$release$shared_ext'
-  finish_cmds=
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
-
-  # This implies no fast_install, which is unacceptable.
-  # Some rework will be needed to allow for fast_install
-  # before this can be enabled.
-  hardcode_into_libs=yes
-
-  dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-  ;;
-
 # This must be glibc/ELF.
 linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
@@ -2867,12 +2672,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
-  # searched for libraries, however this is still not possible.  Aside from not
-  # being certain /sbin/ldconfig is available, command
-  # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
-  # even though it is searched at run-time.  Try to do the best guess by
-  # appending ld.so.conf contents (and includes) to the search path.
+  # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -2904,12 +2704,12 @@ netbsd*)
   need_lib_prefix=no
   need_version=no
   if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
     finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
     dynamic_linker='NetBSD (a.out) ld.so'
   else
-    library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-    soname_spec='$libname$release$shared_ext$major'
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
     dynamic_linker='NetBSD ld.elf_so'
   fi
   shlibpath_var=LD_LIBRARY_PATH
@@ -2919,7 +2719,7 @@ netbsd*)
 
 newsos6)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   ;;
@@ -2928,68 +2728,58 @@ newsos6)
   version_type=qnx
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
-  sys_lib_dlsearch_path_spec=/usr/lib
+  sys_lib_dlsearch_path_spec="/usr/lib"
   need_lib_prefix=no
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
-    need_version=no
-  else
-    need_version=yes
-  fi
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
   shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=yes
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
   ;;
 
 os2*)
   libname_spec='$name'
-  version_type=windows
-  shrext_cmds=.dll
-  need_version=no
+  shrext_cmds=".dll"
   need_lib_prefix=no
-  # OS/2 can only load a DLL with a base name of 8 characters or less.
-  soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
-    v=$($ECHO $release$versuffix | tr -d .-);
-    n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
-    $ECHO $n$v`$shared_ext'
-  library_names_spec='${libname}_dll.$libext'
+  library_names_spec='$libname${shared_ext} $libname.a'
   dynamic_linker='OS/2 ld.exe'
-  shlibpath_var=BEGINLIBPATH
-  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
-  postinstall_cmds='base_file=`basename \$file`~
-    dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
-    dldir=$destdir/`dirname \$dlpath`~
-    test -d \$dldir || mkdir -p \$dldir~
-    $install_prog $dir/$dlname \$dldir/$dlname~
-    chmod a+x \$dldir/$dlname~
-    if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
-      eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
-    fi'
-  postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
-    dlpath=$dir/\$dldll~
-    $RM \$dlpath'
+  shlibpath_var=LIBPATH
   ;;
 
 osf3* | osf4* | osf5*)
   version_type=osf
   need_lib_prefix=no
   need_version=no
-  soname_spec='$libname$release$shared_ext$major'
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
-  sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
   ;;
 
 rdos*)
@@ -3000,8 +2790,8 @@ solaris*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
@@ -3011,11 +2801,11 @@ solaris*)
 
 sunos4*)
   version_type=sunos
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
   finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     need_lib_prefix=no
   fi
   need_version=yes
@@ -3023,8 +2813,8 @@ sunos4*)
 
 sysv4 | sysv4.3*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   case $host_vendor in
     sni)
@@ -3045,24 +2835,24 @@ sysv4 | sysv4.3*)
   ;;
 
 sysv4*MP*)
-  if test -d /usr/nec; then
+  if test -d /usr/nec ;then
     version_type=linux # correct to gnu/linux during the next big refactor
-    library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
-    soname_spec='$libname$shared_ext.$major'
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
   fi
   ;;
 
 sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
-  version_type=sco
+  version_type=freebsd-elf
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
   hardcode_into_libs=yes
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
   else
     sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -3080,7 +2870,7 @@ tpf*)
   version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
   hardcode_into_libs=yes
@@ -3088,8 +2878,8 @@ tpf*)
 
 uts4*)
   version_type=linux # correct to gnu/linux during the next big refactor
-  library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
-  soname_spec='$libname$release$shared_ext$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
@@ -3098,30 +2888,20 @@ uts4*)
   ;;
 esac
 AC_MSG_RESULT([$dynamic_linker])
-test no = "$dynamic_linker" && can_build_shared=no
+test "$dynamic_linker" = no && can_build_shared=no
 
 variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
 fi
 
-if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
-  sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
 fi
-
-if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
-  sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
 fi
 
-# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
-configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
-
-# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
-func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
-
-# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
-configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
-
 _LT_DECL([], [variables_saved_for_relink], [1],
     [Variables whose values should be saved in libtool wrapper scripts and
     restored at link time])
@@ -3154,41 +2934,39 @@ _LT_DECL([], [hardcode_into_libs], [0],
     [Whether we should hardcode library paths into libraries])
 _LT_DECL([], [sys_lib_search_path_spec], [2],
     [Compile-time system search path for libraries])
-_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
-    [Detected run-time system search path for libraries])
-_LT_DECL([], [configure_time_lt_sys_library_path], [2],
-    [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
 ])# _LT_SYS_DYNAMIC_LINKER
 
 
 # _LT_PATH_TOOL_PREFIX(TOOL)
 # --------------------------
-# find a file program that can recognize shared library
+# find a file program which can recognize shared library
 AC_DEFUN([_LT_PATH_TOOL_PREFIX],
 [m4_require([_LT_DECL_EGREP])dnl
 AC_MSG_CHECKING([for $1])
 AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
 [case $MAGIC_CMD in
 [[\\/*] |  ?:[\\/]*])
-  lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
   ;;
 *)
-  lt_save_MAGIC_CMD=$MAGIC_CMD
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
 dnl $ac_dummy forces splitting on constant user-supplied paths.
 dnl POSIX.2 word splitting is done only on the output of word expansions,
 dnl not every word.  This closes a longstanding sh security hole.
   ac_dummy="m4_if([$2], , $PATH, [$2])"
   for ac_dir in $ac_dummy; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$1"; then
-      lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
       if test -n "$file_magic_test_file"; then
 	case $deplibs_check_method in
 	"file_magic "*)
 	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
-	  MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
 	    $EGREP "$file_magic_regex" > /dev/null; then
 	    :
@@ -3211,11 +2989,11 @@ _LT_EOF
       break
     fi
   done
-  IFS=$lt_save_ifs
-  MAGIC_CMD=$lt_save_MAGIC_CMD
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
   ;;
 esac])
-MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
 if test -n "$MAGIC_CMD"; then
   AC_MSG_RESULT($MAGIC_CMD)
 else
@@ -3233,7 +3011,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
 
 # _LT_PATH_MAGIC
 # --------------
-# find a file program that can recognize a shared library
+# find a file program which can recognize a shared library
 m4_defun([_LT_PATH_MAGIC],
 [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
 if test -z "$lt_cv_path_MAGIC_CMD"; then
@@ -3260,16 +3038,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
 AC_ARG_WITH([gnu-ld],
     [AS_HELP_STRING([--with-gnu-ld],
 	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
-    [test no = "$withval" || with_gnu_ld=yes],
+    [test "$withval" = no || with_gnu_ld=yes],
     [with_gnu_ld=no])dnl
 
 ac_prog=ld
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   AC_MSG_CHECKING([for ld used by $CC])
   case $host in
   *-*-mingw*)
-    # gcc leaves a trailing carriage return, which upsets mingw
+    # gcc leaves a trailing carriage return which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
     ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -3283,7 +3061,7 @@ if test yes = "$GCC"; then
       while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
 	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
       done
-      test -z "$LD" && LD=$ac_prog
+      test -z "$LD" && LD="$ac_prog"
       ;;
   "")
     # If it fails, then pretend we aren't using GCC.
@@ -3294,37 +3072,37 @@ if test yes = "$GCC"; then
     with_gnu_ld=unknown
     ;;
   esac
-elif test yes = "$with_gnu_ld"; then
+elif test "$with_gnu_ld" = yes; then
   AC_MSG_CHECKING([for GNU ld])
 else
   AC_MSG_CHECKING([for non-GNU ld])
 fi
 AC_CACHE_VAL(lt_cv_path_LD,
 [if test -z "$LD"; then
-  lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
   for ac_dir in $PATH; do
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
     test -z "$ac_dir" && ac_dir=.
     if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      lt_cv_path_LD=$ac_dir/$ac_prog
+      lt_cv_path_LD="$ac_dir/$ac_prog"
       # Check to see if the program is GNU ld.  I'd rather use --version,
       # but apparently some variants of GNU ld only accept -v.
       # Break only if it was the GNU/non-GNU ld that we prefer.
       case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
       *GNU* | *'with BFD'*)
-	test no != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != no && break
 	;;
       *)
-	test yes != "$with_gnu_ld" && break
+	test "$with_gnu_ld" != yes && break
 	;;
       esac
     fi
   done
-  IFS=$lt_save_ifs
+  IFS="$lt_save_ifs"
 else
-  lt_cv_path_LD=$LD # Let the user override the test with a path.
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
 fi])
-LD=$lt_cv_path_LD
+LD="$lt_cv_path_LD"
 if test -n "$LD"; then
   AC_MSG_RESULT($LD)
 else
@@ -3378,13 +3156,13 @@ esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       reload_cmds=false
     fi
     ;;
   darwin*)
-    if test yes = "$GCC"; then
-      reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
     else
       reload_cmds='$LD$reload_flag -o $output$reload_objs'
     fi
@@ -3395,43 +3173,6 @@ _LT_TAGDECL([], [reload_cmds], [2])dnl
 ])# _LT_CMD_RELOAD
 
 
-# _LT_PATH_DD
-# -----------
-# find a working dd
-m4_defun([_LT_PATH_DD],
-[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-: ${lt_DD:=$DD}
-AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
-[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
-fi])
-rm -f conftest.i conftest2.i conftest.out])
-])# _LT_PATH_DD
-
-
-# _LT_CMD_TRUNCATE
-# ----------------
-# find command to truncate a binary pipe
-m4_defun([_LT_CMD_TRUNCATE],
-[m4_require([_LT_PATH_DD])
-AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
-[printf 0123456789abcdef0123456789abcdef >conftest.i
-cat conftest.i conftest.i >conftest2.i
-lt_cv_truncate_bin=
-if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
-  cmp -s conftest.i conftest.out \
-  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
-fi
-rm -f conftest.i conftest2.i conftest.out
-test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
-_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
-  [Command to truncate a binary pipe])
-])# _LT_CMD_TRUNCATE
-
-
 # _LT_CHECK_MAGIC_METHOD
 # ----------------------
 # how to check for library dependencies
@@ -3447,13 +3188,13 @@ lt_cv_deplibs_check_method='unknown'
 # Need to set the preceding variable on all platforms that support
 # interlibrary dependencies.
 # 'none' -- dependencies not supported.
-# 'unknown' -- same as none, but documents that we really don't know.
+# `unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
 # 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
-# that responds to the $file_magic_cmd with a given extended regex.
-# If you have 'file' or equivalent on your system and you're not sure
-# whether 'pass_all' will *always* work, you probably want this one.
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
 
 case $host_os in
 aix[[4-9]]*)
@@ -3480,7 +3221,8 @@ mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
-  if ( file / ) >/dev/null 2>&1; then
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
@@ -3576,8 +3318,8 @@ newos6*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-openbsd* | bitrig*)
-  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
   else
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
@@ -3630,9 +3372,6 @@ sysv4 | sysv4.3*)
 tpf*)
   lt_cv_deplibs_check_method=pass_all
   ;;
-os2*)
-  lt_cv_deplibs_check_method=pass_all
-  ;;
 esac
 ])
 
@@ -3673,38 +3412,33 @@ AC_DEFUN([LT_PATH_NM],
 AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
 [if test -n "$NM"; then
   # Let the user override the test.
-  lt_cv_path_NM=$NM
+  lt_cv_path_NM="$NM"
 else
-  lt_nm_to_check=${ac_tool_prefix}nm
+  lt_nm_to_check="${ac_tool_prefix}nm"
   if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
     lt_nm_to_check="$lt_nm_to_check nm"
   fi
   for lt_tmp_nm in $lt_nm_to_check; do
-    lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
     for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       test -z "$ac_dir" && ac_dir=.
-      tmp_nm=$ac_dir/$lt_tmp_nm
-      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
 	# Check to see if the nm accepts a BSD-compat flag.
-	# Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
 	#   nm: unknown option "B" ignored
 	# Tru64's nm complains that /dev/null is an invalid object file
-	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
-	case $build_os in
-	mingw*) lt_bad_file=conftest.nm/nofile ;;
-	*) lt_bad_file=/dev/null ;;
-	esac
-	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
-	*$lt_bad_file* | *'Invalid file or object type'*)
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
 	  lt_cv_path_NM="$tmp_nm -B"
-	  break 2
+	  break
 	  ;;
 	*)
 	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
 	  */dev/null*)
 	    lt_cv_path_NM="$tmp_nm -p"
-	    break 2
+	    break
 	    ;;
 	  *)
 	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -3715,21 +3449,21 @@ else
 	esac
       fi
     done
-    IFS=$lt_save_ifs
+    IFS="$lt_save_ifs"
   done
   : ${lt_cv_path_NM=no}
 fi])
-if test no != "$lt_cv_path_NM"; then
-  NM=$lt_cv_path_NM
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
 else
   # Didn't find any BSD compatible name lister, look for dumpbin.
   if test -n "$DUMPBIN"; then :
     # Let the user override the test.
   else
     AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
-    case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
     *COFF*)
-      DUMPBIN="$DUMPBIN -symbols -headers"
+      DUMPBIN="$DUMPBIN -symbols"
       ;;
     *)
       DUMPBIN=:
@@ -3737,8 +3471,8 @@ else
     esac
   fi
   AC_SUBST([DUMPBIN])
-  if test : != "$DUMPBIN"; then
-    NM=$DUMPBIN
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
   fi
 fi
 test -z "$NM" && NM=nm
@@ -3784,8 +3518,8 @@ lt_cv_sharedlib_from_linklib_cmd,
 
 case $host_os in
 cygwin* | mingw* | pw32* | cegcc*)
-  # two different shell functions defined in ltmain.sh;
-  # decide which one to use based on capabilities of $DLLTOOL
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
   *--identify-strict*)
     lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -3797,7 +3531,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   ;;
 *)
   # fallback: assume linklib IS sharedlib
-  lt_cv_sharedlib_from_linklib_cmd=$ECHO
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
   ;;
 esac
 ])
@@ -3824,28 +3558,13 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool
     lt_cv_path_mainfest_tool=yes
   fi
   rm -f conftest*])
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
   MANIFEST_TOOL=:
 fi
 _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
 ])# _LT_PATH_MANIFEST_TOOL
 
 
-# _LT_DLL_DEF_P([FILE])
-# ---------------------
-# True iff FILE is a Windows DLL '.def' file.
-# Keep in sync with func_dll_def_p in the libtool script
-AC_DEFUN([_LT_DLL_DEF_P],
-[dnl
-  test DEF = "`$SED -n dnl
-    -e '\''s/^[[	 ]]*//'\'' dnl Strip leading whitespace
-    -e '\''/^\(;.*\)*$/d'\'' dnl      Delete empty lines and comments
-    -e '\''s/^\(EXPORTS\|LIBRARY\)\([[	 ]].*\)*$/DEF/p'\'' dnl
-    -e q dnl                          Only consider the first "real" line
-    $1`" dnl
-])# _LT_DLL_DEF_P
-
-
 # LT_LIB_M
 # --------
 # check for math library
@@ -3857,11 +3576,11 @@ case $host in
   # These system don't have libm, or don't need it
   ;;
 *-ncr-sysv4.3*)
-  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
   AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
   ;;
 *)
-  AC_CHECK_LIB(m, cos, LIBM=-lm)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
   ;;
 esac
 AC_SUBST([LIBM])
@@ -3880,7 +3599,7 @@ m4_defun([_LT_COMPILER_NO_RTTI],
 
 _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
 
-if test yes = "$GCC"; then
+if test "$GCC" = yes; then
   case $cc_basename in
   nvcc*)
     _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
@@ -3932,7 +3651,7 @@ cygwin* | mingw* | pw32* | cegcc*)
   symcode='[[ABCDGISTW]]'
   ;;
 hpux*)
-  if test ia64 = "$host_cpu"; then
+  if test "$host_cpu" = ia64; then
     symcode='[[ABCDEGRST]]'
   fi
   ;;
@@ -3965,44 +3684,14 @@ case `$NM -V 2>&1` in
   symcode='[[ABCDGIRSTW]]' ;;
 esac
 
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-  # Gets list of data symbols to import.
-  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
-  # Adjust the below global symbol transforms to fixup imported variables.
-  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
-  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
-  lt_c_name_lib_hook="\
-  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
-  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
-else
-  # Disable hooks by default.
-  lt_cv_sys_global_symbol_to_import=
-  lt_cdecl_hook=
-  lt_c_name_hook=
-  lt_c_name_lib_hook=
-fi
-
 # Transform an extracted symbol line into a proper C declaration.
 # Some systems (esp. on ia64) link data and code symbols differently,
 # so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n"\
-$lt_cdecl_hook\
-" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
-$lt_c_name_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/p'"
-
-# Transform an extracted symbol line into symbol name with lib prefix and
-# symbol address.
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
-$lt_c_name_lib_hook\
-" -e 's/^: \(.*\) .*$/  {\"\1\", (void *) 0},/p'"\
-" -e 's/^$symcode$symcode* .* \(lib.*\)$/  {\"\1\", (void *) \&\1},/p'"\
-" -e 's/^$symcode$symcode* .* \(.*\)$/  {\"lib\1\", (void *) \&\1},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -4020,24 +3709,21 @@ for ac_symprfx in "" "_"; do
 
   # Write the raw and C identifiers.
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-    # Fake it for dumpbin and say T for any non-static function,
-    # D for any global variable and I for any imported variable.
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
     # Also find C++ and __fastcall symbols from MSVC++,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
 "     {last_section=section; section=\$ 3};"\
 "     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
-"     /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
-"     /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
-"     /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
 "     {if(hide[section]) next};"\
-"     {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
-"     {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
-"     s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
-"     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
 "     ' prfx=^$ac_symprfx]"
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -4077,11 +3763,11 @@ _LT_EOF
 	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
 	  cat <<_LT_EOF > conftest.$ac_ext
 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
-#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
-/* DATA imports from DLLs on WIN32 can't be const, because runtime
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
    relocations are performed -- see ld's documentation on pseudo-relocs.  */
 # define LT@&t at _DLSYM_CONST
-#elif defined __osf__
+#elif defined(__osf__)
 /* This system does not cope well with relocations in const data.  */
 # define LT@&t at _DLSYM_CONST
 #else
@@ -4107,7 +3793,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] =
 {
   { "@PROGRAM@", (void *) 0 },
 _LT_EOF
-	  $SED "s/^$symcode$symcode* .* \(.*\)$/  {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
 	  cat <<\_LT_EOF >> conftest.$ac_ext
   {0, (void *) 0}
 };
@@ -4127,9 +3813,9 @@ _LT_EOF
 	  mv conftest.$ac_objext conftstm.$ac_objext
 	  lt_globsym_save_LIBS=$LIBS
 	  lt_globsym_save_CFLAGS=$CFLAGS
-	  LIBS=conftstm.$ac_objext
+	  LIBS="conftstm.$ac_objext"
 	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
-	  if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
 	    pipe_works=yes
 	  fi
 	  LIBS=$lt_globsym_save_LIBS
@@ -4150,7 +3836,7 @@ _LT_EOF
   rm -rf conftest* conftst*
 
   # Do not use the global_symbol_pipe unless it works.
-  if test yes = "$pipe_works"; then
+  if test "$pipe_works" = yes; then
     break
   else
     lt_cv_sys_global_symbol_pipe=
@@ -4177,16 +3863,12 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
     [Take the output of nm and produce a listing of raw symbols and C names])
 _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
     [Transform the output of nm in a proper C declaration])
-_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
-    [Transform the output of nm into a list of symbols to manually relocate])
 _LT_DECL([global_symbol_to_c_name_address],
     [lt_cv_sys_global_symbol_to_c_name_address], [1],
     [Transform the output of nm in a C name address pair])
 _LT_DECL([global_symbol_to_c_name_address_lib_prefix],
     [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
     [Transform the output of nm in a C name address pair when lib prefix is needed])
-_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
-    [The name lister interface])
 _LT_DECL([], [nm_file_list_spec], [1],
     [Specify filename containing input files for $NM])
 ]) # _LT_CMD_GLOBAL_SYMBOLS
@@ -4202,18 +3884,17 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)=
 
 m4_if([$1], [CXX], [
   # C++ specific cases for pic, static, wl, etc.
-  if test yes = "$GXX"; then
+  if test "$GXX" = yes; then
     _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
     _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
     case $host_os in
     aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
 
     amigaos*)
@@ -4224,8 +3905,8 @@ m4_if([$1], [CXX], [
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -4241,11 +3922,6 @@ m4_if([$1], [CXX], [
       # (--disable-auto-import) libraries
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
     darwin* | rhapsody*)
       # PIC is the default on this platform
@@ -4295,7 +3971,7 @@ m4_if([$1], [CXX], [
     case $host_os in
       aix[[4-9]]*)
 	# All AIX code is PIC.
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	  # AIX 5 now supports IA64 processor
 	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	else
@@ -4336,14 +4012,14 @@ m4_if([$1], [CXX], [
 	case $cc_basename in
 	  CC*)
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
-	    if test ia64 != "$host_cpu"; then
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
 	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
 	    fi
 	    ;;
 	  aCC*)
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	    _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
 	    case $host_cpu in
 	    hppa*64*|ia64*)
 	      # +Z the default
@@ -4380,7 +4056,7 @@ m4_if([$1], [CXX], [
 	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
 	    ;;
 	  ecpc* )
-	    # old Intel C++ for x86_64, which still supported -KPIC.
+	    # old Intel C++ for x86_64 which still supported -KPIC.
 	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
 	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
@@ -4525,18 +4201,17 @@ m4_if([$1], [CXX], [
   fi
 ],
 [
-  if test yes = "$GCC"; then
+  if test "$GCC" = yes; then
     _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
     _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
 
     case $host_os in
       aix*)
       # All AIX code is PIC.
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
 
     amigaos*)
@@ -4547,8 +4222,8 @@ m4_if([$1], [CXX], [
         ;;
       m68k)
             # FIXME: we need at least 68020 code to build shared libraries, but
-            # adding the '-m68020' flag to GCC prevents building anything better,
-            # like '-m68040'.
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
             _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
         ;;
       esac
@@ -4565,11 +4240,6 @@ m4_if([$1], [CXX], [
       # (--disable-auto-import) libraries
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
 
     darwin* | rhapsody*)
@@ -4640,7 +4310,7 @@ m4_if([$1], [CXX], [
     case $host_os in
     aix*)
       _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# AIX 5 now supports IA64 processor
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       else
@@ -4648,30 +4318,11 @@ m4_if([$1], [CXX], [
       fi
       ;;
 
-    darwin* | rhapsody*)
-      # PIC is the default on this platform
-      # Common symbols not allowed in MH_DYLIB files
-      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
-      case $cc_basename in
-      nagfor*)
-        # NAG Fortran compiler
-        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
-        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
-        _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-        ;;
-      esac
-      ;;
-
     mingw* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       m4_if([$1], [GCJ], [],
 	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
-      case $host_os in
-      os2*)
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
-	;;
-      esac
       ;;
 
     hpux9* | hpux10* | hpux11*)
@@ -4687,7 +4338,7 @@ m4_if([$1], [CXX], [
 	;;
       esac
       # Is there a better lt_prog_compiler_static that works with the bundled CC?
-      _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
       ;;
 
     irix5* | irix6* | nonstopux*)
@@ -4698,7 +4349,7 @@ m4_if([$1], [CXX], [
 
     linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
       case $cc_basename in
-      # old Intel for x86_64, which still supported -KPIC.
+      # old Intel for x86_64 which still supported -KPIC.
       ecc*)
 	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4723,12 +4374,6 @@ m4_if([$1], [CXX], [
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
 	;;
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-	;;
       pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
 	# which looks to be a dead project)
@@ -4826,7 +4471,7 @@ m4_if([$1], [CXX], [
       ;;
 
     sysv4*MP*)
-      if test -d /usr/nec; then
+      if test -d /usr/nec ;then
 	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
 	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       fi
@@ -4855,7 +4500,7 @@ m4_if([$1], [CXX], [
   fi
 ])
 case $host_os in
-  # For platforms that do not support PIC, -DPIC is meaningless:
+  # For platforms which do not support PIC, -DPIC is meaningless:
   *djgpp*)
     _LT_TAGVAR(lt_prog_compiler_pic, $1)=
     ;;
@@ -4921,21 +4566,17 @@ m4_if([$1], [CXX], [
   case $host_os in
   aix[[4-9]]*)
     # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
-    # Without the "-l" option, or with the "-B" option, AIX nm treats
-    # weak defined symbols like other global defined symbols, whereas
-    # GNU nm marks them as "W".
-    # While the 'weak' keyword is ignored in the Export File, we need
-    # it in the Import File for the 'aix-soname' feature, so we have
-    # to replace the "-B" option with "-P" for AIX nm.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     else
-      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
-    _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
@@ -4984,9 +4625,9 @@ m4_if([$1], [CXX], [
   # included in the symbol list
   _LT_TAGVAR(include_expsyms, $1)=
   # exclude_expsyms can be an extended regexp of symbols to exclude
-  # it will be wrapped by ' (' and ')$', so one must not match beginning or
-  # end of line.  Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
-  # as well as any symbol that contains 'd'.
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
   _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
   # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
   # platforms (ab)use it in PIC code, but their linkers get confused if
@@ -5002,7 +4643,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++.
-    if test yes != "$GCC"; then
+    if test "$GCC" != yes; then
       with_gnu_ld=no
     fi
     ;;
@@ -5010,7 +4651,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # we just hope/assume this is gcc and not c89 (= MSVC++)
     with_gnu_ld=yes
     ;;
-  openbsd* | bitrig*)
+  openbsd*)
     with_gnu_ld=no
     ;;
   linux* | k*bsd*-gnu | gnu*)
@@ -5023,7 +4664,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
   # On some targets, GNU ld is compatible enough with the native linker
   # that we're better off using the native interface for both.
   lt_use_gnu_ld_interface=no
-  if test yes = "$with_gnu_ld"; then
+  if test "$with_gnu_ld" = yes; then
     case $host_os in
       aix*)
 	# The AIX port of GNU ld has always aspired to compatibility
@@ -5045,24 +4686,24 @@ dnl Note also adjust exclude_expsyms for C++ above.
     esac
   fi
 
-  if test yes = "$lt_use_gnu_ld_interface"; then
+  if test "$lt_use_gnu_ld_interface" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
-    wlarc='$wl'
+    wlarc='${wl}'
 
     # Set some defaults for GNU ld with shared library support. These
     # are reset later if shared libraries are not supported. Putting them
     # here allows them to be overridden if necessary.
     runpath_var=LD_RUN_PATH
-    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
     # ancient GNU ld didn't support --whole-archive et. al.
     if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
-      _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
     else
       _LT_TAGVAR(whole_archive_flag_spec, $1)=
     fi
     supports_anon_versioning=no
-    case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+    case `$LD -v 2>&1` in
       *GNU\ gold*) supports_anon_versioning=yes ;;
       *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
       *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -5075,7 +4716,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     case $host_os in
     aix[[3-9]]*)
       # On AIX/PPC, the GNU linker is very broken
-      if test ia64 != "$host_cpu"; then
+      if test "$host_cpu" != ia64; then
 	_LT_TAGVAR(ld_shlibs, $1)=no
 	cat <<_LT_EOF 1>&2
 
@@ -5094,7 +4735,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             _LT_TAGVAR(archive_expsym_cmds, $1)=''
         ;;
       m68k)
@@ -5110,7 +4751,7 @@ _LT_EOF
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	# support --undefined.  This deserves some investigation.  FIXME
-	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -5120,7 +4761,7 @@ _LT_EOF
       # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
       # as there is no search path for DLLs.
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
       _LT_TAGVAR(always_export_symbols, $1)=no
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5128,89 +4769,61 @@ _LT_EOF
       _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	# If the export-symbols file already is a .def file, use it as
-	# is; otherwise, prepend EXPORTS...
-	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-          cp $export_symbols $output_objdir/$soname.def;
-        else
-          echo EXPORTS > $output_objdir/$soname.def;
-          cat $export_symbols >> $output_objdir/$soname.def;
-        fi~
-        $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
 
     haiku*)
-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
       ;;
 
-    os2*)
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-      _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      shrext_cmds=.dll
-      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      ;;
-
     interix[[3-9]]*)
       _LT_TAGVAR(hardcode_direct, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
       # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
       # Instead, shared libraries are loaded at an image base (0x10000000 by
       # default) and relocated if they conflict, which is a slow very memory
       # consuming and fragmenting process.  To avoid this, we pick a random,
       # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
       # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
       ;;
 
     gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       tmp_diet=no
-      if test linux-dietlibc = "$host_os"; then
+      if test "$host_os" = linux-dietlibc; then
 	case $cc_basename in
 	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
 	esac
       fi
       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
-	 && test no = "$tmp_diet"
+	 && test "$tmp_diet" = no
       then
 	tmp_addflag=' $pic_flag'
 	tmp_sharedflag='-shared'
 	case $cc_basename,$host_cpu in
         pgcc*)				# Portland Group C compiler
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag'
 	  ;;
 	pgf77* | pgf90* | pgf95* | pgfortran*)
 					# Portland Group f77 and f90 compilers
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  tmp_addflag=' $pic_flag -Mnomain' ;;
 	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
 	  tmp_addflag=' -i_dynamic' ;;
@@ -5221,47 +4834,42 @@ _LT_EOF
 	lf95*)				# Lahey Fortran 8.1
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
 	  tmp_sharedflag='--shared' ;;
-        nagfor*)                        # NAGFOR 5.3
-          tmp_sharedflag='-Wl,-shared' ;;
 	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
 	  tmp_sharedflag='-qmkshrobj'
 	  tmp_addflag= ;;
 	nvcc*)	# Cuda Compiler Driver 2.2
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  _LT_TAGVAR(compiler_needs_object, $1)=yes
 	  ;;
 	esac
 	case `$CC -V 2>&1 | sed 5q` in
 	*Sun\ C*)			# Sun C 5.9
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	  _LT_TAGVAR(compiler_needs_object, $1)=yes
 	  tmp_sharedflag='-G' ;;
 	*Sun\ F*)			# Sun Fortran 8.3
 	  tmp_sharedflag='-G' ;;
 	esac
-	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 
-        if test yes = "$supports_anon_versioning"; then
+        if test "x$supports_anon_versioning" = xyes; then
           _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-            cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-            echo "local: *; };" >> $output_objdir/$libname.ver~
-            $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
         fi
 
 	case $cc_basename in
-	tcc*)
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
-	  ;;
 	xlf* | bgf* | bgxlf* | mpixlf*)
 	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
-	  if test yes = "$supports_anon_versioning"; then
+	  if test "x$supports_anon_versioning" = xyes; then
 	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-              echo "local: *; };" >> $output_objdir/$libname.ver~
-              $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
 	  fi
 	  ;;
 	esac
@@ -5275,8 +4883,8 @@ _LT_EOF
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
 	wlarc=
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -5294,8 +4902,8 @@ _LT_EOF
 
 _LT_EOF
       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -5307,7 +4915,7 @@ _LT_EOF
 	_LT_TAGVAR(ld_shlibs, $1)=no
 	cat <<_LT_EOF 1>&2
 
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
 *** reliably create shared libraries on SCO systems.  Therefore, libtool
 *** is disabling shared libraries support.  We urge you to upgrade GNU
 *** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
@@ -5322,9 +4930,9 @@ _LT_EOF
 	  # DT_RUNPATH tag from executables and libraries.  But doing so
 	  # requires that you compile everything twice, which is a pain.
 	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 	  else
 	    _LT_TAGVAR(ld_shlibs, $1)=no
 	  fi
@@ -5341,15 +4949,15 @@ _LT_EOF
 
     *)
       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
       fi
       ;;
     esac
 
-    if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
       runpath_var=
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
       _LT_TAGVAR(export_dynamic_flag_spec, $1)=
@@ -5365,7 +4973,7 @@ _LT_EOF
       # Note: this linker hardcodes the directories in LIBPATH if there
       # are no directories specified by -L.
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
 	# Neither direct hardcoding nor static linking is supported with a
 	# broken collect2.
 	_LT_TAGVAR(hardcode_direct, $1)=unsupported
@@ -5373,57 +4981,34 @@ _LT_EOF
       ;;
 
     aix[[4-9]]*)
-      if test ia64 = "$host_cpu"; then
+      if test "$host_cpu" = ia64; then
 	# On IA64, the linker does run time linking by default, so we don't
 	# have to do anything special.
 	aix_use_runtimelinking=no
 	exp_sym_flag='-Bexport'
-	no_entry_flag=
+	no_entry_flag=""
       else
 	# If we're using GNU nm, then we don't want the "-C" option.
-	# -C means demangle to GNU nm, but means don't demangle to AIX nm.
-	# Without the "-l" option, or with the "-B" option, AIX nm treats
-	# weak defined symbols like other global defined symbols, whereas
-	# GNU nm marks them as "W".
-	# While the 'weak' keyword is ignored in the Export File, we need
-	# it in the Import File for the 'aix-soname' feature, so we have
-	# to replace the "-B" option with "-P" for AIX nm.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
 	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	else
-	  _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
 	fi
 	aix_use_runtimelinking=no
 
 	# Test if we are trying to use run time linking or normal
 	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
-	# have runtime linking enabled, and use it for executables.
-	# For shared libraries, we enable/disable runtime linking
-	# depending on the kind of the shared library created -
-	# when "with_aix_soname,aix_use_runtimelinking" is:
-	# "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "aix,yes"  lib.so          shared, rtl:yes, for executables
-	#            lib.a           static archive
-	# "both,no"  lib.so.V(shr.o) shared, rtl:yes
-	#            lib.a(lib.so.V) shared, rtl:no,  for executables
-	# "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a(lib.so.V) shared, rtl:no
-	# "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-	#            lib.a           static archive
+	# need to do runtime linking.
 	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
 	  for ld_flag in $LDFLAGS; do
-	  if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
 	    aix_use_runtimelinking=yes
 	    break
 	  fi
 	  done
-	  if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	    # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	    # so we don't have lib.a shared libs to link our executables.
-	    # We have to force runtime linking in this case.
-	    aix_use_runtimelinking=yes
-	    LDFLAGS="$LDFLAGS -Wl,-brtl"
-	  fi
 	  ;;
 	esac
 
@@ -5442,21 +5027,13 @@ _LT_EOF
       _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
       _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
-      case $with_aix_soname,$aix_use_runtimelinking in
-      aix,*) ;; # traditional, no import file
-      svr4,* | *,yes) # use import file
-	# The Import File defines what to hardcode.
-	_LT_TAGVAR(hardcode_direct, $1)=no
-	_LT_TAGVAR(hardcode_direct_absolute, $1)=no
-	;;
-      esac
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
 
-      if test yes = "$GCC"; then
+      if test "$GCC" = yes; then
 	case $host_os in aix4.[[012]]|aix4.[[012]].*)
 	# We only want to do this on AIX 4.2 and lower, the check
 	# below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -5475,80 +5052,62 @@ _LT_EOF
 	  ;;
 	esac
 	shared_flag='-shared'
-	if test yes = "$aix_use_runtimelinking"; then
-	  shared_flag="$shared_flag "'$wl-G'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
 	fi
-	# Need to ensure runtime linking is disabled for the traditional
-	# shared library, or the linker may eventually find shared libraries
-	# /with/ Import File - we do not want to mix them.
-	shared_flag_aix='-shared'
-	shared_flag_svr4='-shared $wl-G'
+	_LT_TAGVAR(link_all_deplibs, $1)=no
       else
 	# not using gcc
-	if test ia64 = "$host_cpu"; then
+	if test "$host_cpu" = ia64; then
 	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	# chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
 	else
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag='$wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
 	  else
-	    shared_flag='$wl-bM:SRE'
+	    shared_flag='${wl}-bM:SRE'
 	  fi
-	  shared_flag_aix='$wl-bM:SRE'
-	  shared_flag_svr4='$wl-G'
 	fi
       fi
 
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
       # It seems that -bexpall does not export symbols beginning with
       # underscore (_), so it is better to generate a list of symbols to export.
       _LT_TAGVAR(always_export_symbols, $1)=yes
-      if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+      if test "$aix_use_runtimelinking" = yes; then
 	# Warning - without using the other runtime loading flags (-brtl),
 	# -berok will link without error, but may produce a broken library.
 	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
         # Determine the default libpath from the value encoded in an
         # empty executable.
         _LT_SYS_MODULE_PATH_AIX([$1])
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
       else
-	if test ia64 = "$host_cpu"; then
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
 	else
 	 # Determine the default libpath from the value encoded in an
 	 # empty executable.
 	 _LT_SYS_MODULE_PATH_AIX([$1])
-	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 	  # Warning - without using the other run time loading flags,
 	  # -berok will link without error, but may produce a broken library.
-	  _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
-	  _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
-	  if test yes = "$with_gnu_ld"; then
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
 	    # We only use this code for GNU lds that support --whole-archive.
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	  else
 	    # Exported symbols can be pulled into shared objects from archives
 	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	  fi
 	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	  # -brtl affects multiple linker settings, -berok does not and is overridden later
-	  compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
-	  if test svr4 != "$with_aix_soname"; then
-	    # This is similar to how AIX traditionally builds its shared libraries.
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	  fi
-	  if test aix != "$with_aix_soname"; then
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 3 [...]
-	  else
-	    # used by -dlpreopen to get the symbols
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	  fi
-	  _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
 	fi
       fi
       ;;
@@ -5557,7 +5116,7 @@ _LT_EOF
       case $host_cpu in
       powerpc)
             # see comment about AmigaOS4 .so support
-            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
             _LT_TAGVAR(archive_expsym_cmds, $1)=''
         ;;
       m68k)
@@ -5587,17 +5146,16 @@ _LT_EOF
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-            cp "$export_symbols" "$output_objdir/$soname.def";
-            echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-          else
-            $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-          fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-          linknames='
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
 	# The linker will not automatically build a static lib if we build a DLL.
 	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5606,18 +5164,18 @@ _LT_EOF
 	# Don't use ranlib
 	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
 	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
-          lt_tool_outputfile="@TOOL_OUTPUT@"~
-          case $lt_outputfile in
-            *.exe|*.EXE) ;;
-            *)
-              lt_outputfile=$lt_outputfile.exe
-              lt_tool_outputfile=$lt_tool_outputfile.exe
-              ;;
-          esac~
-          if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-            $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-            $RM "$lt_outputfile.manifest";
-          fi'
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
 	;;
       *)
 	# Assume MSVC wrapper
@@ -5626,7 +5184,7 @@ _LT_EOF
 	# Tell ltmain to make .lib files, not .a files.
 	libext=lib
 	# Tell ltmain to make .dll files, not .so files.
-	shrext_cmds=.dll
+	shrext_cmds=".dll"
 	# FIXME: Setting linknames here is a bad hack.
 	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
 	# The linker will automatically build a .lib file if we build a DLL.
@@ -5676,33 +5234,33 @@ _LT_EOF
       ;;
 
     hpux9*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       fi
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(hardcode_direct, $1)=yes
 
       # hardcode_minus_L: Not really in the search PATH,
       # but as the default location of the library.
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
       ;;
 
     hpux10*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
       else
 	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
       fi
-      if test no = "$with_gnu_ld"; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 	_LT_TAGVAR(hardcode_direct, $1)=yes
 	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	# hardcode_minus_L: Not really in the search PATH,
 	# but as the default location of the library.
 	_LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -5710,25 +5268,25 @@ _LT_EOF
       ;;
 
     hpux11*)
-      if test yes,no = "$GCC,$with_gnu_ld"; then
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
 	case $host_cpu in
 	hppa*64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	esac
       else
 	case $host_cpu in
 	hppa*64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	ia64*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
 	m4_if($1, [], [
@@ -5736,14 +5294,14 @@ _LT_EOF
 	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
 	  _LT_LINKER_OPTION([if $CC understands -b],
 	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
-	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
 	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
-	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
 	  ;;
 	esac
       fi
-      if test no = "$with_gnu_ld"; then
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	case $host_cpu in
@@ -5754,7 +5312,7 @@ _LT_EOF
 	*)
 	  _LT_TAGVAR(hardcode_direct, $1)=yes
 	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 
 	  # hardcode_minus_L: Not really in the search PATH,
 	  # but as the default location of the library.
@@ -5765,16 +5323,16 @@ _LT_EOF
       ;;
 
     irix5* | irix6* | nonstopux*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	# Try to use the -exported_symbol ld option, if it does not
 	# work, assume that -exports_file does not work either and
 	# implicitly export all symbols.
 	# This should be the same for all languages, so no per-tag cache variable.
 	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
 	  [lt_cv_irix_exported_symbol],
-	  [save_LDFLAGS=$LDFLAGS
-	   LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+	  [save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
 	   AC_LINK_IFELSE(
 	     [AC_LANG_SOURCE(
 	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
@@ -5787,32 +5345,21 @@ _LT_EOF
       end]])])],
 	      [lt_cv_irix_exported_symbol=yes],
 	      [lt_cv_irix_exported_symbol=no])
-           LDFLAGS=$save_LDFLAGS])
-	if test yes = "$lt_cv_irix_exported_symbol"; then
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+           LDFLAGS="$save_LDFLAGS"])
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
 	fi
-	_LT_TAGVAR(link_all_deplibs, $1)=no
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(inherit_rpath, $1)=yes
       _LT_TAGVAR(link_all_deplibs, $1)=yes
       ;;
 
-    linux*)
-      case $cc_basename in
-      tcc*)
-	# Fabrice Bellard et al's Tiny C Compiler
-	_LT_TAGVAR(ld_shlibs, $1)=yes
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	;;
-      esac
-      ;;
-
     netbsd* | netbsdelf*-gnu)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
 	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
@@ -5827,7 +5374,7 @@ _LT_EOF
     newsos6)
       _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
       _LT_TAGVAR(hardcode_direct, $1)=yes
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       ;;
@@ -5835,19 +5382,27 @@ _LT_EOF
     *nto* | *qnx*)
       ;;
 
-    openbsd* | bitrig*)
+    openbsd*)
       if test -f /usr/libexec/ld.so; then
 	_LT_TAGVAR(hardcode_direct, $1)=yes
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
 	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
-	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	else
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
 	fi
       else
 	_LT_TAGVAR(ld_shlibs, $1)=no
@@ -5858,53 +5413,33 @@ _LT_EOF
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      shrext_cmds=.dll
-      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	$ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	$ECHO EXPORTS >> $output_objdir/$libname.def~
-	prefix_cmds="$SED"~
-	if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	  prefix_cmds="$prefix_cmds -e 1d";
-	fi~
-	prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	$CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
       ;;
 
     osf3*)
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
       else
 	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=:
       ;;
 
     osf4* | osf5*)	# as osf3* with the addition of -msym flag
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       else
 	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
-          $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
 
 	# Both c and cxx compiler support -rpath directly
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -5915,24 +5450,24 @@ _LT_EOF
 
     solaris*)
       _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
-      if test yes = "$GCC"; then
-	wlarc='$wl'
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
 	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-          $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
       else
 	case `$CC -V 2>&1` in
 	*"Compilers 5.0"*)
 	  wlarc=''
-	  _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
 	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
 	  ;;
 	*)
-	  wlarc='$wl'
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
 	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-            $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
 	  ;;
 	esac
       fi
@@ -5942,11 +5477,11 @@ _LT_EOF
       solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
       *)
 	# The compiler driver will combine and reorder linker options,
-	# but understands '-z linker_flag'.  GCC discards it without '$wl',
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
 	# but is careful enough not to reorder.
 	# Supported since Solaris 2.6 (maybe 2.5.1?)
-	if test yes = "$GCC"; then
-	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 	else
 	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	fi
@@ -5956,10 +5491,10 @@ _LT_EOF
       ;;
 
     sunos4*)
-      if test sequent = "$host_vendor"; then
+      if test "x$host_vendor" = xsequent; then
 	# Use $CC to link under sequent, because it throws in some extra .o
 	# files that make .init and .fini sections work.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
       else
 	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
       fi
@@ -6008,43 +5543,43 @@ _LT_EOF
       ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
     sysv5* | sco3.2v5* | sco5v6*)
-      # Note: We CANNOT use -z defs as we might desire, because we do not
+      # Note: We can NOT use -z defs as we might desire, because we do not
       # link with -lc, and that would cause any symbols used from libc to
       # always be unresolved, which means just about no library would
       # ever link correctly.  If we're not using GNU ld we use -z text
       # though, which does catch some bad symbols but isn't as heavy-handed
       # as -z defs.
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
-      _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
       _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
-      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
       runpath_var='LD_RUN_PATH'
 
-      if test yes = "$GCC"; then
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       else
-	_LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
       fi
       ;;
 
@@ -6059,17 +5594,17 @@ _LT_EOF
       ;;
     esac
 
-    if test sni = "$host_vendor"; then
+    if test x$host_vendor = xsni; then
       case $host in
       sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
 	;;
       esac
     fi
   fi
 ])
 AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
 _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
 
@@ -6086,7 +5621,7 @@ x|xyes)
   # Assume -lc should be added
   _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
 
-  if test yes,yes = "$GCC,$enable_shared"; then
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
     case $_LT_TAGVAR(archive_cmds, $1) in
     *'~'*)
       # FIXME: we may have to deal with multi-command sequences.
@@ -6166,12 +5701,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
 _LT_TAGDECL([], [hardcode_libdir_separator], [1],
     [Whether we need a single "-rpath" flag with a separated argument])
 _LT_TAGDECL([], [hardcode_direct], [0],
-    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
     DIR into the resulting binary])
 _LT_TAGDECL([], [hardcode_direct_absolute], [0],
-    [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
     DIR into the resulting binary and the resulting library dependency is
-    "absolute", i.e impossible to change by setting $shlibpath_var if the
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
     library is relocated])
 _LT_TAGDECL([], [hardcode_minus_L], [0],
     [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
@@ -6212,10 +5747,10 @@ dnl    [Compiler flag to generate thread safe objects])
 # ------------------------
 # Ensure that the configuration variables for a C compiler are suitably
 # defined.  These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_C_CONFIG],
 [m4_require([_LT_DECL_EGREP])dnl
-lt_save_CC=$CC
+lt_save_CC="$CC"
 AC_LANG_PUSH(C)
 
 # Source file extension for C test sources.
@@ -6255,18 +5790,18 @@ if test -n "$compiler"; then
   LT_SYS_DLOPEN_SELF
   _LT_CMD_STRIPLIB
 
-  # Report what library types will actually be built
+  # Report which library types will actually be built
   AC_MSG_CHECKING([if libtool supports shared libraries])
   AC_MSG_RESULT([$can_build_shared])
 
   AC_MSG_CHECKING([whether to build shared libraries])
-  test no = "$can_build_shared" && enable_shared=no
+  test "$can_build_shared" = "no" && enable_shared=no
 
   # On AIX, shared libraries and static libraries use the same namespace, and
   # are all built from PIC.
   case $host_os in
   aix3*)
-    test yes = "$enable_shared" && enable_static=no
+    test "$enable_shared" = yes && enable_static=no
     if test -n "$RANLIB"; then
       archive_cmds="$archive_cmds~\$RANLIB \$lib"
       postinstall_cmds='$RANLIB $lib'
@@ -6274,12 +5809,8 @@ if test -n "$compiler"; then
     ;;
 
   aix[[4-9]]*)
-    if test ia64 != "$host_cpu"; then
-      case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-      yes,aix,yes) ;;			# shared object as lib.so file only
-      yes,svr4,*) ;;			# shared object as lib.so archive member only
-      yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-      esac
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
     fi
     ;;
   esac
@@ -6287,13 +5818,13 @@ if test -n "$compiler"; then
 
   AC_MSG_CHECKING([whether to build static libraries])
   # Make sure either enable_shared or enable_static is yes.
-  test yes = "$enable_shared" || enable_static=yes
+  test "$enable_shared" = yes || enable_static=yes
   AC_MSG_RESULT([$enable_static])
 
   _LT_CONFIG($1)
 fi
 AC_LANG_POP
-CC=$lt_save_CC
+CC="$lt_save_CC"
 ])# _LT_LANG_C_CONFIG
 
 
@@ -6301,14 +5832,14 @@ CC=$lt_save_CC
 # --------------------------
 # Ensure that the configuration variables for a C++ compiler are suitably
 # defined.  These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to 'libtool'.
+# the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_CXX_CONFIG],
 [m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_EGREP])dnl
 m4_require([_LT_PATH_MANIFEST_TOOL])dnl
-if test -n "$CXX" && ( test no != "$CXX" &&
-    ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
-    (test g++ != "$CXX"))); then
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
   AC_PROG_CXXCPP
 else
   _lt_caught_CXX_error=yes
@@ -6350,7 +5881,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the CXX compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_caught_CXX_error"; then
+if test "$_lt_caught_CXX_error" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="int some_variable = 0;"
 
@@ -6392,35 +5923,35 @@ if test yes != "$_lt_caught_CXX_error"; then
   if test -n "$compiler"; then
     # We don't want -fno-exception when compiling C++ code, so set the
     # no_builtin_flag separately
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
     else
       _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
     fi
 
-    if test yes = "$GXX"; then
+    if test "$GXX" = yes; then
       # Set up default GNU C++ configuration
 
       LT_PATH_LD
 
       # Check if GNU C++ uses GNU ld as the underlying linker, since the
       # archiving commands below assume that GNU ld is being used.
-      if test yes = "$with_gnu_ld"; then
-        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
 
         # If archive_cmds runs LD, not CC, wlarc should be empty
         # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
         #     investigate it a little bit more. (MM)
-        wlarc='$wl'
+        wlarc='${wl}'
 
         # ancient GNU ld didn't support --whole-archive et. al.
         if eval "`$CC -print-prog-name=ld` --help 2>&1" |
 	  $GREP 'no-whole-archive' > /dev/null; then
-          _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
         else
           _LT_TAGVAR(whole_archive_flag_spec, $1)=
         fi
@@ -6456,30 +5987,18 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=no
         ;;
       aix[[4-9]]*)
-        if test ia64 = "$host_cpu"; then
+        if test "$host_cpu" = ia64; then
           # On IA64, the linker does run time linking by default, so we don't
           # have to do anything special.
           aix_use_runtimelinking=no
           exp_sym_flag='-Bexport'
-          no_entry_flag=
+          no_entry_flag=""
         else
           aix_use_runtimelinking=no
 
           # Test if we are trying to use run time linking or normal
           # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-          # have runtime linking enabled, and use it for executables.
-          # For shared libraries, we enable/disable runtime linking
-          # depending on the kind of the shared library created -
-          # when "with_aix_soname,aix_use_runtimelinking" is:
-          # "aix,no"   lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "aix,yes"  lib.so          shared, rtl:yes, for executables
-          #            lib.a           static archive
-          # "both,no"  lib.so.V(shr.o) shared, rtl:yes
-          #            lib.a(lib.so.V) shared, rtl:no,  for executables
-          # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a(lib.so.V) shared, rtl:no
-          # "svr4,*"   lib.so.V(shr.o) shared, rtl:yes, for executables
-          #            lib.a           static archive
+          # need to do runtime linking.
           case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
 	    for ld_flag in $LDFLAGS; do
 	      case $ld_flag in
@@ -6489,13 +6008,6 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        ;;
 	      esac
 	    done
-	    if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
-	      # With aix-soname=svr4, we create the lib.so.V shared archives only,
-	      # so we don't have lib.a shared libs to link our executables.
-	      # We have to force runtime linking in this case.
-	      aix_use_runtimelinking=yes
-	      LDFLAGS="$LDFLAGS -Wl,-brtl"
-	    fi
 	    ;;
           esac
 
@@ -6514,21 +6026,13 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
         _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
         _LT_TAGVAR(link_all_deplibs, $1)=yes
-        _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
-        case $with_aix_soname,$aix_use_runtimelinking in
-        aix,*) ;;	# no import file
-        svr4,* | *,yes) # use import file
-          # The Import File defines what to hardcode.
-          _LT_TAGVAR(hardcode_direct, $1)=no
-          _LT_TAGVAR(hardcode_direct_absolute, $1)=no
-          ;;
-        esac
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
 
-        if test yes = "$GXX"; then
+        if test "$GXX" = yes; then
           case $host_os in aix4.[[012]]|aix4.[[012]].*)
           # We only want to do this on AIX 4.2 and lower, the check
           # below for broken collect2 doesn't work under 4.3+
-	  collect2name=`$CC -print-prog-name=collect2`
+	  collect2name=`${CC} -print-prog-name=collect2`
 	  if test -f "$collect2name" &&
 	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
 	  then
@@ -6546,84 +6050,64 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  fi
           esac
           shared_flag='-shared'
-	  if test yes = "$aix_use_runtimelinking"; then
-	    shared_flag=$shared_flag' $wl-G'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
 	  fi
-	  # Need to ensure runtime linking is disabled for the traditional
-	  # shared library, or the linker may eventually find shared libraries
-	  # /with/ Import File - we do not want to mix them.
-	  shared_flag_aix='-shared'
-	  shared_flag_svr4='-shared $wl-G'
         else
           # not using gcc
-          if test ia64 = "$host_cpu"; then
+          if test "$host_cpu" = ia64; then
 	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
 	  # chokes on -Wl,-G. The following line is correct:
 	  shared_flag='-G'
           else
-	    if test yes = "$aix_use_runtimelinking"; then
-	      shared_flag='$wl-G'
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
 	    else
-	      shared_flag='$wl-bM:SRE'
+	      shared_flag='${wl}-bM:SRE'
 	    fi
-	    shared_flag_aix='$wl-bM:SRE'
-	    shared_flag_svr4='$wl-G'
           fi
         fi
 
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
         # It seems that -bexpall does not export symbols beginning with
         # underscore (_), so it is better to generate a list of symbols to
 	# export.
         _LT_TAGVAR(always_export_symbols, $1)=yes
-	if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+        if test "$aix_use_runtimelinking" = yes; then
           # Warning - without using the other runtime loading flags (-brtl),
           # -berok will link without error, but may produce a broken library.
-          # The "-G" linker flag allows undefined symbols.
-          _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
           # Determine the default libpath from the value encoded in an empty
           # executable.
           _LT_SYS_MODULE_PATH_AIX([$1])
-          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
         else
-          if test ia64 = "$host_cpu"; then
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
 	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
           else
 	    # Determine the default libpath from the value encoded in an
 	    # empty executable.
 	    _LT_SYS_MODULE_PATH_AIX([$1])
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 	    # Warning - without using the other run time loading flags,
 	    # -berok will link without error, but may produce a broken library.
-	    _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
-	    _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
-	    if test yes = "$with_gnu_ld"; then
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
 	      # We only use this code for GNU lds that support --whole-archive.
-	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    else
 	      # Exported symbols can be pulled into shared objects from archives
 	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
 	    fi
 	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
-	    # -brtl affects multiple linker settings, -berok does not and is overridden later
-	    compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
-	    if test svr4 != "$with_aix_soname"; then
-	      # This is similar to how AIX traditionally builds its shared
-	      # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
-	    fi
-	    if test aix != "$with_aix_soname"; then
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# [...]
-	    else
-	      # used by -dlpreopen to get the symbols
-	      _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  $output_objdir/$realname.d/$soname $output_objdir'
-	    fi
-	    _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
           fi
         fi
         ;;
@@ -6633,7 +6117,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
 	  # support --undefined.  This deserves some investigation.  FIXME
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
 	else
 	  _LT_TAGVAR(ld_shlibs, $1)=no
 	fi
@@ -6661,58 +6145,57 @@ if test yes != "$_lt_caught_CXX_error"; then
 	  # Tell ltmain to make .lib files, not .a files.
 	  libext=lib
 	  # Tell ltmain to make .dll files, not .so files.
-	  shrext_cmds=.dll
+	  shrext_cmds=".dll"
 	  # FIXME: Setting linknames here is a bad hack.
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-              cp "$export_symbols" "$output_objdir/$soname.def";
-              echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
-            else
-              $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
-            fi~
-            $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
-            linknames='
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
 	  # The linker will not automatically build a static lib if we build a DLL.
 	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 	  # Don't use ranlib
 	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
 	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
-            lt_tool_outputfile="@TOOL_OUTPUT@"~
-            case $lt_outputfile in
-              *.exe|*.EXE) ;;
-              *)
-                lt_outputfile=$lt_outputfile.exe
-                lt_tool_outputfile=$lt_tool_outputfile.exe
-                ;;
-            esac~
-            func_to_tool_file "$lt_outputfile"~
-            if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
-              $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
-              $RM "$lt_outputfile.manifest";
-            fi'
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
 	  ;;
 	*)
 	  # g++
 	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
 	  # as there is no search path for DLLs.
 	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
 	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	  _LT_TAGVAR(always_export_symbols, $1)=no
 	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
 
 	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-	    # If the export-symbols file already is a .def file, use it as
-	    # is; otherwise, prepend EXPORTS...
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
-              cp $export_symbols $output_objdir/$soname.def;
-            else
-              echo EXPORTS > $output_objdir/$soname.def;
-              cat $export_symbols >> $output_objdir/$soname.def;
-            fi~
-            $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
 	  else
 	    _LT_TAGVAR(ld_shlibs, $1)=no
 	  fi
@@ -6723,34 +6206,6 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_DARWIN_LINKER_FEATURES($1)
 	;;
 
-      os2*)
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-	_LT_TAGVAR(hardcode_minus_L, $1)=yes
-	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-	shrext_cmds=.dll
-	_LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
-	  $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
-	  $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
-	  $ECHO EXPORTS >> $output_objdir/$libname.def~
-	  prefix_cmds="$SED"~
-	  if test EXPORTS = "`$SED 1q $export_symbols`"; then
-	    prefix_cmds="$prefix_cmds -e 1d";
-	  fi~
-	  prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
-	  cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
-	  $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
-	  emximp -o $lib $output_objdir/$libname.def'
-	_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
-	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-	;;
-
       dgux*)
         case $cc_basename in
           ec++*)
@@ -6786,14 +6241,14 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
       haiku*)
-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
         _LT_TAGVAR(link_all_deplibs, $1)=yes
         ;;
 
       hpux9*)
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
         _LT_TAGVAR(hardcode_libdir_separator, $1)=:
-        _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
         _LT_TAGVAR(hardcode_direct, $1)=yes
         _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
 				             # but as the default
@@ -6805,7 +6260,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             _LT_TAGVAR(ld_shlibs, $1)=no
             ;;
           aCC*)
-            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             # Commands to make compiler produce verbose output that lists
             # what "hidden" libraries, object files and flags are used when
             # linking a shared library.
@@ -6814,11 +6269,11 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
-            if test yes = "$GXX"; then
-              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             else
               # FIXME: insert proper C++ library support
               _LT_TAGVAR(ld_shlibs, $1)=no
@@ -6828,15 +6283,15 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
       hpux10*|hpux11*)
-        if test no = "$with_gnu_ld"; then
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
 	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
           case $host_cpu in
             hppa*64*|ia64*)
               ;;
             *)
-	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
               ;;
           esac
         fi
@@ -6862,13 +6317,13 @@ if test yes != "$_lt_caught_CXX_error"; then
           aCC*)
 	    case $host_cpu in
 	      hppa*64*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      ia64*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	      *)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	        ;;
 	    esac
 	    # Commands to make compiler produce verbose output that lists
@@ -6879,20 +6334,20 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
 	        case $host_cpu in
 	          hppa*64*)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          ia64*)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	          *)
-	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	            ;;
 	        esac
 	      fi
@@ -6907,22 +6362,22 @@ if test yes != "$_lt_caught_CXX_error"; then
       interix[[3-9]]*)
 	_LT_TAGVAR(hardcode_direct, $1)=no
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
 	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
 	# Instead, shared libraries are loaded at an image base (0x10000000 by
 	# default) and relocated if they conflict, which is a slow very memory
 	# consuming and fragmenting process.  To avoid this, we pick a random,
 	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
 	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
-	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
 	;;
       irix5* | irix6*)
         case $cc_basename in
           CC*)
 	    # SGI C++
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
@@ -6931,17 +6386,17 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
 	    ;;
           *)
-	    if test yes = "$GXX"; then
-	      if test no = "$with_gnu_ld"; then
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 	      else
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
 	      fi
 	    fi
 	    _LT_TAGVAR(link_all_deplibs, $1)=yes
 	    ;;
         esac
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
         _LT_TAGVAR(hardcode_libdir_separator, $1)=:
         _LT_TAGVAR(inherit_rpath, $1)=yes
         ;;
@@ -6954,8 +6409,8 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
 	    # Commands to make compiler produce verbose output that lists
 	    # what "hidden" libraries, object files and flags are used when
 	    # linking a shared library.
@@ -6964,10 +6419,10 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
 
 	    # Archives containing C++ object files must be created using
 	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
@@ -6981,59 +6436,59 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # earlier do not add the objects themselves.
 	    case `$CC -V 2>&1` in
 	      *"Version 7."*)
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	      *)  # Version 8.0 or newer
 	        tmp_idyn=
 	        case $host_cpu in
 		  ia64*) tmp_idyn=' -i_dynamic';;
 		esac
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 		;;
 	    esac
 	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
 	    ;;
           pgCC* | pgcpp*)
             # Portland Group C++ compiler
 	    case `$CC -V` in
 	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
 	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
-               rm -rf $tpldir~
-               $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
-               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
 	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
-                $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
-                $RANLIB $oldlib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
 	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
 	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
-                rm -rf $tpldir~
-                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-                $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    *) # Version 6 and above use weak symbols
-	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
 	      ;;
 	    esac
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
             ;;
 	  cxx*)
 	    # Compaq C++
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname  -o $lib $wl-retain-symbols-file $wl$export_symbols'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
 
 	    runpath_var=LD_RUN_PATH
 	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -7047,18 +6502,18 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
 	    ;;
 	  xl* | mpixl* | bgxl*)
 	    # IBM XL 8.0 on PPC, with GNU ld
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
-	    if test yes = "$supports_anon_versioning"; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
 	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
-                cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-                echo "local: *; };" >> $output_objdir/$libname.ver~
-                $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
 	    fi
 	    ;;
 	  *)
@@ -7066,10 +6521,10 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    *Sun\ C*)
 	      # Sun C++ 5.9
 	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	      _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
-	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
 	      _LT_TAGVAR(compiler_needs_object, $1)=yes
 
 	      # Not sure whether something based on
@@ -7127,17 +6582,22 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=yes
 	;;
 
-      openbsd* | bitrig*)
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
 	if test -f /usr/libexec/ld.so; then
 	  _LT_TAGVAR(hardcode_direct, $1)=yes
 	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
 	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
 	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
-	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
-	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
-	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
-	    _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
 	  fi
 	  output_verbose_link_cmd=func_echo_all
 	else
@@ -7153,9 +6613,9 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # KCC will only create a shared library if the output file
 	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
 	    # to its proper name (with version) after linking.
-	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
 
-	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
 	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	    # Archives containing C++ object files must be created using
@@ -7173,17 +6633,17 @@ if test yes != "$_lt_caught_CXX_error"; then
           cxx*)
 	    case $host in
 	      osf3*)
-	        _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
-	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 		;;
 	      *)
 	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
-                  echo "-hidden">> $lib.exp~
-                  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
-                  $RM $lib.exp'
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
 	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
 		;;
 	    esac
@@ -7198,21 +6658,21 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	  *)
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
 	      case $host in
 	        osf3*)
-	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	        *)
-	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
 		  ;;
 	      esac
 
-	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
 	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
 
 	      # Commands to make compiler produce verbose output that lists
@@ -7258,9 +6718,9 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # Sun C++ 4.2, 5.x and Centerline C++
             _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
 	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
 	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-              $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
 	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -7268,7 +6728,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
 	      *)
 		# The compiler driver will combine and reorder linker options,
-		# but understands '-z linker_flag'.
+		# but understands `-z linker_flag'.
 	        # Supported since Solaris 2.6 (maybe 2.5.1?)
 		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
 	        ;;
@@ -7285,30 +6745,30 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    ;;
           gcx*)
 	    # Green Hills C++ Compiler
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 
 	    # The C++ compiler must be used to create the archive.
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
 	    ;;
           *)
 	    # GNU C++ compiler with Solaris linker
-	    if test yes,no = "$GXX,$with_gnu_ld"; then
-	      _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
 	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      else
-	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
 	        # platform.
-	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
 	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                  $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
@@ -7316,11 +6776,11 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 	      fi
 
-	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
 	      case $host_os in
 		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
 		*)
-		  _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
 		  ;;
 	      esac
 	    fi
@@ -7329,52 +6789,52 @@ if test yes != "$_lt_caught_CXX_error"; then
         ;;
 
     sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
-      _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
       _LT_TAGVAR(archive_cmds_need_lc, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       runpath_var='LD_RUN_PATH'
 
       case $cc_basename in
         CC*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
 	*)
-	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	  ;;
       esac
       ;;
 
       sysv5* | sco3.2v5* | sco5v6*)
-	# Note: We CANNOT use -z defs as we might desire, because we do not
+	# Note: We can NOT use -z defs as we might desire, because we do not
 	# link with -lc, and that would cause any symbols used from libc to
 	# always be unresolved, which means just about no library would
 	# ever link correctly.  If we're not using GNU ld we use -z text
 	# though, which does catch some bad symbols but isn't as heavy-handed
 	# as -z defs.
-	_LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
-	_LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
 	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
 	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
-	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
 	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
 	_LT_TAGVAR(link_all_deplibs, $1)=yes
-	_LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
 	runpath_var='LD_RUN_PATH'
 
 	case $cc_basename in
           CC*)
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
-              '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	      '"$_LT_TAGVAR(old_archive_cmds, $1)"
 	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
-              '"$_LT_TAGVAR(reload_cmds, $1)"
+	      '"$_LT_TAGVAR(reload_cmds, $1)"
 	    ;;
 	  *)
-	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
-	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
 	    ;;
 	esac
       ;;
@@ -7405,10 +6865,10 @@ if test yes != "$_lt_caught_CXX_error"; then
     esac
 
     AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-    test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
 
-    _LT_TAGVAR(GCC, $1)=$GXX
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7435,7 +6895,7 @@ if test yes != "$_lt_caught_CXX_error"; then
   lt_cv_path_LD=$lt_save_path_LD
   lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
   lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test yes != "$_lt_caught_CXX_error"
+fi # test "$_lt_caught_CXX_error" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_CXX_CONFIG
@@ -7457,14 +6917,13 @@ AC_REQUIRE([_LT_DECL_SED])
 AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
 func_stripname_cnf ()
 {
-  case @S|@2 in
-  .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
-  *)  func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
   esac
 } # func_stripname_cnf
 ])# _LT_FUNC_STRIPNAME_CNF
 
-
 # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
 # ---------------------------------
 # Figure out "hidden" library dependencies from verbose
@@ -7548,13 +7007,13 @@ if AC_TRY_EVAL(ac_compile); then
   pre_test_object_deps_done=no
 
   for p in `eval "$output_verbose_link_cmd"`; do
-    case $prev$p in
+    case ${prev}${p} in
 
     -L* | -R* | -l*)
        # Some compilers place space between "-{L,R}" and the path.
        # Remove the space.
-       if test x-L = "$p" ||
-          test x-R = "$p"; then
+       if test $p = "-L" ||
+          test $p = "-R"; then
 	 prev=$p
 	 continue
        fi
@@ -7570,16 +7029,16 @@ if AC_TRY_EVAL(ac_compile); then
        case $p in
        =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
        esac
-       if test no = "$pre_test_object_deps_done"; then
-	 case $prev in
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
 	 -L | -R)
 	   # Internal compiler library paths should come after those
 	   # provided the user.  The postdeps already come after the
 	   # user supplied libs so there is no need to process them.
 	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
-	     _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
 	   else
-	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
 	   fi
 	   ;;
 	 # The "-l" case would never come before the object being
@@ -7587,9 +7046,9 @@ if AC_TRY_EVAL(ac_compile); then
 	 esac
        else
 	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
-	   _LT_TAGVAR(postdeps, $1)=$prev$p
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
 	 else
-	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
 	 fi
        fi
        prev=
@@ -7604,15 +7063,15 @@ if AC_TRY_EVAL(ac_compile); then
 	 continue
        fi
 
-       if test no = "$pre_test_object_deps_done"; then
+       if test "$pre_test_object_deps_done" = no; then
 	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
-	   _LT_TAGVAR(predep_objects, $1)=$p
+	   _LT_TAGVAR(predep_objects, $1)="$p"
 	 else
 	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
 	 fi
        else
 	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
-	   _LT_TAGVAR(postdep_objects, $1)=$p
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
 	 else
 	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
 	 fi
@@ -7643,6 +7102,51 @@ interix[[3-9]]*)
   _LT_TAGVAR(postdep_objects,$1)=
   _LT_TAGVAR(postdeps,$1)=
   ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
 esac
 ])
 
@@ -7651,7 +7155,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in
 esac
  _LT_TAGVAR(compiler_lib_search_dirs, $1)=
 if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
 fi
 _LT_TAGDECL([], [compiler_lib_search_dirs], [1],
     [The directories searched by this compiler when creating a shared library])
@@ -7671,10 +7175,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1],
 # --------------------------
 # Ensure that the configuration variables for a Fortran 77 compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_F77_CONFIG],
 [AC_LANG_PUSH(Fortran 77)
-if test -z "$F77" || test no = "$F77"; then
+if test -z "$F77" || test "X$F77" = "Xno"; then
   _lt_disable_F77=yes
 fi
 
@@ -7711,7 +7215,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the F77 compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_F77"; then
+if test "$_lt_disable_F77" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="\
       subroutine t
@@ -7733,7 +7237,7 @@ if test yes != "$_lt_disable_F77"; then
   _LT_LINKER_BOILERPLATE
 
   # Allow CC to be a program name with arguments.
-  lt_save_CC=$CC
+  lt_save_CC="$CC"
   lt_save_GCC=$GCC
   lt_save_CFLAGS=$CFLAGS
   CC=${F77-"f77"}
@@ -7747,25 +7251,21 @@ if test yes != "$_lt_disable_F77"; then
     AC_MSG_RESULT([$can_build_shared])
 
     AC_MSG_CHECKING([whether to build shared libraries])
-    test no = "$can_build_shared" && enable_shared=no
+    test "$can_build_shared" = "no" && enable_shared=no
 
     # On AIX, shared libraries and static libraries use the same namespace, and
     # are all built from PIC.
     case $host_os in
       aix3*)
-        test yes = "$enable_shared" && enable_static=no
+        test "$enable_shared" = yes && enable_static=no
         if test -n "$RANLIB"; then
           archive_cmds="$archive_cmds~\$RANLIB \$lib"
           postinstall_cmds='$RANLIB $lib'
         fi
         ;;
       aix[[4-9]]*)
-	if test ia64 != "$host_cpu"; then
-	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-	  yes,aix,yes) ;;		# shared object as lib.so file only
-	  yes,svr4,*) ;;		# shared object as lib.so archive member only
-	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-	  esac
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
 	fi
         ;;
     esac
@@ -7773,11 +7273,11 @@ if test yes != "$_lt_disable_F77"; then
 
     AC_MSG_CHECKING([whether to build static libraries])
     # Make sure either enable_shared or enable_static is yes.
-    test yes = "$enable_shared" || enable_static=yes
+    test "$enable_shared" = yes || enable_static=yes
     AC_MSG_RESULT([$enable_static])
 
-    _LT_TAGVAR(GCC, $1)=$G77
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7794,9 +7294,9 @@ if test yes != "$_lt_disable_F77"; then
   fi # test -n "$compiler"
 
   GCC=$lt_save_GCC
-  CC=$lt_save_CC
-  CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_F77"
+  CC="$lt_save_CC"
+  CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_F77_CONFIG
@@ -7806,11 +7306,11 @@ AC_LANG_POP
 # -------------------------
 # Ensure that the configuration variables for a Fortran compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_FC_CONFIG],
 [AC_LANG_PUSH(Fortran)
 
-if test -z "$FC" || test no = "$FC"; then
+if test -z "$FC" || test "X$FC" = "Xno"; then
   _lt_disable_FC=yes
 fi
 
@@ -7847,7 +7347,7 @@ _LT_TAGVAR(objext, $1)=$objext
 # the FC compiler isn't working.  Some variables (like enable_shared)
 # are currently assumed to apply to all compilers on this platform,
 # and will be corrupted by setting them based on a non-working compiler.
-if test yes != "$_lt_disable_FC"; then
+if test "$_lt_disable_FC" != yes; then
   # Code to be used in simple compile tests
   lt_simple_compile_test_code="\
       subroutine t
@@ -7869,7 +7369,7 @@ if test yes != "$_lt_disable_FC"; then
   _LT_LINKER_BOILERPLATE
 
   # Allow CC to be a program name with arguments.
-  lt_save_CC=$CC
+  lt_save_CC="$CC"
   lt_save_GCC=$GCC
   lt_save_CFLAGS=$CFLAGS
   CC=${FC-"f95"}
@@ -7885,25 +7385,21 @@ if test yes != "$_lt_disable_FC"; then
     AC_MSG_RESULT([$can_build_shared])
 
     AC_MSG_CHECKING([whether to build shared libraries])
-    test no = "$can_build_shared" && enable_shared=no
+    test "$can_build_shared" = "no" && enable_shared=no
 
     # On AIX, shared libraries and static libraries use the same namespace, and
     # are all built from PIC.
     case $host_os in
       aix3*)
-        test yes = "$enable_shared" && enable_static=no
+        test "$enable_shared" = yes && enable_static=no
         if test -n "$RANLIB"; then
           archive_cmds="$archive_cmds~\$RANLIB \$lib"
           postinstall_cmds='$RANLIB $lib'
         fi
         ;;
       aix[[4-9]]*)
-	if test ia64 != "$host_cpu"; then
-	  case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
-	  yes,aix,yes) ;;		# shared object as lib.so file only
-	  yes,svr4,*) ;;		# shared object as lib.so archive member only
-	  yes,*) enable_static=no ;;	# shared object in lib.a archive as well
-	  esac
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
 	fi
         ;;
     esac
@@ -7911,11 +7407,11 @@ if test yes != "$_lt_disable_FC"; then
 
     AC_MSG_CHECKING([whether to build static libraries])
     # Make sure either enable_shared or enable_static is yes.
-    test yes = "$enable_shared" || enable_static=yes
+    test "$enable_shared" = yes || enable_static=yes
     AC_MSG_RESULT([$enable_static])
 
-    _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
-    _LT_TAGVAR(LD, $1)=$LD
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
 
     ## CAVEAT EMPTOR:
     ## There is no encapsulation within the following macros, do not change
@@ -7935,7 +7431,7 @@ if test yes != "$_lt_disable_FC"; then
   GCC=$lt_save_GCC
   CC=$lt_save_CC
   CFLAGS=$lt_save_CFLAGS
-fi # test yes != "$_lt_disable_FC"
+fi # test "$_lt_disable_FC" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_FC_CONFIG
@@ -7945,7 +7441,7 @@ AC_LANG_POP
 # --------------------------
 # Ensure that the configuration variables for the GNU Java Compiler compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_GCJ_CONFIG],
 [AC_REQUIRE([LT_PROG_GCJ])dnl
 AC_LANG_SAVE
@@ -7979,7 +7475,7 @@ CC=${GCJ-"gcj"}
 CFLAGS=$GCJFLAGS
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
 _LT_CC_BASENAME([$compiler])
 
 # GCJ did not exist at the time GCC didn't implicitly link libc in.
@@ -8016,7 +7512,7 @@ CFLAGS=$lt_save_CFLAGS
 # --------------------------
 # Ensure that the configuration variables for the GNU Go compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_GO_CONFIG],
 [AC_REQUIRE([LT_PROG_GO])dnl
 AC_LANG_SAVE
@@ -8050,7 +7546,7 @@ CC=${GOC-"gccgo"}
 CFLAGS=$GOFLAGS
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)=$LD
+_LT_TAGVAR(LD, $1)="$LD"
 _LT_CC_BASENAME([$compiler])
 
 # Go did not exist at the time GCC didn't implicitly link libc in.
@@ -8087,7 +7583,7 @@ CFLAGS=$lt_save_CFLAGS
 # -------------------------
 # Ensure that the configuration variables for the Windows resource compiler
 # are suitably defined.  These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to 'libtool'.
+# to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_RC_CONFIG],
 [AC_REQUIRE([LT_PROG_RC])dnl
 AC_LANG_SAVE
@@ -8103,7 +7599,7 @@ _LT_TAGVAR(objext, $1)=$objext
 lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
 
 # Code to be used in simple link tests
-lt_simple_link_test_code=$lt_simple_compile_test_code
+lt_simple_link_test_code="$lt_simple_compile_test_code"
 
 # ltmain only uses $CC for tagged configurations so make sure $CC is set.
 _LT_TAG_COMPILER
@@ -8113,7 +7609,7 @@ _LT_COMPILER_BOILERPLATE
 _LT_LINKER_BOILERPLATE
 
 # Allow CC to be a program name with arguments.
-lt_save_CC=$CC
+lt_save_CC="$CC"
 lt_save_CFLAGS=$CFLAGS
 lt_save_GCC=$GCC
 GCC=
@@ -8142,7 +7638,7 @@ AC_DEFUN([LT_PROG_GCJ],
 [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
   [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
     [AC_CHECK_TOOL(GCJ, gcj,)
-      test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
       AC_SUBST(GCJFLAGS)])])[]dnl
 ])
 
@@ -8253,7 +7749,7 @@ lt_ac_count=0
 # Add /usr/xpg4/bin/sed as it is typically found on Solaris
 # along with /bin/sed that truncates output.
 for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
-  test ! -f "$lt_ac_sed" && continue
+  test ! -f $lt_ac_sed && continue
   cat /dev/null > conftest.in
   lt_ac_count=0
   echo $ECHO_N "0123456789$ECHO_C" >conftest.in
@@ -8270,9 +7766,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
     $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
     cmp -s conftest.out conftest.nl || break
     # 10000 chars as input seems more than enough
-    test 10 -lt "$lt_ac_count" && break
+    test $lt_ac_count -gt 10 && break
     lt_ac_count=`expr $lt_ac_count + 1`
-    if test "$lt_ac_count" -gt "$lt_ac_max"; then
+    if test $lt_ac_count -gt $lt_ac_max; then
       lt_ac_max=$lt_ac_count
       lt_cv_path_SED=$lt_ac_sed
     fi
@@ -8296,7 +7792,27 @@ dnl AC_DEFUN([LT_AC_PROG_SED], [])
 # Find out whether the shell is Bourne or XSI compatible,
 # or has some other useful features.
 m4_defun([_LT_CHECK_SHELL_FEATURES],
-[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
   lt_unset=unset
 else
   lt_unset=false
@@ -8320,9 +7836,102 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
 ])# _LT_CHECK_SHELL_FEATURES
 
 
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary parameter first.
+    func_stripname_result=${3}
+    func_stripname_result=${func_stripname_result#"${1}"}
+    func_stripname_result=${func_stripname_result%"${2}"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
 # _LT_PATH_CONVERSION_FUNCTIONS
 # -----------------------------
-# Determine what file name conversion functions should be used by
+# Determine which file name conversion functions should be used by
 # func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
 # for certain cross-compile configurations and native mingw.
 m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
index 94b0829..5d9acd8 100644
--- a/m4/ltoptions.m4
+++ b/m4/ltoptions.m4
@@ -1,14 +1,14 @@
 # Helper functions for option handling.                    -*- Autoconf -*-
 #
-#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
-#   Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
 #   Written by Gary V. Vaughan, 2004
 #
 # This file is free software; the Free Software Foundation gives
 # unlimited permission to copy and/or distribute it, with or without
 # modifications, as long as this notice is preserved.
 
-# serial 8 ltoptions.m4
+# serial 7 ltoptions.m4
 
 # This is to help aclocal find these macros, as it can't see m4_define.
 AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -29,7 +29,7 @@ m4_define([_LT_SET_OPTION],
 [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
 m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
         _LT_MANGLE_DEFUN([$1], [$2]),
-    [m4_warning([Unknown $1 option '$2'])])[]dnl
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
 ])
 
 
@@ -75,15 +75,13 @@ m4_if([$1],[LT_INIT],[
   dnl
   dnl If no reference was made to various pairs of opposing options, then
   dnl we run the default mode handler for the pair.  For example, if neither
-  dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
   dnl archives by default:
   _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
   _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
   _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
   _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
-		   [_LT_ENABLE_FAST_INSTALL])
-  _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
-		   [_LT_WITH_AIX_SONAME([aix])])
+  		   [_LT_ENABLE_FAST_INSTALL])
   ])
 ])# _LT_SET_OPTIONS
 
@@ -114,7 +112,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN],
 [_LT_SET_OPTION([LT_INIT], [dlopen])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'dlopen' option into LT_INIT's first parameter.])
+put the `dlopen' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -150,7 +148,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
 _LT_SET_OPTION([LT_INIT], [win32-dll])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'win32-dll' option into LT_INIT's first parameter.])
+put the `win32-dll' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -159,9 +157,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
 
 # _LT_ENABLE_SHARED([DEFAULT])
 # ----------------------------
-# implement the --enable-shared flag, and supports the 'shared' and
-# 'disable-shared' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_SHARED],
 [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([shared],
@@ -174,14 +172,14 @@ AC_ARG_ENABLE([shared],
     *)
       enable_shared=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_shared=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
@@ -213,9 +211,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], [])
 
 # _LT_ENABLE_STATIC([DEFAULT])
 # ----------------------------
-# implement the --enable-static flag, and support the 'static' and
-# 'disable-static' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_STATIC],
 [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([static],
@@ -228,14 +226,14 @@ AC_ARG_ENABLE([static],
     *)
      enable_static=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_static=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
@@ -267,9 +265,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], [])
 
 # _LT_ENABLE_FAST_INSTALL([DEFAULT])
 # ----------------------------------
-# implement the --enable-fast-install flag, and support the 'fast-install'
-# and 'disable-fast-install' LT_INIT options.
-# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
 m4_define([_LT_ENABLE_FAST_INSTALL],
 [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
 AC_ARG_ENABLE([fast-install],
@@ -282,14 +280,14 @@ AC_ARG_ENABLE([fast-install],
     *)
       enable_fast_install=no
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for pkg in $enableval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$pkg" = "X$p"; then
 	  enable_fast_install=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
     [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
@@ -306,14 +304,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL],
 [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'fast-install' option into LT_INIT's first parameter.])
+the `fast-install' option into LT_INIT's first parameter.])
 ])
 
 AU_DEFUN([AC_DISABLE_FAST_INSTALL],
 [_LT_SET_OPTION([LT_INIT], [disable-fast-install])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the 'disable-fast-install' option into LT_INIT's first parameter.])
+the `disable-fast-install' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
@@ -321,64 +319,11 @@ dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
 dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
 
 
-# _LT_WITH_AIX_SONAME([DEFAULT])
-# ----------------------------------
-# implement the --with-aix-soname flag, and support the `aix-soname=aix'
-# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
-# is either `aix', `both' or `svr4'.  If omitted, it defaults to `aix'.
-m4_define([_LT_WITH_AIX_SONAME],
-[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
-shared_archive_member_spec=
-case $host,$enable_shared in
-power*-*-aix[[5-9]]*,yes)
-  AC_MSG_CHECKING([which variant of shared library versioning to provide])
-  AC_ARG_WITH([aix-soname],
-    [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
-      [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
-    [case $withval in
-    aix|svr4|both)
-      ;;
-    *)
-      AC_MSG_ERROR([Unknown argument to --with-aix-soname])
-      ;;
-    esac
-    lt_cv_with_aix_soname=$with_aix_soname],
-    [AC_CACHE_VAL([lt_cv_with_aix_soname],
-      [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
-    with_aix_soname=$lt_cv_with_aix_soname])
-  AC_MSG_RESULT([$with_aix_soname])
-  if test aix != "$with_aix_soname"; then
-    # For the AIX way of multilib, we name the shared archive member
-    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
-    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
-    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
-    # the AIX toolchain works better with OBJECT_MODE set (default 32).
-    if test 64 = "${OBJECT_MODE-32}"; then
-      shared_archive_member_spec=shr_64
-    else
-      shared_archive_member_spec=shr
-    fi
-  fi
-  ;;
-*)
-  with_aix_soname=aix
-  ;;
-esac
-
-_LT_DECL([], [shared_archive_member_spec], [0],
-    [Shared archive member basename, for filename based shared library versioning on AIX])dnl
-])# _LT_WITH_AIX_SONAME
-
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
-LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
-
-
 # _LT_WITH_PIC([MODE])
 # --------------------
-# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
 # LT_INIT options.
-# MODE is either 'yes' or 'no'.  If omitted, it defaults to 'both'.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
 m4_define([_LT_WITH_PIC],
 [AC_ARG_WITH([pic],
     [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
@@ -389,17 +334,19 @@ m4_define([_LT_WITH_PIC],
     *)
       pic_mode=default
       # Look at the argument we got.  We use all the common list separators.
-      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
       for lt_pkg in $withval; do
-	IFS=$lt_save_ifs
+	IFS="$lt_save_ifs"
 	if test "X$lt_pkg" = "X$lt_p"; then
 	  pic_mode=yes
 	fi
       done
-      IFS=$lt_save_ifs
+      IFS="$lt_save_ifs"
       ;;
     esac],
-    [pic_mode=m4_default([$1], [default])])
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
 
 _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
 ])# _LT_WITH_PIC
@@ -412,7 +359,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE],
 [_LT_SET_OPTION([LT_INIT], [pic-only])
 AC_DIAGNOSE([obsolete],
 [$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the 'pic-only' option into LT_INIT's first parameter.])
+put the `pic-only' option into LT_INIT's first parameter.])
 ])
 
 dnl aclocal-1.4 backwards compatibility:
diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4
index 48bc934..9000a05 100644
--- a/m4/ltsugar.m4
+++ b/m4/ltsugar.m4
@@ -1,7 +1,6 @@
 # ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
 #
-# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
-# Foundation, Inc.
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
 # Written by Gary V. Vaughan, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -34,7 +33,7 @@ m4_define([_lt_join],
 # ------------
 # Manipulate m4 lists.
 # These macros are necessary as long as will still need to support
-# Autoconf-2.59, which quotes differently.
+# Autoconf-2.59 which quotes differently.
 m4_define([lt_car], [[$1]])
 m4_define([lt_cdr],
 [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
@@ -45,7 +44,7 @@ m4_define([lt_unquote], $1)
 
 # lt_append(MACRO-NAME, STRING, [SEPARATOR])
 # ------------------------------------------
-# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
 # Note that neither SEPARATOR nor STRING are expanded; they are appended
 # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
 # No SEPARATOR is output if MACRO-NAME was previously undefined (different
diff --git a/m4/ltversion.m4 b/m4/ltversion.m4
index fa04b52..07a8602 100644
--- a/m4/ltversion.m4
+++ b/m4/ltversion.m4
@@ -1,6 +1,6 @@
 # ltversion.m4 -- version numbers			-*- Autoconf -*-
 #
-#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+#   Copyright (C) 2004 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -9,15 +9,15 @@
 
 # @configure_input@
 
-# serial 4179 ltversion.m4
+# serial 3337 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.4.6])
-m4_define([LT_PACKAGE_REVISION], [2.4.6])
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.6'
-macro_revision='2.4.6'
+[macro_version='2.4.2'
+macro_revision='1.3337'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4
index c6b26f8..c573da9 100644
--- a/m4/lt~obsolete.m4
+++ b/m4/lt~obsolete.m4
@@ -1,7 +1,6 @@
 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 #
-#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
-#   Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004.
 #
 # This file is free software; the Free Software Foundation gives
@@ -12,7 +11,7 @@
 
 # These exist entirely to fool aclocal when bootstrapping libtool.
 #
-# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
 # which have later been changed to m4_define as they aren't part of the
 # exported API, or moved to Autoconf or Automake where they belong.
 #
@@ -26,7 +25,7 @@
 # included after everything else.  This provides aclocal with the
 # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
 # because those macros already exist, or will be overwritten later.
-# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
 #
 # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
 # Yes, that means every name once taken will need to remain here until
diff --git a/m4/scilab.m4 b/m4/scilab.m4
index b644695..e2ac2f3 100644
--- a/m4/scilab.m4
+++ b/m4/scilab.m4
@@ -1,3 +1,18 @@
+dnl Copyright (C) 2009-2017 Yann Colette
+dnl 
+dnl This file is  free software;  you  can  redistribute  it  and/or modify it
+dnl under  the  terms  of the  GNU  Lesser General Public License as published
+dnl by  the  Free Software Foundation;  either version 3 of the License,  or
+dnl (at your option) any later version along with the GCC Runtime Library
+dnl Exception either version 3.1 or (at your option) any later version.
+dnl This program  is  distributed  in  the  hope  that it will be useful,  but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+dnl or  FITNESS  FOR  A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+dnl License and GCC Runtime Library Exception for more details.
+dnl You  should  have received a copy of the GNU Lesser General Public License
+dnl along  with  this program;  if not, write to the Free Software Foundation,
+dnl Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 AC_DEFUN([AC_CHECK_SCILAB],
 [
   AH_TEMPLATE(HAVE_SCILAB,
diff --git a/mkinstalldirs b/mkinstalldirs
index 4b6f7c1..994d71c 100755
--- a/mkinstalldirs
+++ b/mkinstalldirs
@@ -4,7 +4,7 @@
 # Created: 1993-05-16
 # Public domain
 
-# $Id: mkinstalldirs 1866 2005-01-27 13:22:54Z pommier $
+# $Id$
 
 errstatus=0
 dirmode=""
diff --git a/src/Makefile.am b/src/Makefile.am
index 3ea12b8..cc060d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 nobase_include_HEADERS =                   		\
 	getfem_boost/workaround.hpp        		\
 	getfem_boost/noncopyable.hpp       		\
@@ -162,6 +179,8 @@ SRC =                                      		\
 	bgeot_poly.cc                      		\
 	bgeot_poly_composite.cc            		\
 	bgeot_ftool.cc                     		\
+	getfem_models.cc                 		\
+	getfem_model_solvers.cc                		\
 	getfem_superlu.cc		   		\
 	getfem_mesh.cc                     		\
 	getfem_mesh_region.cc              		\
@@ -198,8 +217,6 @@ SRC =                                      		\
 	getfem_assembling_tensors.cc       		\
 	getfem_generic_assembly.cc       		\
 	getfem_mesher.cc		   		\
-	getfem_models.cc                 		\
-	getfem_model_solvers.cc                		\
 	getfem_fourth_order.cc                		\
 	getfem_nonlinear_elasticity.cc                  \
 	getfem_linearized_plates.cc               	\
diff --git a/src/Makefile.in b/src/Makefile.in
index 9ffac1c..e2f745c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,26 @@
 
 @SET_MAKE@
 
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -90,6 +97,9 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = src
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(nobase_include_HEADERS)
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -105,8 +115,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \
-	$(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -147,9 +155,10 @@ am__objects_1 = dal_backtrace.lo dal_bit_vector.lo dal_singleton.lo \
 	bgeot_geometric_trans.lo bgeot_geotrans_inv.lo bgeot_kdtree.lo \
 	bgeot_mesh_structure.lo bgeot_rtree.lo bgeot_node_tab.lo \
 	bgeot_small_vector.lo bgeot_sparse_tensors.lo bgeot_poly.lo \
-	bgeot_poly_composite.lo bgeot_ftool.lo getfem_superlu.lo \
-	getfem_mesh.lo getfem_mesh_region.lo getfem_context.lo \
-	getfem_mesh_fem.lo getfem_mesh_im.lo getfem_integration.lo \
+	bgeot_poly_composite.lo bgeot_ftool.lo getfem_models.lo \
+	getfem_model_solvers.lo getfem_superlu.lo getfem_mesh.lo \
+	getfem_mesh_region.lo getfem_context.lo getfem_mesh_fem.lo \
+	getfem_mesh_im.lo getfem_integration.lo \
 	getfem_integration_composite.lo getfem_global_function.lo \
 	getfem_fem.lo getfem_interpolated_fem.lo \
 	getfem_projected_fem.lo getfem_fem_global_function.lo \
@@ -163,9 +172,9 @@ am__objects_1 = dal_backtrace.lo dal_bit_vector.lo dal_singleton.lo \
 	getfem_regular_meshes.lo getfem_import.lo \
 	getfem_interpolation.lo getfem_error_estimate.lo \
 	getfem_export.lo getfem_assembling_tensors.lo \
-	getfem_generic_assembly.lo getfem_mesher.lo getfem_models.lo \
-	getfem_model_solvers.lo getfem_fourth_order.lo \
-	getfem_nonlinear_elasticity.lo getfem_linearized_plates.lo \
+	getfem_generic_assembly.lo getfem_mesher.lo \
+	getfem_fourth_order.lo getfem_nonlinear_elasticity.lo \
+	getfem_linearized_plates.lo \
 	getfem_contact_and_friction_common.lo \
 	getfem_contact_and_friction_nodal.lo \
 	getfem_contact_and_friction_integral.lo \
@@ -242,8 +251,6 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -311,7 +318,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -344,8 +350,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -426,7 +434,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -599,6 +606,8 @@ SRC = \
 	bgeot_poly.cc                      		\
 	bgeot_poly_composite.cc            		\
 	bgeot_ftool.cc                     		\
+	getfem_models.cc                 		\
+	getfem_model_solvers.cc                		\
 	getfem_superlu.cc		   		\
 	getfem_mesh.cc                     		\
 	getfem_mesh_region.cc              		\
@@ -635,8 +644,6 @@ SRC = \
 	getfem_assembling_tensors.cc       		\
 	getfem_generic_assembly.cc       		\
 	getfem_mesher.cc		   		\
-	getfem_models.cc                 		\
-	getfem_model_solvers.cc                		\
 	getfem_fourth_order.cc                		\
 	getfem_nonlinear_elasticity.cc                  \
 	getfem_linearized_plates.cc               	\
@@ -674,6 +681,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -1066,8 +1074,6 @@ uninstall-am: uninstall-libLTLIBRARIES uninstall-nobase_includeHEADERS
 	tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \
 	uninstall-nobase_includeHEADERS
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/bgeot_convex_ref.cc b/src/bgeot_convex_ref.cc
index 5080abc..613ab8c 100644
--- a/src/bgeot_convex_ref.cc
+++ b/src/bgeot_convex_ref.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2001-2016 Yves Renard
+ Copyright (C) 2001-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -134,19 +134,19 @@ namespace bgeot {
   class K_simplex_of_ref_ : public convex_of_reference {
   public :
     scalar_type is_in(const base_node &pt) const {
-      // return a negative or null number if pt is in the convex
+      // return a negative number if pt is in the convex
       GMM_ASSERT1(pt.size() == cvs->dim(),
-                  "K_simplex_of_ref_::is_in: Dimension does not match");
+                  "K_simplex_of_ref_::is_in: Dimensions mismatch");
       scalar_type e = -1.0, r = (pt.size() > 0) ? -pt[0] : 0.0;
       base_node::const_iterator it = pt.begin(), ite = pt.end();
       for (; it != ite; e += *it, ++it) r = std::max(r, -(*it));
       return std::max(r, e);
     }
     scalar_type is_in_face(short_type f, const base_node &pt) const {
-      // return a null number if pt is in the face of the convex
+      // return zero if pt is in the face of the convex
       // negative if the point is on the side of the face where the element is
       GMM_ASSERT1(pt.size() == cvs->dim(),
-                  "K_simplex_of_ref_::is_in_face: Dimension does not match");
+                  "K_simplex_of_ref_::is_in_face: Dimensions mismatch");
       if (f > 0) return -pt[f-1];
       scalar_type e = -1.0;
       base_node::const_iterator it = pt.begin(), ite = pt.end();
@@ -214,29 +214,16 @@ namespace bgeot {
   /* By Yao Koutsawa  <yao.koutsawa at tudor.lu> 2012-12-10                  */
 
   class Q2_incomplete_of_ref_ : public convex_of_reference {
+    pconvex_ref pllref;
   public :
-    scalar_type is_in(const base_node& pt) const {
-      // return a negative or null number if pt is in the convex
-      GMM_ASSERT1(pt.size() == cvs->dim(),
-                  "Q2_incomplete_of_ref_::is_in: Dimension does not match");
-      scalar_type e = -1.0, r = (pt.size() > 0) ? -pt[0] : 0.0;
-      base_node::const_iterator it = pt.begin(), ite = pt.end();
-      for (; it != ite; e += *it, ++it) r = std::max(r, -(*it));
-      return std::max(r, e);
-    }
-    scalar_type is_in_face(short_type f, const base_node& pt) const {
-      // return a null number if pt is in the face of the convex
-      // negative if the point is on the side of the face where the element is
-      GMM_ASSERT1(pt.size() == cvs->dim(), "Q2_incomplete_of_ref_::is_in_face: "
-                  "Dimension does not match");
-      if (f > 0) return -pt[f-1];
-      scalar_type e = -1.0;
-      base_node::const_iterator it = pt.begin(), ite = pt.end();
-      for (; it != ite; e += *it, ++it) {};
-      return e / sqrt(scalar_type(pt.size()));
-    }
+    scalar_type is_in(const base_node& pt) const
+    { return pllref->is_in(pt); }
+    scalar_type is_in_face(short_type f, const base_node& pt) const
+    { return pllref->is_in_face(f, pt); }
     
     Q2_incomplete_of_ref_(dim_type nc) {
+      GMM_ASSERT1(nc == 2 || nc == 3, "Sorry exist only in dimension 2 or 3");
+      pllref = parallelepiped_of_reference(nc);
       cvs = Q2_incomplete_structure(nc);
       convex<base_node>::points().resize(cvs->nb_points());
       normals_.resize(nc == 2 ? 4: 6);
@@ -308,6 +295,91 @@ namespace bgeot {
     return p;
   }
 
+  /* ******************************************************************** */
+  /*    Pyramidal element of reference.                                   */
+  /* ******************************************************************** */
+
+  class pyramid_of_ref_ : public convex_of_reference {
+  public :
+    scalar_type is_in_face(short_type f, const base_node& pt) const {
+      // return zero if pt is in the face of the convex
+      // negative if the point is on the side of the face where the element is
+      GMM_ASSERT1(pt.size() == 3, "Dimensions mismatch");
+      if (f == 0)
+	return -pt[2];
+      else
+	return gmm::vect_sp(normals_[f], pt) - sqrt(2.)/2.;
+    }
+    scalar_type is_in(const base_node& pt) const {
+      // return a negative number if pt is in the convex
+      scalar_type r = is_in_face(0, pt);
+      for (short_type i = 1; i < 5; ++i) r = std::max(r, is_in_face(i, pt));
+      return r;
+    }
+    
+    pyramid_of_ref_(dim_type k) {
+      GMM_ASSERT1(k == 1 || k == 2,
+		  "Sorry exist only in degree 1 or 2, not " << k);
+
+      cvs = pyramidal_structure(k);
+      convex<base_node>::points().resize(cvs->nb_points());
+      normals_.resize(cvs->nb_faces());
+      if (k == 1)
+	auto_basic = true;
+      else
+	basic_convex_ref_ = pyramidal_element_of_reference(1);
+
+      sc(normals_[0]) =  0., 0., -1.;
+      sc(normals_[1]) =  0.,-1.,  1.;
+      sc(normals_[2]) =  1., 0.,  1.;
+      sc(normals_[3]) =  0., 1.,  1.;
+      sc(normals_[4]) = -1., 0.,  1.;
+
+      for (size_type i = 0; i < normals_.size(); ++i)
+	gmm::scale(normals_[i], 1. / gmm::vect_norm2(normals_[i]));
+      
+      if (k==1) {
+        convex<base_node>::points()[0]  = base_node(-1.0, -1.0, 0.0);
+        convex<base_node>::points()[1]  = base_node( 1.0, -1.0, 0.0);
+        convex<base_node>::points()[2]  = base_node(-1.0,  1.0, 0.0);
+        convex<base_node>::points()[3]  = base_node( 1.0,  1.0, 0.0);
+        convex<base_node>::points()[4]  = base_node( 0.0,  0.0, 1.0);
+      } else if (k==2) {
+        convex<base_node>::points()[0]  = base_node(-1.0, -1.0, 0.0);
+        convex<base_node>::points()[1]  = base_node( 0.0, -1.0, 0.0);
+        convex<base_node>::points()[2]  = base_node( 1.0, -1.0, 0.0);
+        convex<base_node>::points()[3]  = base_node(-1.0,  0.0, 0.0);
+        convex<base_node>::points()[4]  = base_node( 0.0,  0.0, 0.0);
+        convex<base_node>::points()[5]  = base_node( 1.0,  0.0, 0.0);
+        convex<base_node>::points()[6]  = base_node(-1.0,  1.0, 0.0);
+        convex<base_node>::points()[7]  = base_node( 0.0,  1.0, 0.0);
+        convex<base_node>::points()[8]  = base_node( 1.0,  1.0, 0.0);
+        convex<base_node>::points()[9]  = base_node(-0.5, -0.5, 0.5);
+        convex<base_node>::points()[10] = base_node( 0.5, -0.5, 0.5);
+        convex<base_node>::points()[11] = base_node(-0.5,  0.5, 0.5);
+        convex<base_node>::points()[12] = base_node( 0.5,  0.5, 0.5);
+        convex<base_node>::points()[13] = base_node( 0.0,  0.0, 1.0);
+      }
+      ppoints = store_point_tab(convex<base_node>::points());
+    }
+  };
+  
+  
+  DAL_SIMPLE_KEY(pyramidal_reference_key_, dim_type);
+  
+  pconvex_ref pyramidal_element_of_reference(dim_type k) {
+     dal::pstatic_stored_object_key
+      pk = std::make_shared<pyramidal_reference_key_>(k);
+    dal::pstatic_stored_object o = dal::search_stored_object(pk);
+    if (o) return std::dynamic_pointer_cast<const convex_of_reference>(o);
+    pconvex_ref p = std::make_shared<pyramid_of_ref_>(k);
+    dal::add_stored_object(pk, p, p->structure(), p->pspt(),
+                           dal::PERMANENT_STATIC_OBJECT);
+    pconvex_ref p1 = basic_convex_ref(p);
+    if (p != p1) add_dependency(p, p1); 
+    return p;
+  }
+
 
   /* ******************************************************************** */
   /*    Products.                                                         */
@@ -330,7 +402,7 @@ namespace bgeot {
 
     scalar_type is_in_face(short_type f, const base_node &pt) const {
       // ne controle pas si le point est dans le convexe mais si un point
-      // suppos� appartenir au convexe est dans une face donn�e
+      // suppos\E9 appartenir au convexe est dans une face donn\E9e
       dim_type n1 = cvr1->structure()->dim(), n2 = cvr2->structure()->dim();
       base_node pt1(n1), pt2(n2);
       GMM_ASSERT1(pt.size() == cvs->dim(), "Dimensions mismatch");
@@ -383,20 +455,10 @@ namespace bgeot {
     return p;
   }
 
-  struct parallelepiped_of_reference_tab
-    : public dal::dynamic_array<pconvex_ref> {};
-
-  pconvex_ref parallelepiped_of_reference(dim_type nc) {
-    parallelepiped_of_reference_tab &tab
-      = dal::singleton<parallelepiped_of_reference_tab>::instance();
-    static dim_type ncd = 1;
-    if (nc <= 1) return simplex_of_reference(nc);
-    if (nc > ncd) { 
-      tab[nc] = convex_ref_product(parallelepiped_of_reference(dim_type(nc-1)),
-                                   simplex_of_reference(1));
-      ncd = nc;
-    }
-    return tab[nc];
+  pconvex_ref parallelepiped_of_reference(dim_type nc, dim_type k) {
+    if (nc <= 1) return simplex_of_reference(nc,k);
+    return convex_ref_product(parallelepiped_of_reference(dim_type(nc-1),k),
+			      simplex_of_reference(k));
   }
 
   pconvex_ref prism_of_reference(dim_type nc) {
diff --git a/src/bgeot_convex_ref_simplexified.cc b/src/bgeot_convex_ref_simplexified.cc
index ece2106..94292bb 100644
--- a/src/bgeot_convex_ref_simplexified.cc
+++ b/src/bgeot_convex_ref_simplexified.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard
+ Copyright (C) 2006-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -23,7 +23,7 @@
 #include "getfem/bgeot_convex_ref.h"
 
 
- namespace bgeot {
+namespace bgeot {
 
 
   static size_type simplexified_parallelepiped_2[6] = {
@@ -250,9 +250,14 @@
   };
 
   static size_type simplexified_prism_6_nb = 6;
+ 
+  static size_type simplexified_pyramid[30] = {
+     0, 1, 2, 4, 3, 2, 1, 4
+  };
 
-
-
+  static size_type simplexified_pyramid_nb = 3;
+   
+  
   size_type simplexified_tab(pconvex_structure cvs,
                              size_type **tab) {
     if (cvs == parallelepiped_structure(2)) {
@@ -300,6 +305,11 @@
       return simplexified_prism_6_nb;
     }
 
+    if (cvs == pyramidal_structure(1)) {
+      *tab = simplexified_pyramid;
+      return simplexified_pyramid_nb;
+    }
+
     GMM_ASSERT1(false, "No simplexification for this element");
   }
 
diff --git a/src/bgeot_convex_structure.cc b/src/bgeot_convex_structure.cc
index 85b3567..bb936f3 100644
--- a/src/bgeot_convex_structure.cc
+++ b/src/bgeot_convex_structure.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -28,9 +28,9 @@
 namespace bgeot {
 
   /* ******************************************************************** */
-  /*                                                                          */
+  /*                                                                      */
   /* class   convex_structure                                             */
-  /*                                                                          */
+  /*                                                                      */
   /* ******************************************************************** */
 
   void convex_structure::add_point_adaptative(short_type i, short_type f) {
@@ -358,26 +358,25 @@ namespace bgeot {
     { DAL_STORED_OBJECT_DEBUG_DESTROYED(this, "parallelepiped structure"); }
   };
 
-  DAL_SIMPLE_KEY(parallelepiped_key_, dim_type);
+  DAL_DOUBLE_KEY(parallelepiped_key_, dim_type, dim_type);
 
-  pconvex_structure parallelepiped_structure(dim_type nc) {
-    if (nc <= 1) return simplex_structure(nc);
+  pconvex_structure parallelepiped_structure(dim_type nc, dim_type k) {
+    if (nc <= 1) return simplex_structure(nc, k);
     dal::pstatic_stored_object_key
-      pcsk = std::make_shared<parallelepiped_key_>(nc);
+      pcsk = std::make_shared<parallelepiped_key_>(nc, k);
 
     dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
     if (o) return ((std::dynamic_pointer_cast<const parallelepiped_>(o))->p);
     auto p = std::make_shared<parallelepiped_>();
-    p->p = convex_product_structure(parallelepiped_structure(dim_type(nc-1)),
-                                    simplex_structure(1));
+    p->p = convex_product_structure(parallelepiped_structure(dim_type(nc-1),k),
+                                    simplex_structure(1,k));
     dal::add_stored_object(pcsk, dal::pstatic_stored_object(p), p->p,
                            dal::PERMANENT_STATIC_OBJECT);
     return p->p;
   }
 
-
   /* ******************************************************************** */
-  /*        Incomplete Q2 structure for n=2 or 3.                             */
+  /*        Incomplete Q2 structure for n=2 or 3.                         */
   /* ******************************************************************** */
   /* By Yao Koutsawa  <yao.koutsawa at tudor.lu> 2012-12-10                  */
 
@@ -456,8 +455,106 @@ namespace bgeot {
   }
 
 
+
+  /* ******************************************************************** */
+  /*        Pyramidal 3D structure for k=1 or 2.                          */
+  /* ******************************************************************** */
+
+  struct pyramidal_structure_ : public convex_structure {
+    friend pconvex_structure pyramidal_structure(dim_type k);
+  };
+
+  DAL_SIMPLE_KEY(pyramidal_structure_key_, dim_type);
+
+  pconvex_structure pyramidal_structure(dim_type k) {
+    GMM_ASSERT1(k == 1 || k == 2, "Sorry, pyramidal elements implemented "
+		"only for degree one or two.");
+    dal::pstatic_stored_object_key
+      pcsk = std::make_shared<pyramidal_structure_key_>(k);
+    dal::pstatic_stored_object o = dal::search_stored_object(pcsk);
+    if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
+
+    auto p = std::make_shared<pyramidal_structure_>();
+    pconvex_structure pcvs(p);
+    
+    p->Nc = 3;
+    p->dir_points_ = std::vector<short_type>(p->Nc + 1);
+    
+
+    if (k == 1) {
+      p->nbpt = 5;
+      p->nbf = 5;
+      p->auto_basic = true;
+      //    4 
+      //   /|||
+      //  / || |
+      // 2-|--|-3
+      // | |  | |
+      // ||    ||
+      // ||    ||
+      // 0------1
+      p->faces_struct.resize(p->nbf);
+      p->faces = std::vector< std::vector<short_type> >(p->nbf);
+      sc(p->faces[0]) = 0,1,2,3;
+      sc(p->faces[1]) = 0,1,4;
+      sc(p->faces[2]) = 1,3,4;
+      sc(p->faces[3]) = 3,2,4;
+      sc(p->faces[4]) = 2,0,4;
+
+      p->dir_points_[0] = 0;
+      p->dir_points_[1] = 1;
+      p->dir_points_[2] = 2;
+      p->dir_points_[3] = 4;
+
+      p->faces_struct[0] = parallelepiped_structure(2);
+      for (int i = 1; i < p->nbf; i++)
+	p->faces_struct[i] = simplex_structure(2);
+
+      dal::add_stored_object(pcsk, pcvs, parallelepiped_structure(2),
+			     simplex_structure(2),
+			     dal::PERMANENT_STATIC_OBJECT);
+      
+    } else {
+      p->nbpt = 14;
+      p->nbf = 5;
+      p->basic_pcvs = pyramidal_structure(1);
+      //    13
+      //   /  |
+      //  11--12
+      //  |   |
+      //  9---10
+      //  /    |
+      // 6--7--8
+      // |     |
+      // 3  4  5
+      // |     |
+      // 0--1--2
+      p->faces_struct.resize(p->nbf);
+      p->faces = std::vector< std::vector<short_type> >(p->nbf);
+      sc(p->faces[0]) = 0,1,2,3,4,5,6,7,8;
+      sc(p->faces[1]) = 0,1,2,9,10,13;
+      sc(p->faces[2]) = 2,5,8,10,12,13;
+      sc(p->faces[3]) = 8,7,6,12,11,13;
+      sc(p->faces[4]) = 6,3,0,11,9,13;
+
+      p->dir_points_[0] = 0;
+      p->dir_points_[1] = 2;
+      p->dir_points_[2] = 6;
+      p->dir_points_[3] = 13;
+
+      p->faces_struct[0] = parallelepiped_structure(2, 2);
+      for (int i = 1; i < p->nbf; i++)
+	p->faces_struct[i] = simplex_structure(2, 2);
+
+      dal::add_stored_object(pcsk, pcvs, parallelepiped_structure(2, 2),
+			     simplex_structure(2, 2),
+			     dal::PERMANENT_STATIC_OBJECT);
+    }
+    return pcvs;
+  }
+  
   /* ******************************************************************** */
-  /*        Generic dummy convex with n global nodes.                         */
+  /*        Generic dummy convex with n global nodes.                     */
   /* ******************************************************************** */
 
   struct dummy_structure_ : public convex_structure {
diff --git a/src/bgeot_ftool.cc b/src/bgeot_ftool.cc
index 42bd445..9f6e78a 100644
--- a/src/bgeot_ftool.cc
+++ b/src/bgeot_ftool.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/bgeot_geometric_trans.cc b/src/bgeot_geometric_trans.cc
index af17cf0..54ed28e 100644
--- a/src/bgeot_geometric_trans.cc
+++ b/src/bgeot_geometric_trans.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -28,15 +28,270 @@
 
 namespace bgeot {
 
+  std::vector<scalar_type>& __aux1(){
+    DEFINE_STATIC_THREAD_LOCAL(std::vector<scalar_type>, v);
+    return v;
+  }
+  
+  std::vector<scalar_type>& __aux2(){
+    DEFINE_STATIC_THREAD_LOCAL(std::vector<scalar_type>, v);
+    return v;
+  }
+  
+  std::vector<scalar_type>& __aux3(){
+    DEFINE_STATIC_THREAD_LOCAL(std::vector<scalar_type>, v);
+    return v;
+  }
+  
+  std::vector<int>& __ipvt_aux(){
+    DEFINE_STATIC_THREAD_LOCAL(std::vector<int>, vi);
+    return vi;
+  }
+  
+  // Optimized matrix mult for small matrices. To be verified.
+  // Multiply the matrix A of size MxN by B of size NxP in C of size MxP
+  void mat_mult(const scalar_type *A, const scalar_type *B, scalar_type *C,
+		size_type M, size_type N, size_type P) {
+    if (N != 0) {
+      auto itC = C; auto itB = B;
+      for (size_type j = 0; j < P; ++j, itB += N)
+	for (size_type i = 0; i < M; ++i, ++itC) {
+	  auto itA = A+i, itB1 = itB;
+	  *itC = (*itA) * (*itB1);
+	  for (size_type k = 1; k < N; ++k)
+	    { itA += M; ++itB1; *itC += (*itA) * (*itB1); }
+	}
+    } else std::fill(C, C+M*P, scalar_type(0));
+  }
+
+  // Optimized matrix mult for small matrices.
+  // Multiply the matrix A of size MxN by the transpose of B of size PxN
+  // in C of size MxP
+  void mat_tmult(const scalar_type *A, const scalar_type *B, scalar_type *C,
+		 size_type M, size_type N, size_type P) {
+    auto itC = C;
+    switch (N) {
+    case 0 : std::fill(C, C+M*P, scalar_type(0)); break;
+    case 1 : 
+      for (size_type j = 0; j < P; ++j)
+	for (size_type i = 0; i < M; ++i, ++itC) {
+	  auto itA = A+i, itB = B+j;
+	  *itC = (*itA) * (*itB);
+	}
+      break;
+    case 2 :
+      for (size_type j = 0; j < P; ++j)
+	for (size_type i = 0; i < M; ++i, ++itC) {
+	  auto itA = A+i, itB = B+j;
+	  *itC = (*itA) * (*itB);
+	  itA += M; itB += P; *itC += (*itA) * (*itB);
+	}
+      break;
+    case 3 :
+      for (size_type j = 0; j < P; ++j)
+	for (size_type i = 0; i < M; ++i, ++itC) {
+	  auto itA = A+i, itB = B+j;
+	  *itC = (*itA) * (*itB);
+	  itA += M; itB += P; *itC += (*itA) * (*itB);
+	  itA += M; itB += P; *itC += (*itA) * (*itB);
+	}
+      break;
+    default :
+      for (size_type j = 0; j < P; ++j)
+	for (size_type i = 0; i < M; ++i, ++itC) {
+	  auto itA = A+i, itB = B+j;
+	  *itC = (*itA) * (*itB);
+	  for (size_type k = 1; k < N; ++k)
+	    { itA += M; itB += P; *itC += (*itA) * (*itB); }
+	}
+    }
+  }
+
+
+
+
+  // Optimized lu_factor for small square matrices
+  size_type lu_factor(scalar_type *A, std::vector<int> &ipvt,
+		      size_type N) {
+    size_type info(0), i, j, jp, N_1 = N-1;
+      
+    if (N) {
+      for (j = 0; j < N_1; ++j) {
+	auto it = A + (j*(N+1));
+	scalar_type max = gmm::abs(*it); jp = j;
+	for (i = j+1; i < N; ++i) {
+	  scalar_type ap = gmm::abs(*(++it));
+	  if (ap > max) { jp = i; max = ap; }
+	}
+	ipvt[j] = int(jp + 1);
+	
+	if (max == scalar_type(0)) { info = j + 1; break; }
+        if (jp != j) {
+	  auto it1 = A+jp, it2 = A+j;
+	  for (i = 0; i < N; ++i, it1+=N, it2+=N) std::swap(*it1, *it2);
+	}
+	it = A + (j*(N+1)); max = *it++;
+	for (i = j+1; i < N; ++i) *it++ /= max; 
+	auto it22 = A + (j*N + j+1), it11 = it22;
+	auto it3 = A + ((j+1)*N+j);
+	for (size_type l = j+1; l < N; ++l) {
+	  it11 += N;
+	  auto it1 = it11, it2 = it22;
+	  scalar_type a = *it3; it3 += N;
+	  for (size_type k = j+1; k < N; ++k) *it1++ -= *it2++ * a;
+	}
+
+      }
+      ipvt[N-1] = int(N);
+    }
+    return info;
+  }
+
+  static void lower_tri_solve(const scalar_type *T, scalar_type *x, int N,
+			      bool is_unit) {
+    scalar_type x_j;
+    for (int j = 0; j < N; ++j) {
+      auto itc = T + j*N, it = itc+(j+1), ite = itc+N;
+      auto itx = x + j;
+      if (!is_unit) *itx /= itc[j];
+      x_j = *itx++;
+      for (; it != ite ; ++it, ++itx) *itx -= x_j * (*it);
+    }
+  }
+
+  static void upper_tri_solve(const scalar_type *T, scalar_type *x, int N,
+			      bool is_unit) {
+    scalar_type x_j;
+    for (int j = N - 1; j >= 0; --j) {
+      auto itc = T + j*N, it = itc, ite = itc+j;
+      auto itx = x;
+      if (!is_unit) x[j] /= itc[j];
+      for (x_j = x[j]; it != ite ; ++it, ++itx) *itx -= x_j * (*it);
+    }
+  }
+
+  static void lu_solve(const scalar_type *LU, const std::vector<int> &ipvt, 
+		       scalar_type *x, scalar_type *b, int N) {
+    std::copy(b, b+N, x);
+    for(int i = 0; i < N; ++i)
+      { int perm = ipvt[i]-1; if(i != perm) std::swap(x[i], x[perm]); }
+    bgeot::lower_tri_solve(LU, x, N, true);
+    bgeot::upper_tri_solve(LU, x, N, false);
+  }
+
+  scalar_type lu_det(const scalar_type *LU, const std::vector<int> &ipvt,
+		     size_type N) {
+    scalar_type det(1);
+    for (size_type j = 0; j < N; ++j) det *= *(LU+j*(N+1));
+    for(int i = 0; i < int(N); ++i) if (i != ipvt[i]-1) { det = -det; }
+    return det;
+  }
+
+  scalar_type lu_det(const scalar_type *A, size_type N) {
+    switch (N) {
+    case 1: return *A;
+    case 2: return (*A) * (A[3]) - (A[1]) * (A[2]);
+    case 3: 
+      {
+	scalar_type a0 = A[4]*A[8] - A[5]*A[7], a3 = A[5]*A[6] - A[3]*A[8];
+	scalar_type a6 = A[3]*A[7] - A[4]*A[6];
+	return A[0] * a0 + A[1] * a3 + A[2] * a6;
+      }
+    default:
+      {
+	size_type NN = N*N;
+	if (__aux1().size() < NN) __aux1().resize(N*N);
+	std::copy(A, A+NN, __aux1().begin());
+	__ipvt_aux().resize(N);
+	lu_factor(&(*(__aux1().begin())), __ipvt_aux(), N);
+	return lu_det(&(*(__aux1().begin())), __ipvt_aux(), N);
+      }
+    }
+  }
+
+  void lu_inverse(const scalar_type *LU, const std::vector<int> &ipvt,
+		  scalar_type *A, size_type N) {
+    __aux2().resize(N); gmm::clear(__aux2());
+    __aux3().resize(N);
+    for(size_type i = 0; i < N; ++i) {
+      __aux2()[i] = scalar_type(1);
+      bgeot::lu_solve(LU, ipvt, A+i*N, &(*(__aux2().begin())), int(N));
+      __aux2()[i] = scalar_type(0);
+    }
+  }
+
+  scalar_type lu_inverse(scalar_type *A, size_type N, bool doassert) {
+    switch (N) {
+    case 1:
+      {
+	scalar_type det = *A;
+	GMM_ASSERT1(det != scalar_type(0), "Non invertible matrix");
+	*A = scalar_type(1)/det;
+	return det;
+      }
+    case 2:
+      {
+	scalar_type a = *A, b = A[2], c = A[1], d = A[3];
+	scalar_type det = a * d - b * c;
+	GMM_ASSERT1(det != scalar_type(0), "Non invertible matrix");
+	*A++ =  d/det;  *A++ /= -det; *A++ /= -det;  *A =  a/det;
+	return det;
+      }
+    case 3:
+      {
+	scalar_type a0 = A[4]*A[8] - A[5]*A[7], a1 = A[5]*A[6] - A[3]*A[8];
+	scalar_type a2 = A[3]*A[7] - A[4]*A[6];
+	scalar_type det =  A[0] * a0 + A[1] * a1 + A[2] * a2;
+	GMM_ASSERT1(det != scalar_type(0), "Non invertible matrix");
+	scalar_type a3 = (A[2]*A[7] - A[1]*A[8]), a6 = (A[1]*A[5] - A[2]*A[4]);
+	scalar_type a4 = (A[0]*A[8] - A[2]*A[6]), a7 = (A[2]*A[3] - A[0]*A[5]);
+	scalar_type a5 = (A[1]*A[6] - A[0]*A[7]), a8 = (A[0]*A[4] - A[1]*A[3]);
+	*A++ = a0 / det; *A++ = a3 / det; *A++ = a6 / det;
+	*A++ = a1 / det; *A++ = a4 / det; *A++ = a7 / det;
+	*A++ = a2 / det; *A++ = a5 / det; *A++ = a8 / det;
+	return det;
+      }
+    default:
+      {
+	size_type NN = N*N;
+	if (__aux1().size() < NN) __aux1().resize(NN);
+	std::copy(A, A+NN, __aux1().begin());
+	__ipvt_aux().resize(N);
+	size_type info = lu_factor(&(*(__aux1().begin())), __ipvt_aux(), N);
+	if (doassert) GMM_ASSERT1(!info, "Non invertible matrix, pivot = "
+				  << info);
+	if (!info) lu_inverse(&(*(__aux1().begin())), __ipvt_aux(), A, N);
+	return lu_det(&(*(__aux1().begin())), __ipvt_aux(), N);
+      }
+    }
+  }
+
+
+
   void geometric_trans::compute_K_matrix
-    (const base_matrix &G, const base_matrix &pc, base_matrix &K) const{
-    gmm::mult(G, pc, K);
+    (const base_matrix &G, const base_matrix &pc, base_matrix &K) const {
+    // gmm::mult(G, pc, K);
+    // Faster than the lapack call on my config ...
+    size_type N=gmm::mat_nrows(G), P=gmm::mat_nrows(pc), Q=gmm::mat_ncols(pc);
+    if (N && P && Q) {
+      auto itK = K.begin();
+      for (size_type j = 0; j < Q; ++j) {
+	auto itpc_j = pc.begin() + j*P, itG_b = G.begin();
+	for (size_type i = 0; i < N; ++i, ++itG_b) {
+	  auto itG = itG_b, itpc = itpc_j;
+	  register scalar_type a = *(itG) * (*itpc);
+	  for (size_type k = 1; k < P; ++k)
+	    { itG += N; a += *(itG) * (*++itpc); }
+	  *itK++ = a;
+	}
+      }
+    } else gmm::clear(K);
   }
 
   const base_node& geotrans_interpolation_context::xref() const {
     if (!have_xref()) {
       if (pspt_) xref_ = (*pspt_)[ii_];
-      else GMM_ASSERT1(false, "missing xref");
+      else GMM_ASSERT1(false, "Missing xref");
     }
     return xref_;
   }
@@ -51,56 +306,93 @@ namespace bgeot {
   }
 
   void geotrans_interpolation_context::compute_J(void) const {
-    GMM_ASSERT1(have_G() && have_pgt(), "unable to compute B\n");
+    GMM_ASSERT1(have_G() && have_pgt(), "Unable to compute J\n");
     size_type P = pgt_->structure()->dim();
-    base_matrix CS(P,P);
+    const base_matrix &KK = K();
     if (P != N()) {
-      gmm::mult(gmm::transposed(K()), K(), CS);
+      B_factors.base_resize(P, P);
+      gmm::mult(gmm::transposed(KK), KK, B_factors);
       // gmm::abs below because on flat convexes determinant could be -1e-27.
-      J_ = ::sqrt(gmm::abs(gmm::lu_det(CS)));
+      J__ = J_ =::sqrt(gmm::abs(bgeot::lu_inverse(&(*(B_factors.begin())), P)));
+    } else {
+      auto it = &(*(KK.begin()));
+      switch (P) {
+      case 1: J__ = *it; break;
+      case 2: J__ = (*it) * (it[3]) - (it[1]) * (it[2]); break;
+      case 3:
+	{
+	  B_.base_resize(P, P); // co-factors
+	  auto itB = B_.begin();
+	  scalar_type a0 = itB[0] = it[4]*it[8] - it[5]*it[7];
+	  scalar_type a1 = itB[1] = it[5]*it[6] - it[3]*it[8];
+	  scalar_type a2 = itB[2] = it[3]*it[7] - it[4]*it[6];
+	  J__ = it[0] * a0 + it[1] * a1 + it[2] * a2;
+	} break;
+      default:
+      	B_factors.base_resize(P, P); // store factorization for B computation
+      	gmm::copy(gmm::transposed(KK), B_factors);
+      	ipvt.resize(P);
+	bgeot::lu_factor(&(*(B_factors.begin())), ipvt, P);
+	J__ = bgeot::lu_det(&(*(B_factors.begin())), ipvt, P);
+	break;
+      }
+      J_ = gmm::abs(J__);
     }
-    else
-      J_ = gmm::abs(gmm::lu_det(K()));
+    have_J_ = true;
   }
 
   const base_matrix& geotrans_interpolation_context::K() const {
     if (!have_K()) {
-      GMM_ASSERT1(have_G() && have_pgt(), "unable to compute K\n");
+      GMM_ASSERT1(have_G() && have_pgt(), "Unable to compute K\n");
       size_type P = pgt_->structure()->dim();
-      K_.resize(N(), P);
+      K_.base_resize(N(), P);
       if (have_pgp()) {
-        GMM_ASSERT1(ii_ < pgp_->get_ppoint_tab()->size(),
-                    "Invalid index " << ii_ << " should be < "
-                    << pgp_->get_ppoint_tab()->size());
-
-        if (&pgp_->grad(ii_) == 0) { cerr << "OULA!! " << ii_ << "\n"; }
-        else if (pgp_->grad(ii_).size() == 0) { cerr << "OUCH\n"; }
-
-        pgt()->compute_K_matrix(G(), pgp_->grad(ii_), K_);
+	pgt_->compute_K_matrix(*G_, pgp_->grad(ii_), K_);
       } else {
-        base_matrix pc(pgt()->nb_points(), P);
-        pgt()->poly_vector_grad(xref(), pc);
-        pgt()->compute_K_matrix(G(), pc, K_);
+	PC.base_resize(pgt_->nb_points(), P);
+        pgt_->poly_vector_grad(xref(), PC);
+	pgt_->compute_K_matrix(*G_, PC, K_);
       }
+      have_K_ = true;
     }
     return K_;
   }
 
   const base_matrix& geotrans_interpolation_context::B() const {
     if (!have_B()) {
-      GMM_ASSERT1(have_G() && have_pgt(), "unable to compute B\n");
-      size_type P = pgt_->structure()->dim();
-      B_.resize(N(), P);
-      if (P != N()) {
-        base_matrix CS(P,P);
-        gmm::mult(gmm::transposed(K()), K(), CS);
-        // gmm::abs below because on flat convexes determinant could be -1e-27.
-        J_ = ::sqrt(gmm::abs(gmm::lu_inverse(CS)));
-        gmm::mult(K(), CS, B_);
+      const base_matrix &KK = K();
+      size_type P = pgt_->structure()->dim(), N_ = gmm::mat_nrows(KK);
+      B_.base_resize(N_, P);
+      if (!have_J_) compute_J();
+      GMM_ASSERT1(J__ != scalar_type(0), "Non invertible matrix");
+      if (P != N_) {
+        gmm::mult(KK, B_factors, B_);
       } else {
-        gmm::copy(gmm::transposed(K()), B_);
-        J_ = gmm::abs(gmm::lu_inverse(B_));
+	switch(P) {
+	case 1: B_(0, 0) = scalar_type(1) / J__;  break;
+	case 2:
+	  {
+	    auto it = &(*(KK.begin())); auto itB = &(*(B_.begin()));
+	    *itB++ = it[3] / J__; *itB++ = -it[2] / J__; 
+	    *itB++ = -it[1] / J__; *itB = (*it) / J__;
+	  } break;
+	case 3:
+	  {
+	    auto it = &(*(KK.begin())); auto itB = &(*(B_.begin()));
+	    *itB++ /= J__; *itB++ /= J__; *itB++ /= J__; 
+	    *itB++ = (it[2]*it[7] - it[1]*it[8]) / J__;
+	    *itB++ = (it[0]*it[8] - it[2]*it[6]) / J__;
+	    *itB++ = (it[1]*it[6] - it[0]*it[7]) / J__;
+	    *itB++ = (it[1]*it[5] - it[2]*it[4]) / J__;
+	    *itB++ = (it[2]*it[3] - it[0]*it[5]) / J__;
+	    *itB   = (it[0]*it[4] - it[1]*it[3]) / J__;
+	  } break;
+	default:
+	  bgeot::lu_inverse(&(*(B_factors.begin())), ipvt, &(*(B_.begin())), P);
+	  break;
+	}
       }
+      have_B_ = true;
     }
     return B_;
   }
@@ -109,12 +401,13 @@ namespace bgeot {
     if (!have_B3()) {
       const base_matrix &BB = B();
       size_type P=gmm::mat_ncols(BB), N_=gmm::mat_nrows(BB);
-      B3_.resize(N_*N_, P*P);
+      B3_.base_resize(N_*N_, P*P);
       for (short_type i = 0; i < P; ++i)
         for (short_type j = 0; j < P; ++j)
           for (short_type k = 0; k < N_; ++k)
             for (short_type l = 0; l < N_; ++l)
               B3_(k + N_*l, i + P*j) = BB(k, i) * BB(l, j);
+      have_B3_ = true;
     }
     return B3_;
   }
@@ -123,16 +416,16 @@ namespace bgeot {
     if (!have_B32()) {
       const base_matrix &BB = B();
       size_type P=gmm::mat_ncols(BB), N_=gmm::mat_nrows(BB);
-      B32_.resize(N_*N_, P);
+      B32_.base_resize(N_*N_, P);
       if (!pgt()->is_linear()) {
         base_matrix B2(P*P, P), Htau(N_, P*P);
         if (have_pgp()) {
           gmm::mult(G(), pgp_->hessian(ii_), Htau);
         } else {
           /* very inefficient of course... */
-          base_matrix pc(pgt()->nb_points(), P*P);
-          pgt()->poly_vector_hess(xref(), pc);
-          gmm::mult(G(), pc, Htau);
+	  PC.base_resize(pgt()->nb_points(), P*P);
+          pgt()->poly_vector_hess(xref(), PC);
+          gmm::mult(G(), PC, Htau);
         }
         for (short_type i = 0; i < P; ++i)
           for (short_type j = 0; j < P; ++j)
@@ -141,47 +434,17 @@ namespace bgeot {
                 B2(i + P*j, k) += Htau(l, i + P*j) * BB(l,k);
         gmm::mult(B3(), B2, B32_);
       } else gmm::clear(B32_);
+      have_B32_ = true;
     }
     return B32_;
   }
 
- void geotrans_interpolation_context::set_ii(size_type ii__) {
-    if (ii_ == ii__) return;
-    if (have_K() && !pgt()->is_linear()) { K_.resize(0,0); }
-    if (have_B() && !pgt()->is_linear()) { B_.resize(0,0); }
-    if (have_B3() && !pgt()->is_linear()) {
-      B3_.resize(0,0); B32_.resize(0,0); }
-    if (J_ >= scalar_type(0) && !pgt()->is_linear()) J_ = scalar_type(-1);
-    xref_.clear(); xreal_.clear();
-    ii_=ii__;
-  }
-
   void geotrans_interpolation_context::set_xref(const base_node& P) {
     xref_ = P;
-    if (have_K() && !pgt()->is_linear()) { K_.resize(0,0); }
-    if (have_B() && !pgt()->is_linear()) { B_.resize(0,0); }
-    if (have_B3() && !pgt()->is_linear()) {
-      B3_.resize(0,0); B32_.resize(0,0); }
-    if (J_ >= scalar_type(0) && !pgt()->is_linear()) J_ = scalar_type(-1);
-    xreal_.clear(); ii_ = size_type(-1); pspt_ = 0;
-  }
-
-  geotrans_interpolation_context::geotrans_interpolation_context() :
-    G_(0), pgt_(0), pgp_(0), pspt_(0), ii_(size_type(-1)), J_(-1) {}
-  geotrans_interpolation_context::geotrans_interpolation_context
-  (bgeot::pgeotrans_precomp pgp__, size_type ii__, const base_matrix& G__) :
-    G_(&G__), pgt_(pgp__->get_trans()), pgp_(pgp__),
-    pspt_(pgp__->get_ppoint_tab()), ii_(ii__), J_(-1) {}
-  geotrans_interpolation_context::geotrans_interpolation_context
-  (bgeot::pgeometric_trans pgt__, bgeot::pstored_point_tab pspt__,
-   size_type ii__,  const base_matrix& G__) :
-    G_(&G__), pgt_(pgt__), pgp_(0),
-    pspt_(pspt__), ii_(ii__), J_(-1) {}
-  geotrans_interpolation_context::geotrans_interpolation_context
-  (bgeot::pgeometric_trans pgt__, const base_node& xref__,
-   const base_matrix& G__) :
-    xref_(xref__), G_(&G__), pgt_(pgt__), pgp_(0), pspt_(0),
-    ii_(size_type(-1)), J_(-1) {}
+    if (pgt_ && !pgt()->is_linear())
+      { have_K_ = have_B_ = have_B3_ = have_B32_ = have_J_ = false; }
+    xreal_.resize(0); ii_ = size_type(-1); pspt_ = 0;
+  }
 
 
   base_node geometric_trans::transform(const base_node &pt,
@@ -198,17 +461,18 @@ namespace bgeot {
     return P;
   }
 
-  void geometric_trans::fill_standard_vertices(void) {
+  void geometric_trans::fill_standard_vertices() {
     vertices_.resize(0);
     for (size_type ip = 0; ip < nb_points(); ++ip) {
       bool vertex = true;
       for (size_type i = 0; i < cvr->points()[ip].size(); ++i)
         if (gmm::abs(cvr->points()[ip][i]) > 1e-10
-            && gmm::abs(cvr->points()[ip][i]-1.0) > 1e-10)
+            && gmm::abs(cvr->points()[ip][i]-1.0) > 1e-10
+	    && gmm::abs(cvr->points()[ip][i]+1.0) > 1e-10)
           { vertex = false; break; }
       if (vertex) vertices_.push_back(ip);
     }
-    assert(vertices_.size() >= dim());
+    assert(vertices_.size() > dim());
   }
 
   /* ******************************************************************** */
@@ -219,14 +483,43 @@ namespace bgeot {
   struct igeometric_trans : public geometric_trans {
 
     std::vector<FUNC> trans;
+    mutable std::vector<std::vector<FUNC>> grad_, hess_;
+
+    void compute_grad_() const {
+      size_type R = trans.size();
+      dim_type n = dim();
+      grad_.resize(R);
+      for (size_type i = 0; i < R; ++i) {
+	grad_[i].resize(n);
+	for (dim_type j = 0; j < n; ++j) {
+	  grad_[i][j] = trans[i]; grad_[i][j].derivative(j);
+	}
+      }
+    }
 
+    void compute_hess_() const {
+      size_type R = trans.size();
+      dim_type n = dim();
+      hess_.resize(R);
+      for (size_type i = 0; i < R; ++i) {
+	hess_[i].resize(n*n);
+	for (dim_type j = 0; j < n; ++j) {
+	  for (dim_type k = 0; k < n; ++k) {
+	    hess_[i][j+k*n] = trans[i];
+	    hess_[i][j+k*n].derivative(j); hess_[i][j+k*n].derivative(k);
+	  }
+	}
+      }
+    }
+    
     virtual void poly_vector_val(const base_node &pt, base_vector &val) const {
       val.resize(nb_points());
       for (size_type k = 0; k < nb_points(); ++k)
         val[k] = to_scalar(trans[k].eval(pt.begin()));
     }
 
-    virtual void poly_vector_val(const base_node &pt, const convex_ind_ct &ind_ct,
+    virtual void poly_vector_val(const base_node &pt,
+				 const convex_ind_ct &ind_ct,
                                  base_vector &val) const {
       size_type nb_funcs=ind_ct.size();
       val.resize(nb_funcs);
@@ -235,40 +528,35 @@ namespace bgeot {
     }
 
     virtual void poly_vector_grad(const base_node &pt, base_matrix &pc) const {
+      if (!(grad_.size())) compute_grad_();
       FUNC PP;
-      pc.resize(nb_points(),dim());
+      pc.base_resize(nb_points(),dim());
       for (size_type i = 0; i < nb_points(); ++i)
-        for (dim_type n = 0; n < dim(); ++n) {
-          PP = trans[i];
-          PP.derivative(n);
-          pc(i, n) = to_scalar(PP.eval(pt.begin()));
-        }
+        for (dim_type n = 0; n < dim(); ++n)
+          pc(i, n) = to_scalar(grad_[i][n].eval(pt.begin()));
     }
 
     virtual void poly_vector_grad(const base_node &pt,
 				  const convex_ind_ct &ind_ct,
                                   base_matrix &pc) const {
+      if (!(grad_.size())) compute_grad_();
       FUNC PP;
       size_type nb_funcs=ind_ct.size();
-      pc.resize(nb_funcs,dim());
+      pc.base_resize(nb_funcs,dim());
       for (size_type i = 0; i < nb_funcs; ++i)
-        for (dim_type n = 0; n < dim(); ++n) {
-          PP = trans[ind_ct[i]];
-          PP.derivative(n);
-          pc(i, n) = to_scalar(PP.eval(pt.begin()));
-        }
+        for (dim_type n = 0; n < dim(); ++n)
+          pc(i, n) = to_scalar(grad_[ind_ct[i]][n].eval(pt.begin()));
     }
 
     virtual void poly_vector_hess(const base_node &pt, base_matrix &pc) const {
+      if (!(hess_.size())) compute_hess_();
       FUNC PP, QP;
-      pc.resize(nb_points(),dim()*dim());
+      pc.base_resize(nb_points(),dim()*dim());
       for (size_type i = 0; i < nb_points(); ++i)
         for (dim_type n = 0; n < dim(); ++n) {
-          QP = trans[i]; QP.derivative(n);
-          for (dim_type m = 0; m <= n; ++m) {
-            PP = QP; PP.derivative(m);
-            pc(i, n*dim()+m) = pc(i, m*dim()+n) = to_scalar(PP.eval(pt.begin()));
-          }
+          for (dim_type m = 0; m <= n; ++m)
+            pc(i, n*dim()+m) = pc(i, m*dim()+n) =
+	      to_scalar(hess_[i][m*dim()+n].eval(pt.begin()));
         }
     }
 
@@ -276,6 +564,7 @@ namespace bgeot {
 
   typedef igeometric_trans<base_poly> poly_geometric_trans;
   typedef igeometric_trans<polynomial_composite> comppoly_geometric_trans;
+  typedef igeometric_trans<base_rational_fraction> fraction_geometric_trans;
 
   /* ******************************************************************** */
   /* transformation on simplex.                                           */
@@ -557,6 +846,78 @@ namespace bgeot {
     return geometric_trans_descriptor(name.str());
   }
 
+  /* ******************************************************************** */
+  /*	Pyramidal geometric transformation of order k=1 or 2.             */
+  /* ******************************************************************** */
+
+  struct pyramidal_trans_: public fraction_geometric_trans  {
+    pyramidal_trans_(short_type k) {
+      cvr = pyramidal_element_of_reference(k);
+      size_type R = cvr->structure()->nb_points();
+      is_lin = false;
+      complexity_ = k;
+      trans.resize(R);
+
+      if (k == 1) {
+	base_rational_fraction Q(read_base_poly(3, "x*y"),    // Q = xy/(1-z)
+				 read_base_poly(3, "1-z"));
+	trans[0] = (read_base_poly(3, "1-x-y-z") + Q)*0.25;
+	trans[1] = (read_base_poly(3, "1+x-y-z") - Q)*0.25;
+	trans[2] = (read_base_poly(3, "1-x+y-z") - Q)*0.25;
+	trans[3] = (read_base_poly(3, "1+x+y-z") + Q)*0.25;
+	trans[4] = read_base_poly(3, "z");
+      } else if (k == 2) {
+        base_poly xi0  = read_base_poly(3, "(1-z-x)*0.5");
+        base_poly xi1  = read_base_poly(3, "(1-z-y)*0.5");
+        base_poly xi2  = read_base_poly(3, "(1-z+x)*0.5");
+        base_poly xi3  = read_base_poly(3, "(1-z+y)*0.5");
+	base_poly x    = read_base_poly(3, "x");
+	base_poly y    = read_base_poly(3, "y");
+	base_poly z    = read_base_poly(3, "z");
+	base_poly ones = read_base_poly(3, "1");
+	base_poly un_z = read_base_poly(3, "1-z");
+	base_rational_fraction Q(read_base_poly(3, "1"), un_z); // Q = 1/(1-z)
+	trans[ 0] = Q*Q*xi0*xi1*(x*y-z*un_z);
+	trans[ 1] = Q*Q*xi0*xi1*xi2*(xi1*2.-un_z)*4.;
+	trans[ 2] = Q*Q*xi1*xi2*(-x*y-z*un_z);
+	trans[ 3] = Q*Q*xi3*xi0*xi1*(xi0*2.-un_z)*4.;
+	trans[ 4] = Q*Q*xi0*xi1*xi2*xi3*16.;
+	trans[ 5] = Q*Q*xi1*xi2*xi3*(xi2*2.-un_z)*4.;
+	trans[ 6] = Q*Q*xi3*xi0*(-x*y-z*un_z);
+	trans[ 7] = Q*Q*xi2*xi3*xi0*(xi3*2.-un_z)*4.;
+	trans[ 8] = Q*Q*xi2*xi3*(x*y-z*un_z);
+	trans[ 9] = Q*z*xi0*xi1*4.;
+	trans[10] = Q*z*xi1*xi2*4.;
+	trans[11] = Q*z*xi3*xi0*4.;
+	trans[12] = Q*z*xi2*xi3*4.;
+	trans[13] = read_base_poly(3, "z*(2*z-1)");
+      }
+      fill_standard_vertices();
+    }
+  };
+  
+  static pgeometric_trans
+    pyramidal_gt(gt_param_list& params,
+                     std::vector<dal::pstatic_stored_object> &dependencies) {
+    GMM_ASSERT1(params.size() == 1, "Bad number of parameters : "
+		<< params.size() << " should be 1.");
+    GMM_ASSERT1(params[0].type() == 0, "Bad type of parameters");
+    int k = int(::floor(params[0].num() + 0.01));
+    
+    dependencies.push_back(pyramidal_element_of_reference(dim_type(k)));
+    return std::make_shared<pyramidal_trans_>(dim_type(k));
+  }
+  
+  pgeometric_trans pyramidal_geotrans(short_type k) {
+    static short_type k_ = -1;
+    static pgeometric_trans pgt = 0;
+    if (k != k_) {
+      std::stringstream name;
+      name << "GT_PYRAMID(" << k << ")";
+      pgt = geometric_trans_descriptor(name.str());
+    }
+    return pgt;  
+  }
 
   /* ******************************************************************** */
   /*    Misc function.                                                    */
@@ -636,6 +997,7 @@ namespace bgeot {
       add_suffix("LINEAR_PRODUCT", linear_product_gt);
       add_suffix("LINEAR_QK", linear_qk);
       add_suffix("Q2_INCOMPLETE", Q2_incomplete_gt);
+      add_suffix("PYRAMID", pyramidal_gt);
     }
   };
 
diff --git a/src/bgeot_geotrans_inv.cc b/src/bgeot_geotrans_inv.cc
index 4166bff..67dacd5 100644
--- a/src/bgeot_geotrans_inv.cc
+++ b/src/bgeot_geotrans_inv.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -66,7 +66,7 @@ namespace bgeot
     if (P != N) {
       pgt->compute_K_matrix(G, pc, K);
       gmm::mult(gmm::transposed(K), K, CS);
-      gmm::lu_inverse(CS);
+      bgeot::lu_inverse(&(*(CS.begin())), P);
       gmm::mult(K, CS, B);
     }
     else {
@@ -75,8 +75,8 @@ namespace bgeot
       base_matrix KT(K.nrows(), K.ncols());
       pgt->compute_K_matrix(G, pc, KT);
       gmm::copy(gmm::transposed(KT), K);
-      gmm::copy(K,B);
-      gmm::lu_inverse(K); B.swap(K); 
+      gmm::copy(K, B);
+      bgeot::lu_inverse(&(*(K.begin())), P); B.swap(K); 
     }
   }
 
@@ -108,7 +108,6 @@ namespace bgeot
 
     //    for (size_type j = 0; j < pgt->nb_points(); ++j) 
     //       cout << "point " << j << " : " << cvpts[j] << endl;
-
     converged = true;
     base_node xn(P), y, z,x0;
     /* find an initial guess */
@@ -123,7 +122,6 @@ namespace bgeot
 
     base_node vres(P);
     base_node rn(xreal); rn -= y; 
-
     pgt->poly_vector_grad(x, pc);
     update_B();
     
diff --git a/src/bgeot_kdtree.cc b/src/bgeot_kdtree.cc
index a909cc5..55f9066 100644
--- a/src/bgeot_kdtree.cc
+++ b/src/bgeot_kdtree.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/bgeot_mesh_structure.cc b/src/bgeot_mesh_structure.cc
index d8fd930..c1feaa0 100644
--- a/src/bgeot_mesh_structure.cc
+++ b/src/bgeot_mesh_structure.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/bgeot_node_tab.cc b/src/bgeot_node_tab.cc
index ee280dd..580dce5 100644
--- a/src/bgeot_node_tab.cc
+++ b/src/bgeot_node_tab.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard
+ Copyright (C) 2007-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -112,8 +112,7 @@ namespace bgeot {
         id = dal::dynamic_tas<base_node>::add(pt);
         for (size_type i = 0; i < sorters.size(); ++i) {
           sorters[i].insert(id);
-          GMM_ASSERT3(sorters[i].size() == card(), "internal error, "
-		      << sorters[i].size() << " != " << card() << " pt = " << pt);
+          GMM_ASSERT3(sorters[i].size() == card(), "internal error");
         }
       }
     }
diff --git a/src/bgeot_poly.cc b/src/bgeot_poly.cc
index 20020b7..de5ba06 100644
--- a/src/bgeot_poly.cc
+++ b/src/bgeot_poly.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -244,8 +244,10 @@ namespace bgeot {
     return value_list[0];
   }
 
-  base_poly read_base_poly(short_type n, const std::string &s)
-  { std::stringstream f(s); return read_base_poly(n, f); }
+  base_poly read_base_poly(short_type n, const std::string &s) {
+    std::stringstream f(s);
+    return read_base_poly(n, f);
+  }
 
 
 }  /* end of namespace bgeot.                                             */
diff --git a/src/bgeot_poly_composite.cc b/src/bgeot_poly_composite.cc
index 0d01e04..f832031 100644
--- a/src/bgeot_poly_composite.cc
+++ b/src/bgeot_poly_composite.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -39,8 +39,8 @@ namespace bgeot {
     int ret = 0;
     for (; itx != itex; ++itx, ++ity) {
       long a = long(sfloor((*itx) * c1)), b = long(sfloor((*ity) * c1));
-      if ((gmm::abs(a) > scalar_type(base))
-          || (gmm::abs(b) > scalar_type(base))) { 
+      if ((scalar_type(gmm::abs(a)) > scalar_type(base))
+          || (scalar_type(gmm::abs(b)) > scalar_type(base))) { 
         exp_max++; c_max /= scalar_type(base);
         return (*this)(x,y);
       }
@@ -81,7 +81,7 @@ namespace bgeot {
       base_matrix pc(pgt->nb_points() , N);
       base_matrix B0(N, P);
 
-      vectors_to_base_matrix(G, m.points_of_convex(cv));
+      m.points_of_convex(cv, G);
 
       base_node x(N); gmm::clear(x);
       pgt->poly_vector_grad(x, pc);
diff --git a/src/bgeot_rtree.cc b/src/bgeot_rtree.cc
index 34cf768..8d45754 100644
--- a/src/bgeot_rtree.cc
+++ b/src/bgeot_rtree.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Julien Pommier
+ Copyright (C) 2000-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -334,7 +334,8 @@ namespace bgeot {
       rtree_leaf *rl = static_cast<rtree_leaf*>(p);
       cout << "Leaf [" << rl->lst.size() << " elts] = ";
       for (size_type i=0; i < rl->lst.size(); ++i)
-        cout << " " << rl->lst[i]->id; cout << "\n";
+        cout << " " << rl->lst[i]->id;
+      cout << "\n";
       count += rl->lst.size();
     } else {
       cout << "Node\n";
diff --git a/src/bgeot_small_vector.cc b/src/bgeot_small_vector.cc
index 72069d1..7f56973 100644
--- a/src/bgeot_small_vector.cc
+++ b/src/bgeot_small_vector.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/bgeot_sparse_tensors.cc b/src/bgeot_sparse_tensors.cc
index 5768120..0ac040b 100644
--- a/src/bgeot_sparse_tensors.cc
+++ b/src/bgeot_sparse_tensors.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Julien Pommier
+ Copyright (C) 2000-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -628,9 +628,9 @@ namespace bgeot {
       cout << "  pri[" << int(i) << "]: n=" << int(pri[i].n) 
            << ", range=" << pri[i].range << ", mean_increm=" 
            << pri[i].mean_increm << ", regular = " << pri[i].have_regular_strides 
-           << ", inc=" << pri[i].inc << "\n";
-    cout << "bloc_rank: " << bloc_rank << ", bloc_nelt: " << bloc_nelt << "\n";    
-    cout << "vectorized_size : " << vectorized_size_ << ", strides = " << vectorized_strides_ << ", pr_dim=" << vectorized_pr_dim << "\n";
+           << ", inc=" << vref(pri[i].inc) << "\n";
+    cout << "bloc_rank: " << vref(bloc_rank) << ", bloc_nelt: " << vref(bloc_nelt) << "\n";    
+    cout << "vectorized_size : " << vectorized_size_ << ", strides = " << vref(vectorized_strides_) << ", pr_dim=" << vectorized_pr_dim << "\n";
   }
 
   void tensor_reduction::insert(const tensor_ref& tr_, const std::string& s) {
diff --git a/src/dal_backtrace.cc b/src/dal_backtrace.cc
index 318357a..bb98c2e 100644
--- a/src/dal_backtrace.cc
+++ b/src/dal_backtrace.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1995-2016 Yves Renard
+ Copyright (C) 1995-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/dal_bit_vector.cc b/src/dal_bit_vector.cc
index ec5e525..a7c4703 100644
--- a/src/dal_bit_vector.cc
+++ b/src/dal_bit_vector.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1995-2016 Yves Renard
+ Copyright (C) 1995-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -52,7 +52,8 @@ namespace dal {
   void bit_vector::fill_false(size_type i1, size_type i2) {
     size_type f = i1 / WD_BIT, r = i1 & (WD_BIT-1), l = i2 / WD_BIT;
     (*((bit_container *)(this)))[l];
-    if (r != 0) f++; l++;
+    if (r != 0) f++;
+    l++;
     if (f < l) std::fill(dal::bit_container::begin()+f,
 			 dal::bit_container::begin()+l, 0);
     ilast_false = i2;
diff --git a/src/dal_singleton.cc b/src/dal_singleton.cc
index 720b1f0..4d9cc96 100644
--- a/src/dal_singleton.cc
+++ b/src/dal_singleton.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/dal_static_stored_objects.cc b/src/dal_static_stored_objects.cc
index c405d27..67445b0 100644
--- a/src/dal_static_stored_objects.cc
+++ b/src/dal_static_stored_objects.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -234,7 +234,7 @@ static bool dal_static_stored_tab_valid__ = true;
   }
 
   void add_dependency(pstatic_stored_object o1,
-    pstatic_stored_object o2) {
+                      pstatic_stored_object o2) {
     bool dep_added = false;
     for(size_t thread=0; thread < num_threads(); ++thread)
     {
@@ -252,7 +252,7 @@ static bool dal_static_stored_tab_valid__ = true;
     {
       stored_object_tab& stored_objects
           = dal::singleton<stored_object_tab>::instance(thread);
-      if ((dependent_added =stored_objects.add_dependent_(o1,o2))) break;
+      if ((dependent_added = stored_objects.add_dependent_(o1,o2))) break;
     }
     GMM_ASSERT1(dependent_added, "Failed to add dependent between " << o1
 		<< " of type " << typeid(*o1).name() << " and " << o2
@@ -298,7 +298,7 @@ static bool dal_static_stored_tab_valid__ = true;
 
 
   void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o,
-			 permanence perm) {
+                         permanence perm) {
     GMM_ASSERT1(dal_static_stored_tab_valid__, "Too late to add an object");
     stored_object_tab& stored_objects
       = dal::singleton<stored_object_tab>::instance();
@@ -347,25 +347,19 @@ static bool dal_static_stored_tab_valid__ = true;
     if (dal_static_stored_tab_valid__) {
 
       std::list<pstatic_stored_object>::iterator it, itnext;
-
-      for (it = to_delete.begin(); it != to_delete.end(); it = itnext) 
-      {
+      for (it = to_delete.begin(); it != to_delete.end(); it = itnext) {
         itnext = it; itnext++;
 
         auto itos = iterators_of_object(*it);
-        if (itos.first == itos.second)
-        {
+        if (itos.first == itos.second) {
           if (ignore_unstored)
             to_delete.erase(it);
           else
-            if (me_is_multithreaded_now())
-            {
+            if (me_is_multithreaded_now()) {
               GMM_WARNING1("This object is (already?) not stored : "<< it->get()
               << " typename: " << typeid(*it->get()).name() 
               << "(which could happen in multithreaded code and is OK)");
-            }
-            else
-            {
+            } else {
               GMM_ASSERT1(false, "This object is not stored : " << it->get()
               << " typename: " << typeid(*it->get()).name());
             }
@@ -374,38 +368,29 @@ static bool dal_static_stored_tab_valid__ = true;
           itos.first->second.valid = false;
       }
 
-      std::set<pstatic_stored_object>::iterator itd;
-      for (it = to_delete.begin(); it != to_delete.end(); ++it) 
-      {
-        if (*it)
-        {
-          auto itos = iterators_of_object(*it);
+      for (pstatic_stored_object pobj : to_delete) {
+        if (pobj) {
+          auto itos = iterators_of_object(pobj);
           GMM_ASSERT1(itos.first != itos.second, "An object disapeared !");
           itos.first->second.valid = false;
-          std::set<pstatic_stored_object> dep = itos.first->second.dependencies;
-          for (itd = dep.begin(); itd != dep.end(); ++itd)
-          {
-            if (del_dependency(*it, *itd))
-            {
-              auto itods = iterators_of_object(*itd);
+          auto second_dep = itos.first->second.dependencies;
+          for (const pstatic_stored_object pdep : second_dep) {
+            if (del_dependency(pobj, pdep)) {
+              auto itods = iterators_of_object(pdep);
               if (itods.first->second.perm == AUTODELETE_STATIC_OBJECT
-                && itods.first->second.valid)
-              {
-                  itods.first->second.valid = false;
-                  to_delete.push_back(*itd);
+                  && itods.first->second.valid) {
+                itods.first->second.valid = false;
+                to_delete.push_back(pdep);
               }
             }
           }
-          for (itd = itos.first->second.dependent_object.begin();
-                          itd != itos.first->second.dependent_object.end(); ++itd)
-          {
-            auto itods = iterators_of_object(*itd);
-            if (itods.first != itods.second)
-            {
+          for (pstatic_stored_object
+               pdep : itos.first->second.dependent_object) {
+            auto itods = iterators_of_object(pdep);
+            if (itods.first != itods.second) {
               GMM_ASSERT1(itods.first->second.perm != PERMANENT_STATIC_OBJECT,
-              "Trying to delete a permanent object " << *itd);
-              if (itods.first->second.valid)
-              {
+              "Trying to delete a permanent object " << pdep);
+              if (itods.first->second.valid) {
                 itods.first->second.valid = false;
                 to_delete.push_back(itods.first->second.p);
               }
@@ -495,7 +480,7 @@ static bool dal_static_stored_tab_valid__ = true;
   }
 
   bool stored_object_tab::add_dependency_(pstatic_stored_object o1,
-    pstatic_stored_object o2)
+                                          pstatic_stored_object o2)
   {
     getfem::local_guard guard = locks_.get_lock();
     stored_key_tab::const_iterator it = stored_keys_.find(o1);
diff --git a/src/getfem/bgeot_comma_init.h b/src/getfem/bgeot_comma_init.h
index 54aa0f7..40800b0 100644
--- a/src/getfem/bgeot_comma_init.h
+++ b/src/getfem/bgeot_comma_init.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Julien Pommier
+ Copyright (C) 2003-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/bgeot_config.h b/src/getfem/bgeot_config.h
index 57836ac..66a367b 100644
--- a/src/getfem/bgeot_config.h
+++ b/src/getfem/bgeot_config.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -72,7 +72,7 @@ namespace bgeot {
 
   using std::endl; using std::cout; using std::cerr;
   using std::ends; using std::cin;
-  
+  using gmm::vref;
 
   static const size_t ST_NIL = size_t(-1);
   typedef gmm::uint16_type dim_type;
diff --git a/src/getfem/bgeot_convex.h b/src/getfem/bgeot_convex.h
index 127f4b0..6021f38 100644
--- a/src/getfem/bgeot_convex.h
+++ b/src/getfem/bgeot_convex.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -187,7 +187,8 @@ namespace bgeot {
     virtual bool compare(const static_stored_object_key &oo) const {
       const special_convex_structure_key_ &o
         = dynamic_cast<const special_convex_structure_key_ &>(oo);
-      if (p < o.p) return true;  return false;
+      if (p < o.p) return true;
+      return false;
     }
     special_convex_structure_key_(pconvex_structure pp) : p(pp) {}
   };
diff --git a/src/getfem/bgeot_convex_ref.h b/src/getfem/bgeot_convex_ref.h
index 9fc0e1d..8834afe 100644
--- a/src/getfem/bgeot_convex_ref.h
+++ b/src/getfem/bgeot_convex_ref.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2001-2016 Yves Renard
+ Copyright (C) 2001-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -139,7 +139,7 @@ namespace bgeot {
   /** returns a simplex of reference of dimension nc and degree k */
   pconvex_ref simplex_of_reference(dim_type nc, short_type k = 1);
   /** parallelepiped of reference of dimension nc (and degree 1) */
-  pconvex_ref parallelepiped_of_reference(dim_type nc);
+  pconvex_ref parallelepiped_of_reference(dim_type nc, dim_type k = 1);
   /** prism of reference of dimension nc (and degree 1) */
   pconvex_ref prism_of_reference(dim_type nc);
   /** incomplete Q2 quadrilateral/hexahedral of reference of dimension
@@ -149,6 +149,8 @@ namespace bgeot {
   /** tensorial product of two convex ref.
       in order to ensure unicity, it is required the a->dim() >= b->dim()
   */
+  /** Pyramidal element of reference of degree k (k = 1 or 2 only) */
+  pconvex_ref pyramidal_element_of_reference(dim_type k);
   pconvex_ref convex_ref_product(pconvex_ref a, pconvex_ref b);
   /** equilateral simplex (degree 1). used only for mesh quality estimations
    */
diff --git a/src/getfem/bgeot_convex_structure.h b/src/getfem/bgeot_convex_structure.h
index 86778e0..0dcb509 100644
--- a/src/getfem/bgeot_convex_structure.h
+++ b/src/getfem/bgeot_convex_structure.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -174,7 +174,7 @@ namespace bgeot {
   /// Give a pointer on the structures of a simplex of dimension d.
   pconvex_structure simplex_structure(dim_type d);
   /// Give a pointer on the structures of a parallelepiped of dimension d.
-  pconvex_structure parallelepiped_structure(dim_type d);
+  pconvex_structure parallelepiped_structure(dim_type d, dim_type k = 1);
   /// Give a pointer on the structures of a polygon with n vertex.
   pconvex_structure polygon_structure(short_type);
   /** Give a pointer on the structures of a incomplete Q2
@@ -193,6 +193,9 @@ namespace bgeot {
     return convex_product_structure(simplex_structure(dim_type(nc-1)),
                                     simplex_structure(1));
   }
+  /// Give a pointer on the 3D pyramid structure for a degree k = 1 or 2.
+  pconvex_structure pyramidal_structure(short_type k);
+  
 
   /** Simplex structure with the Lagrange grid of degree k.
       @param n the simplex dimension.
diff --git a/src/getfem/bgeot_ftool.h b/src/getfem/bgeot_ftool.h
index 273712d..8b752c2 100644
--- a/src/getfem/bgeot_ftool.h
+++ b/src/getfem/bgeot_ftool.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/bgeot_geometric_trans.h b/src/getfem/bgeot_geometric_trans.h
index b954bba..06ce13f 100644
--- a/src/getfem/bgeot_geometric_trans.h
+++ b/src/getfem/bgeot_geometric_trans.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -111,7 +111,7 @@ namespace bgeot {
     size_type complexity_; /* either the degree or the refinement of the
                             *  transformation */
 
-    void fill_standard_vertices(void);
+    void fill_standard_vertices();
   public :
 
     /// Dimension of the reference element.
@@ -221,6 +221,7 @@ namespace bgeot {
   pgeometric_trans APIDECL linear_product_geotrans(pgeometric_trans pg1,
                                            pgeometric_trans pg2);
   pgeometric_trans APIDECL Q2_incomplete_geotrans(dim_type nc);
+  pgeometric_trans APIDECL pyramidal_geotrans(short_type k);
 
   /**
      Get the geometric transformation from its string name.
@@ -394,24 +395,29 @@ namespace bgeot {
      are heavily described in the GetFEM++ Kernel Documentation.
   */
   class APIDECL geotrans_interpolation_context {
-    mutable base_node xref_; /** reference point */
+  protected:
+    mutable base_node xref_;  /** reference point */
     mutable base_node xreal_; /** transformed point */
-    const base_matrix *G_; /** pointer to the matrix of real nodes of the convex */
-    mutable base_matrix K_,B_, B3_, B32_; /** see documentation (getfem kernel doc) for more details */
+    const base_matrix *G_;    /** pointer to the matrix of real nodes of the convex */
+    mutable base_matrix K_, B_, B3_, B32_; /** see documentation (getfem kernel doc) for more details */
     pgeometric_trans pgt_;
     pgeotrans_precomp pgp_;
     pstored_point_tab pspt_; /** if pgp != 0, it is the same as pgp's one */
-    size_type ii_; /** index of current point in the pgp */
-    mutable scalar_type J_; /** Jacobian */
+    size_type ii_;           /** index of current point in the pgp */
+    mutable scalar_type J_, J__; /** Jacobian */
+    mutable base_matrix PC, B_factors;
+    mutable base_vector aux1, aux2;
+    mutable std::vector<int> ipvt;
+    mutable bool have_J_, have_B_, have_B3_, have_B32_, have_K_;
     void compute_J(void) const;
   public:
     bool have_xref() const { return !xref_.empty(); }
     bool have_xreal() const { return !xreal_.empty(); }
     bool have_G() const { return G_ != 0; }
-    bool have_K() const { return !K_.empty(); }
-    bool have_B() const { return !B_.empty(); }
-    bool have_B3() const { return !B3_.empty(); }
-    bool have_B32() const { return !B32_.empty(); }
+    bool have_K() const { return have_K_; }
+    bool have_B() const { return have_B_; }
+    bool have_B3() const { return have_B3_; }
+    bool have_B32() const { return have_B32_; }
     bool have_pgt() const { return pgt_ != 0; }
     bool have_pgp() const { return pgp_ != 0; }
     /// coordinates of the current point, in the reference convex.
@@ -427,27 +433,71 @@ namespace bgeot {
     /** matrix whose columns are the vertices of the convex */
     const base_matrix& G() const { return *G_; }
     /** get the Jacobian of the geometric trans (taken at point @c xref() ) */
-    scalar_type J() const { if (J_ < scalar_type(0)) compute_J(); return J_; }
+    scalar_type J() const { if (!have_J_) compute_J(); return J_; }
     size_type N() const { if (have_G()) return G().nrows();
       else if (have_xreal()) return xreal_.size();
       else GMM_ASSERT2(false, "cannot get N"); return 0; }
     size_type ii() const { return ii_; }
     bgeot::pgeotrans_precomp pgp() const { return pgp_; }
     /** change the current point (assuming a geotrans_precomp_ is used) */
-    void set_ii(size_type ii__);
+    void set_ii(size_type ii__) {
+      if (ii_ != ii__) {
+	if (pgt_ && !pgt()->is_linear())
+	  { have_K_ = have_B_ = have_B3_ = have_B32_ = have_J_ = false; }
+	xref_.resize(0); xreal_.resize(0);
+	ii_=ii__;
+      }
+    }
     /** change the current point (coordinates given in the reference convex) */
     void set_xref(const base_node& P);
-    geotrans_interpolation_context();
+    void change(bgeot::pgeotrans_precomp pgp__,
+		size_type ii__,
+		const base_matrix& G__) {
+      G_ = &G__; pgt_ = pgp__->get_trans(); pgp_ = pgp__;
+      pspt_ = pgp__->get_ppoint_tab(); ii_ = ii__;
+      have_J_ = have_B_ = have_B3_ = have_B32_ = have_K_ = false;
+      xref_.resize(0); xreal_.resize(0);
+    }
+    void change(bgeot::pgeometric_trans pgt__,
+		bgeot::pstored_point_tab pspt__,
+		size_type ii__,
+		const base_matrix& G__) {
+      G_ = &G__; pgt_ = pgt__; pgp_ = 0; pspt_ = pspt__; ii_ = ii__;
+      have_J_ = have_B_ = have_B3_ = have_B32_ = have_K_ = false;
+      xref_.resize(0); xreal_.resize(0);
+    }
+    void change(bgeot::pgeometric_trans pgt__,
+		const base_node& xref__,
+		const base_matrix& G__) {
+      xref_ = xref__; G_ = &G__; pgt_ = pgt__; pgp_ = 0; pspt_ = 0;
+      ii_ = size_type(-1);
+      have_J_ = have_B_ = have_B3_ = have_B32_ = have_K_ = false;
+      xreal_.resize(0);
+    }
+    
+    geotrans_interpolation_context()
+      : G_(0), pgt_(0), pgp_(0), pspt_(0), ii_(size_type(-1)),
+      have_J_(false), have_B_(false), have_B3_(false), have_B32_(false),
+      have_K_(false) {}
     geotrans_interpolation_context(bgeot::pgeotrans_precomp pgp__,
                                    size_type ii__,
-                                   const base_matrix& G__);
+                                   const base_matrix& G__)
+      : G_(&G__), pgt_(pgp__->get_trans()), pgp_(pgp__),
+      pspt_(pgp__->get_ppoint_tab()), ii_(ii__), have_J_(false), have_B_(false),
+      have_B3_(false), have_B32_(false), have_K_(false) {}
     geotrans_interpolation_context(bgeot::pgeometric_trans pgt__,
                                    bgeot::pstored_point_tab pspt__,
                                    size_type ii__,
-                                   const base_matrix& G__);
+                                   const base_matrix& G__)
+      : G_(&G__), pgt_(pgt__), pgp_(0),
+      pspt_(pspt__), ii_(ii__), have_J_(false), have_B_(false), have_B3_(false),
+      have_B32_(false), have_K_(false) {}
     geotrans_interpolation_context(bgeot::pgeometric_trans pgt__,
                                    const base_node& xref__,
-                                   const base_matrix& G__);
+                                   const base_matrix& G__)
+      : xref_(xref__), G_(&G__), pgt_(pgt__), pgp_(0), pspt_(0),
+      ii_(size_type(-1)),have_J_(false), have_B_(false), have_B3_(false),
+      have_B32_(false), have_K_(false)  {}
   };
 
   /* Function allowing the add of an geometric transformation method outwards
@@ -459,6 +509,23 @@ namespace bgeot {
   (std::string name, dal::naming_system<geometric_trans>::pfunction f);
 
 
+  /* Optimized operation for small matrices                               */
+  scalar_type lu_det(const scalar_type *A, size_type N);
+  scalar_type lu_inverse(scalar_type *A, size_type N, bool doassert = true);
+  inline scalar_type lu_det(const base_matrix &A)
+  { return lu_det(&(*(A.begin())), A.nrows()); }
+  inline scalar_type lu_inverse(base_matrix &A, bool doassert = true)
+  { return lu_inverse(&(*(A.begin())), A.nrows(), doassert); }
+  // Optimized matrix mult for small matrices.
+  // Multiply the matrix A of size MxN by B of size NxP in C of size MxP
+  void mat_mult(const scalar_type *A, const scalar_type *B, scalar_type *C,
+		size_type M, size_type N, size_type P);
+  // Optimized matrix mult for small matrices.
+  // Multiply the matrix A of size MxN by the transpose of B of size PxN
+  // in C of size MxP
+  void mat_tmult(const scalar_type *A, const scalar_type *B, scalar_type *C,
+		 size_type M, size_type N, size_type P);
+
 }  /* end of namespace bgeot.                                             */
 
 
diff --git a/src/getfem/bgeot_geotrans_inv.h b/src/getfem/bgeot_geotrans_inv.h
index 5bb4b5b..9195942 100644
--- a/src/getfem/bgeot_geotrans_inv.h
+++ b/src/getfem/bgeot_geotrans_inv.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/bgeot_kdtree.h b/src/getfem/bgeot_kdtree.h
index bd78dbf..9d45555 100644
--- a/src/getfem/bgeot_kdtree.h
+++ b/src/getfem/bgeot_kdtree.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/bgeot_mesh.h b/src/getfem/bgeot_mesh.h
index 8c596e5..bdc4720 100644
--- a/src/getfem/bgeot_mesh.h
+++ b/src/getfem/bgeot_mesh.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard
+ Copyright (C) 2006-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -46,7 +46,7 @@ namespace bgeot {
 
   /** @internal mesh structure + points
    */
-  class basic_mesh :  public bgeot::mesh_structure {
+  class basic_mesh : public bgeot::mesh_structure {
 
   public :
     
@@ -73,27 +73,52 @@ namespace bgeot {
  
   public :
 
-    dim_type dim(void) const { return pts.dim(); }
+    dim_type dim() const { return pts.dim(); }
 
+    /** Return the bgeot::geometric_trans attached to a convex.
+        @param ic the convex number.
+    */
     bgeot::pgeometric_trans trans_of_convex(size_type ic) const {
-      GMM_ASSERT2(trans_exists[ic], "internal error");
-      return gtab[ic]; 
+      GMM_ASSERT1(trans_exists[ic],
+                  "No geometric transformation or nonexisting element");
+      return gtab[ic];
     }
 
-    const PT_TAB &points(void) const { return pts; }
+    const PT_TAB &points() const { return pts; }
 
+    /// Return a (pseudo)container of the points of a given convex
     ref_mesh_pt_ct points_of_convex(size_type ic) const {
       const ind_cv_ct &rct = ind_points_of_convex(ic);
       return ref_mesh_pt_ct(pts.begin(), rct.begin(), rct.end());
-    } 
+    }
+
+    inline void points_of_convex(size_type ic, base_matrix &G) const {
+      const ind_cv_ct &rct = ind_points_of_convex(ic);
+      size_type N = dim(), Np = rct.size();
+      G.base_resize(N, Np);
+      auto it = G.begin();
+      for (size_type i = 0; i < Np; ++i, it += N) {
+        const base_node &P = pts[rct[i]];
+        std::copy(P.begin(),  P.end(), it);
+      }
+    }
+
+    /** Add the point pt to the mesh and return the index of the
+        point.
 
+        If the point is too close to an existing point and remove_duplicated_nodes = true,
+        the function does not create a new point, and returns the index of the
+        already existing point.
+        @param pt the point coordinates.
+    */
     size_type add_point(const base_node &pt,
-                        const scalar_type tol=scalar_type(0)) {
-      return pts.add_node(pt, tol);
+                        const scalar_type tol=scalar_type(0),
+                        bool remove_duplicated_nodes = true) {
+      return pts.add_node(pt, tol, remove_duplicated_nodes);
     }
 
     template<class ITER>
-    size_type add_convex(bgeot::pgeometric_trans pgt, ITER ipts) { 
+    size_type add_convex(bgeot::pgeometric_trans pgt, ITER ipts) {
       bool present;
       size_type i = mesh_structure::add_convex(pgt->structure(), ipts,
                                                &present);
diff --git a/src/getfem/bgeot_mesh_structure.h b/src/getfem/bgeot_mesh_structure.h
index c1d1d6e..50e46ed 100644
--- a/src/getfem/bgeot_mesh_structure.h
+++ b/src/getfem/bgeot_mesh_structure.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -94,6 +94,9 @@ namespace bgeot {
     dal::bit_vector convex_index(dim_type) const;
     /// The total number of convexes in the mesh
     size_type nb_convex(void) const { return convex_tab.card(); }
+    /// The number of convex indexes from 0 to the index of the last convex
+    size_type nb_allocated_convex() const
+      { return convex_tab.index().last_true()+1; }
     /// Return true if i is in convex_index()
     bool is_convex_valid(size_type i) { return (convex_tab.index())[i]; }
     size_type nb_max_points(void) const { return points_tab.size(); }
@@ -250,7 +253,7 @@ namespace bgeot {
 
   /** Return the cuthill_mc_kee ordering on the convexes */
   void APIDECL cuthill_mckee_on_convexes(const bgeot::mesh_structure &ms,
-                                 std::vector<size_type> &cmk);
+					 std::vector<size_type> &cmk);
 
   template<class ITER>
     bool mesh_structure::is_convex_having_points(size_type ic,
@@ -317,11 +320,12 @@ namespace bgeot {
   struct APIDECL edge_list_elt  {
     size_type i, j;
     size_type cv;
-    inline bool operator < (const edge_list_elt &e) const
-    {
-      if (i < e.i) return true; if (i > e.i) return false;
+    inline bool operator < (const edge_list_elt &e) const {
+      if (i < e.i) return true;
+      if (i > e.i) return false;
       if (j < e.j) return true; else if (j > e.j) return false;
-      if (cv < e.cv) return true; return false;
+      if (cv < e.cv) return true;
+      return false;
     }
     edge_list_elt(size_type ii, size_type jj, size_type ic = 0) : cv(ic)
     { i = std::min(ii, jj); j = std::max(ii, jj); }
diff --git a/src/getfem/bgeot_node_tab.h b/src/getfem/bgeot_node_tab.h
index d08138d..66a924c 100644
--- a/src/getfem/bgeot_node_tab.h
+++ b/src/getfem/bgeot_node_tab.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard
+ Copyright (C) 2007-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/bgeot_permutations.h b/src/getfem/bgeot_permutations.h
index a63733c..86a8185 100644
--- a/src/getfem/bgeot_permutations.h
+++ b/src/getfem/bgeot_permutations.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/bgeot_poly.h b/src/getfem/bgeot_poly.h
index cf85edc..67e0502 100644
--- a/src/getfem/bgeot_poly.h
+++ b/src/getfem/bgeot_poly.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -175,8 +175,6 @@ namespace bgeot
    *        variables of P plus the number of variables of Q.
    *        The resulting polynomials have a smaller degree.
    *
-   *  @todo <h3>Horner scheme to evaluate polynomials.</h3>
-   *
    */
   template<typename T> class polynomial : public std::vector<T> {
   protected :
@@ -240,8 +238,10 @@ namespace bgeot
     /// Derivative of P with respect to the variable k. P contains the result.
     void derivative(short_type k);
     /// Makes P = 1.
-    void one(void) { change_degree(0); (*this)[0] = T(1); }
-    void clear(void) { change_degree(0); (*this)[0] = T(0); }
+    void one() { change_degree(0); (*this)[0] = T(1); }
+    void clear() { change_degree(0); (*this)[0] = T(0); }
+    bool is_zero()
+    { return(this->real_degree()==0) && (this->size()==0 || (*this)[0]==T(0)); }
     template <typename ITER> T horner(power_index &mi, short_type k,
 				   short_type de, const ITER &it) const;
     /** Evaluate the polynomial. "it" is an iterator pointing to the list
@@ -562,7 +562,8 @@ namespace bgeot
 	if (gmm::abs(*it)!=T(1)) { o << gmm::abs(*it); first_var = false; }
 	for (short_type j = 0; j < P.dim(); ++j)
 	  if (mi[j] != 0) {
-	    if (!first_var) o << "*"; first_var = false;
+	    if (!first_var) o << "*";
+	    first_var = false;
             if (P.dim() <= 7) o << "xyzwvut"[j];
             else o << "x_" << j; 
 	    if (mi[j] > 1) o << "^" << mi[j];
@@ -606,8 +607,8 @@ namespace bgeot
   }
   
   template<typename U, typename T>
-  polynomial<T> operator *(U c, const polynomial<T> &p)
-  { polynomial<T> q = p; q *= T(c); return q; }
+  polynomial<T> operator *(T c, const polynomial<T> &p)
+  { polynomial<T> q = p; q *= c; return q; }
 
   typedef polynomial<opt_long_scalar_type> base_poly;
 
@@ -625,6 +626,145 @@ namespace bgeot
   /** read a base_poly on the string s. */
   base_poly read_base_poly(short_type n, const std::string &s);
 
+
+  /**********************************************************************/
+  /* A class for rational fractions                                     */
+  /**********************************************************************/
+
+  template<typename T> class rational_fraction : public std::vector<T> {
+  protected :
+    
+    polynomial<T> numerator_, denominator_;
+    
+  public :
+
+    const polynomial<T> &numerator() const { return numerator_; }
+    const polynomial<T> &denominator() const { return denominator_; }
+
+    short_type dim(void) const { return numerator_.dim(); }
+    
+    /// Add Q to P. P contains the result.
+    rational_fraction &operator +=(const rational_fraction &Q) {
+      numerator_ = numerator_*Q.denominator() + Q.numerator()*denominator_;
+      denominator_ *= Q.denominator();
+      return *this;
+    }
+    /// Subtract Q from P. P contains the result.
+    rational_fraction &operator -=(const rational_fraction &Q) {
+      numerator_ = numerator_*Q.denominator() - Q.numerator()*denominator_;
+      denominator_ *= Q.denominator();
+      return *this;
+    }
+    /// Add Q to P.
+    rational_fraction operator +(const rational_fraction &Q) const
+    { rational_fraction R = *this; R += Q; return R; }
+    /// Subtract Q from P.
+    rational_fraction operator -(const rational_fraction &Q) const
+    { rational_fraction R = *this; R -= Q; return R; }
+    /// Add Q to P.
+    rational_fraction operator +(const polynomial<T> &Q) const
+    { rational_fraction R(numerator_+Q*denominator_, denominator_); return R; }
+    /// Subtract Q from P.
+    rational_fraction operator -(const polynomial<T> &Q) const
+    { rational_fraction R(numerator_-Q*denominator_, denominator_); return R; }
+    rational_fraction operator -(void) const
+    { rational_fraction R(-numerator_, denominator_); return R; }
+    /// Multiply P with Q. P contains the result.
+    rational_fraction &operator *=(const rational_fraction &Q)
+    { numerator_*=Q.numerator(); denominator_*=Q.denominator(); return *this; }
+    /// Divide P by Q. P contains the result.
+    rational_fraction &operator /=(const rational_fraction &Q)
+    { numerator_*=Q.denominator(); denominator_*=Q.numerator(); return *this; }
+    /// Multiply P with Q. 
+    rational_fraction operator *(const rational_fraction &Q) const
+    { rational_fraction R = *this; R *= Q; return R; }
+    /// Divide P by Q. 
+    rational_fraction operator /(const rational_fraction &Q) const
+    { rational_fraction R = *this; R /= Q; return R; }
+    /// Multiply P with the scalar a. P contains the result.
+    rational_fraction &operator *=(const T &e)
+    { numerator_ *= e; return *this; }
+    /// Multiply P with the scalar a.
+    rational_fraction operator *(const T &e) const
+    { rational_fraction R = *this; R *= e; return R; }
+    /// Divide P with the scalar a. P contains the result.
+    rational_fraction &operator /=(const T &e)
+    { denominator_ *= e; return *this; }
+    /// Divide P with the scalar a.
+    rational_fraction operator /(const T &e) const
+    { rational_fraction res = *this; res /= e; return res; }   
+    /// operator ==.
+    bool operator ==(const rational_fraction &Q) const
+    { return  (numerator_==Q.numerator() && denominator_==Q.denominator()); }
+    /// operator !=.
+    bool operator !=(const rational_fraction  &Q) const
+    { return !(operator ==(*this,Q)); }   
+    /// Derivative of P with respect to the variable k. P contains the result.
+    void derivative(short_type k) {
+      polynomial<T> der_num = numerator_;   der_num.derivative(k);
+      polynomial<T> der_den = denominator_; der_den.derivative(k);
+      if (der_den.is_zero()) {
+	if (der_num.is_zero()) this->clear(); else numerator_ = der_num;
+      } else {
+	numerator_ = der_num * denominator_ - der_den * numerator_;
+	denominator_ =  denominator_ * denominator_;
+      }
+    }
+    /// Makes P = 1.
+    void one() { numerator_.one(); denominator_.one(); }
+    void clear() { numerator_.clear(); denominator_.one(); }
+    template <typename ITER> T eval(const ITER &it) const {
+      typedef typename gmm::number_traits<T>::magnitude_type R;
+      T a = numerator_.eval(it), b = denominator_.eval(it);
+      if (b == T(0)) { // The better should be to evaluate the derivatives ...
+	std::vector<T> p(it, it+dim()), q(dim(), T(1));
+	R no = gmm::vect_norm2(p);
+	if (no == R(0)) no = R(1E-35); else no*=gmm::default_tol(R())*R(100000);
+	gmm::add(gmm::scaled(q, T(no)), p);
+	a = numerator_.eval(p.begin());
+	b = denominator_.eval(p.begin());
+      }
+      if (a != T(0)) a /= b;
+      return a;
+    }
+    /// Constructor.
+    rational_fraction()
+      : numerator_(1,0), denominator_(1,0) { clear(); }
+    /// Constructor.
+    rational_fraction(short_type dim_)
+      : numerator_(dim_,0), denominator_(dim_,0)  { clear(); }
+    /// Constructor
+    rational_fraction(const polynomial<T> &numer)
+      : numerator_(numer), denominator_(numer.dim(),0) { denominator_.one(); }
+    /// Constructor
+    rational_fraction(const polynomial<T> &numer, const polynomial<T> &denom)
+      : numerator_(numer), denominator_(denom)
+    { GMM_ASSERT1(numer.dim() == denom.dim(), "Dimensions mismatch"); }
+  };
+
+  /// Add Q to P.
+  template<typename T>
+  rational_fraction<T> operator +(const polynomial<T> &P,
+				  const rational_fraction<T> &Q) {
+    rational_fraction<T> R(P*Q.denominator()+Q.numerator(), Q.denominator());
+    return R;
+  }
+  /// Subtract Q from P.
+  template<typename T>
+  rational_fraction<T> operator -(const polynomial<T> &P,
+				  const rational_fraction<T> &Q) {
+    rational_fraction<T> R(P*Q.denominator()-Q.numerator(), Q.denominator());
+    return R;
+  }
+  
+  template<typename T>  std::ostream &operator <<
+  (std::ostream &o, const rational_fraction<T>& P) {
+    o << "[" << P.numerator() << "]/[" << P.denominator() << "]";
+    return o;
+  }
+
+  typedef rational_fraction<opt_long_scalar_type> base_rational_fraction;
+
 }  /* end of namespace bgeot.                                           */
 
 
diff --git a/src/getfem/bgeot_poly_composite.h b/src/getfem/bgeot_poly_composite.h
index 4d3021f..5c43f65 100644
--- a/src/getfem/bgeot_poly_composite.h
+++ b/src/getfem/bgeot_poly_composite.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -106,13 +106,22 @@ namespace bgeot {
     void derivative(short_type k);
     base_poly &poly_of_subelt(size_type l) { return polytab[l]; }
     const base_poly &poly_of_subelt(size_type l) const { return polytab[l]; }
-    
+    size_type nb_subelt() const { return polytab.size(); }
 
     polynomial_composite(bool lc = true) : local_coordinate(lc) {}
     polynomial_composite(const mesh_precomposite &m, bool lc = true);
 
   };
 
+  inline std::ostream &operator <<
+  (std::ostream &o, const polynomial_composite& P) {
+    o << "poly_composite [";
+    for (size_type i = 0; i < P.nb_subelt(); ++i) 
+      { if (i != 0) o << ", ";  o << P.poly_of_subelt(i); }
+    o << "]";
+    return o;
+  }
+
   template <class ITER>
   scalar_type polynomial_composite::eval(const ITER &it) const {
     base_node pt(mp->dim());
diff --git a/src/getfem/bgeot_rtree.h b/src/getfem/bgeot_rtree.h
index 0af67b0..397eec3 100644
--- a/src/getfem/bgeot_rtree.h
+++ b/src/getfem/bgeot_rtree.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Julien Pommier
+ Copyright (C) 2000-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/bgeot_small_vector.h b/src/getfem/bgeot_small_vector.h
index 9d74483..a952d26 100644
--- a/src/getfem/bgeot_small_vector.h
+++ b/src/getfem/bgeot_small_vector.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Julien Pommier
+ Copyright (C) 2000-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -174,9 +174,9 @@ namespace bgeot {
     typedef const T * const_iterator;
 
     reference operator[](size_type l)
-    { GMM_ASSERT2(l < size(), "out of range"); return base()[l]; }
+    { GMM_ASSERT2(l <=size(), "out of range, l="<<l<<"size="<<size()); return base()[l]; }
     value_type operator[](size_type l) const
-    { GMM_ASSERT2(l < size(), "out of range"); return const_base()[l]; }
+    { GMM_ASSERT2(l <= size(), "out of range, l="<<l<<"size="<<size()); return const_base()[l]; }
     value_type at(size_type l) const { return const_base()[l]; }
     iterator begin() { return base(); }
     const_iterator begin() const { return const_base(); }
@@ -394,7 +394,7 @@ namespace bgeot {
   template <class VEC_CONT>
   void vectors_to_base_matrix(base_matrix &G, const VEC_CONT &a) {
     size_type P = (*(a.begin())).size(), NP = a.end() - a.begin();
-    G.resize(P, NP);
+    G.base_resize(P, NP);
     typename VEC_CONT::const_iterator it = a.begin(), ite = a.end();
     base_matrix::iterator itm = G.begin();
     for (; it != ite; ++it, itm += P)
diff --git a/src/getfem/bgeot_sparse_tensors.h b/src/getfem/bgeot_sparse_tensors.h
index 3b77128..0f45e22 100644
--- a/src/getfem/bgeot_sparse_tensors.h
+++ b/src/getfem/bgeot_sparse_tensors.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Julien Pommier
+ Copyright (C) 2000-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/bgeot_tensor.h b/src/getfem/bgeot_tensor.h
index e4da315..43d779d 100644
--- a/src/getfem/bgeot_tensor.h
+++ b/src/getfem/bgeot_tensor.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -200,34 +200,34 @@ namespace bgeot {
     inline size_type order(void) const { return sizes_.size(); }
 
     void init(const multi_index &c) {
-      multi_index::const_iterator it = c.begin();
+      auto it = c.begin();
       size_type d = 1;
       sizes_ = c; coeff.resize(c.size());
-      multi_index::iterator p = coeff.begin(), pe = coeff.end();
+      auto p = coeff.begin(), pe = coeff.end();
       for ( ; p != pe; ++p, ++it) { *p = d; d *= *it; }
       this->resize(d);
     }
 
-    void init() { sizes_.resize(0);  coeff.resize(0); this->resize(1); }
+    inline void init() { sizes_.resize(0);  coeff.resize(0); this->resize(1); }
 
-    void init(size_type i) {
+    inline void init(size_type i) {
       sizes_.resize(1); sizes_[0] = i; coeff.resize(1); coeff[0] = 1;
       this->resize(i);
     }
 
-    void init(size_type i, size_type j) {
+    inline void init(size_type i, size_type j) {
       sizes_.resize(2); sizes_[0] = i; sizes_[1] = j;
       coeff.resize(2); coeff[0] = 1; coeff[1] = i;
       this->resize(i*j);
     }
 
-    void init(size_type i, size_type j, size_type k) {
+    inline void init(size_type i, size_type j, size_type k) {
       sizes_.resize(3); sizes_[0] = i; sizes_[1] = j; sizes_[2] = k; 
       coeff.resize(3); coeff[0] = 1; coeff[1] = i; coeff[2] = i*j;
       this->resize(i*j*k);
     }
 
-    void init(size_type i, size_type j, size_type k, size_type l) {
+    inline void init(size_type i, size_type j, size_type k, size_type l) {
       sizes_.resize(4);
       sizes_[0] = i; sizes_[1] = j; sizes_[2] = k; sizes_[3] = k; 
       coeff.resize(4);
@@ -235,36 +235,42 @@ namespace bgeot {
       this->resize(i*j*k*l);
     }
 
-    void adjust_sizes(const multi_index &mi) {
-      if (!mi.size() || (mi.size() != sizes().size())
-          || !(std::equal(mi.begin(), mi.end(), sizes().begin())))
-        init(mi);
+    inline void adjust_sizes(const multi_index &mi) { init(mi); }
+    inline void adjust_sizes(void) { init(); }
+    inline void adjust_sizes(size_type i) { init(i); }
+    inline void adjust_sizes(size_type i, size_type j) { init(i, j); }
+    inline void adjust_sizes(size_type i, size_type j, size_type k)
+    { init(i, j, k); }
+    inline void adjust_sizes(size_type i, size_type j, size_type k, size_type l)
+    { init(i, j, k, l); }
+    
+    inline size_type adjust_sizes_changing_last(const tensor &t, size_type P) {
+      const multi_index &mi = t.sizes_; size_type d = mi.size();
+      sizes_.resize(d); coeff.resize(d);
+      if (d) {
+	std::copy(mi.begin(), mi.end(), sizes_.begin());
+	std::copy(t.coeff.begin(), t.coeff.end(), coeff.begin());
+	size_type e = coeff.back();
+	sizes_.back() = P;
+	this->resize(e*P);
+	return e;
+      } else {
+	this->resize(1);
+	return 1;
+      }
     }
 
-    void adjust_sizes(void) { if (sizes_.size() || this->size() != 1) init(); }
-
-    void adjust_sizes(size_type i)
-    { if (sizes_.size() != 1 || sizes_[0] != i) init(i); }
-
-    void adjust_sizes(size_type i, size_type j)
-    { if (sizes_.size() != 2 || sizes_[0] != i || sizes_[1] != j) init(i, j); }
-
-    void adjust_sizes(size_type i, size_type j, size_type k) {
-      if (sizes_.size() != 3 || sizes_[0] != i || sizes_[1] != j
-          || sizes_[2] != k)
-        init(i, j, k);
-    }
-    void adjust_sizes(size_type i, size_type j, size_type k, size_type l) {
-      if (sizes_.size() != 3 || sizes_[0] != i || sizes_[1] != j
-          || sizes_[2] != k || sizes_[3] != l)
-        init(i, j, k, l);
+    inline void remove_unit_dim() {
+      if (sizes_.size()) {
+	size_type i = 0, j = 0;
+	for (; i < sizes_.size(); ++i)
+	  if (sizes_[i] != 1) { sizes_[j]=sizes_[i]; coeff[j]=coeff[i]; ++j; }
+	if (!j) ++j;
+	sizes_.resize(j);
+	coeff.resize(j);
+      }
     }
 
-    tensor(const multi_index &c) { init(c); }
-    tensor(size_type i, size_type j, size_type k, size_type l)
-    { init(multi_index(i, j, k, l)); }
-    tensor(void) {}
-
     /** reduction of tensor t with respect to index ni with matrix m:
      *  t(...,j,...) <-- t(...,i,..) m(i, j)
      */
@@ -305,6 +311,21 @@ namespace bgeot {
 
     tensor<T>& operator /=(const scalar_type w)
     { gmm::scale(this->as_vector(), scalar_type(1)/w); return *this; }
+
+    tensor &operator =(const tensor &t) {
+      if (this->size() != t.size()) this->resize(t.size());
+      std::copy(t.begin(), t.end(), this->begin());
+      if (sizes_.size() != t.sizes_.size()) sizes_.resize(t.sizes_.size());
+      std::copy(t.sizes_.begin(), t.sizes_.end(), sizes_.begin());
+      if (coeff.size() != t.coeff.size()) coeff.resize(t.coeff.size());
+      std::copy(t.coeff.begin(), t.coeff.end(), coeff.begin());
+      return *this;
+    }
+
+    tensor(const multi_index &c) { init(c); }
+    tensor(size_type i, size_type j, size_type k, size_type l)
+    { init(multi_index(i, j, k, l)); }
+    tensor(void) {}
   };
 
   template<class T> void tensor<T>::mat_transp_reduction
@@ -312,17 +333,8 @@ namespace bgeot {
     /* reduction du tenseur t par son indice ni et la matrice          */
     /* transposee de m.                                                */
 
-    // DEFINE_STATIC_THREAD_LOCAL(std::vector<T>*,tmp);
-    // DEFINE_STATIC_THREAD_LOCAL(multi_index*,mi);
     DEFINE_STATIC_THREAD_LOCAL(std::vector<T>, tmp);
     DEFINE_STATIC_THREAD_LOCAL(multi_index, mi);
-    // DEFINE_STATIC_THREAD_LOCAL_INITIALIZED(bool,isinit,false);
-
-    // if (!isinit) {
-    //  tmp = std::make_shared<std::vector<T>(3);
-    //  mi = std::make_shared<multi_index>();
-    //  isinit = true;
-    // }
 
     mi = t.sizes();
     size_type dimt = mi[ni], dim = m.nrows();
@@ -331,7 +343,6 @@ namespace bgeot {
     GMM_ASSERT2(dimt == m.ncols(), "Dimensions mismatch.");
     GMM_ASSERT2(&t != this, "Does not work when t and *this are the same.");
 
-
     mi[ni] = dim;
     if (tmp.size() < dimt) tmp.resize(dimt);
     adjust_sizes(mi);
@@ -371,7 +382,7 @@ namespace bgeot {
                 "This operation is for order four tensors only.");
     GMM_ASSERT2(sizes_[2] == gmm::mat_nrows(m) &&
                 sizes_[3] == gmm::mat_ncols(m), "Dimensions mismatch.");
-    gmm::resize(mm, sizes_[0], sizes_[1]);
+    mm.base_resize(sizes_[0], sizes_[1]);
     gmm::clear(mm);
 
     const_iterator pt = this->begin();
@@ -389,14 +400,9 @@ namespace bgeot {
   template<class T> void tensor<T>::mat_reduction
   (const tensor &t, const gmm::dense_matrix<T> &m, int ni) {
     /* reduction du tenseur t par son indice ni et la matrice m.       */
-    // DEFINE_STATIC_THREAD_LOCAL(std::vector<T>*,tmp);
-    // DEFINE_STATIC_THREAD_LOCAL(multi_index*,mi);
-    // DEFINE_STATIC_THREAD_LOCAL_INITIALIZED(bool,isinit,false);
     DEFINE_STATIC_THREAD_LOCAL(std::vector<T>, tmp);
     DEFINE_STATIC_THREAD_LOCAL(multi_index, mi);
-    // if (!isinit) {
-    //  tmp = new std::vector<T>(3); mi = new multi_index(); isinit = true;
-    // }
+    
     mi = t.sizes();
     size_type dimt = mi[ni], dim = m.ncols();
     GMM_ASSERT2(dimt, "Inconsistent dimension.");
@@ -540,7 +546,7 @@ namespace bgeot {
 
   template<class T> std::ostream &operator <<
     (std::ostream &o, const tensor<T>& t) {
-    o << "sizes " << t.sizes() << " " << t.as_vector();
+    o << "sizes " << t.sizes() << " " << vref(t.as_vector());
     return o;
   }
 
diff --git a/src/getfem/dal_backtrace.h b/src/getfem/dal_backtrace.h
index c98aff5..c23c95a 100644
--- a/src/getfem/dal_backtrace.h
+++ b/src/getfem/dal_backtrace.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1995-2016 Yves Renard
+ Copyright (C) 1995-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/dal_basic.h b/src/getfem/dal_basic.h
index 47b7168..878b996 100644
--- a/src/getfem/dal_basic.h
+++ b/src/getfem/dal_basic.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1995-2016 Yves Renard
+ Copyright (C) 1995-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/dal_bit_vector.h b/src/getfem/dal_bit_vector.h
index 22aa796..9ffe368 100644
--- a/src/getfem/dal_bit_vector.h
+++ b/src/getfem/dal_bit_vector.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1995-2016 Yves Renard
+ Copyright (C) 1995-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/dal_config.h b/src/getfem/dal_config.h
index 1d36c4f..87b87b5 100644
--- a/src/getfem/dal_config.h
+++ b/src/getfem/dal_config.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard
+ Copyright (C) 2007-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/dal_naming_system.h b/src/getfem/dal_naming_system.h
index d7a5be9..71f1226 100644
--- a/src/getfem/dal_naming_system.h
+++ b/src/getfem/dal_naming_system.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/dal_singleton.h b/src/getfem/dal_singleton.h
index bb46a3a..454f018 100644
--- a/src/getfem/dal_singleton.h
+++ b/src/getfem/dal_singleton.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/dal_static_stored_objects.h b/src/getfem/dal_static_stored_objects.h
index e37849a..7269ddb 100644
--- a/src/getfem/dal_static_stored_objects.h
+++ b/src/getfem/dal_static_stored_objects.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -150,7 +150,7 @@ namespace dal {
   public :
     virtual bool compare(const static_stored_object_key &oo) const {
       const simple_key &o = dynamic_cast<const simple_key &>(oo);
-      if (a < o.a) return true; return false;
+      if (a < o.a) return true; else return false;
     }
     simple_key(var_type aa) : a(aa) {}
   };
@@ -219,7 +219,7 @@ namespace dal {
 
   /** Add an object with two optional dependencies. */
   void add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o,
-    permanence perm = STANDARD_STATIC_OBJECT);
+                         permanence perm = STANDARD_STATIC_OBJECT);
 
   inline void
     add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o,
@@ -230,7 +230,7 @@ namespace dal {
   }
 
   inline void
-    add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o,
+  add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o,
     pstatic_stored_object dep1, pstatic_stored_object dep2,
     permanence perm = STANDARD_STATIC_OBJECT) {
       add_stored_object(k, o, perm);
@@ -239,10 +239,10 @@ namespace dal {
   }
 
   inline void
-    add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o,
-    pstatic_stored_object dep1, pstatic_stored_object dep2,
-    pstatic_stored_object dep3,
-    permanence perm = STANDARD_STATIC_OBJECT) {
+  add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o,
+                    pstatic_stored_object dep1, pstatic_stored_object dep2,
+                    pstatic_stored_object dep3,
+                    permanence perm = STANDARD_STATIC_OBJECT) {
       add_stored_object(k, o, perm);
       add_dependency(o, dep1);
       add_dependency(o, dep2);
@@ -250,10 +250,10 @@ namespace dal {
   }
 
   inline void
-    add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o,
-    pstatic_stored_object dep1, pstatic_stored_object dep2,
-    pstatic_stored_object dep3, pstatic_stored_object dep4,
-    permanence perm = STANDARD_STATIC_OBJECT) {
+  add_stored_object(pstatic_stored_object_key k, pstatic_stored_object o,
+                    pstatic_stored_object dep1, pstatic_stored_object dep2,
+                    pstatic_stored_object dep3, pstatic_stored_object dep4,
+                    permanence perm = STANDARD_STATIC_OBJECT) {
       add_stored_object(k, o, perm);
       add_dependency(o, dep1);
       add_dependency(o, dep2);
@@ -291,7 +291,7 @@ namespace dal {
     std::set<pstatic_stored_object> dependencies;
     enr_static_stored_object(pstatic_stored_object o, permanence perma)
       : p(o), perm(perma) {valid = true;}
-    enr_static_stored_object(void)
+    enr_static_stored_object()
       : perm(STANDARD_STATIC_OBJECT) {valid = true;}
     enr_static_stored_object(const enr_static_stored_object& enr_o)
       : p(enr_o.p), perm(enr_o.perm), dependent_object(enr_o.dependent_object),
diff --git a/src/getfem/dal_tas.h b/src/getfem/dal_tas.h
index 6268ad5..5b93a72 100644
--- a/src/getfem/dal_tas.h
+++ b/src/getfem/dal_tas.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1995-2016 Yves Renard
+ Copyright (C) 1995-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/dal_tree_sorted.h b/src/getfem/dal_tree_sorted.h
index f79fca7..0ae6419 100644
--- a/src/getfem/dal_tree_sorted.h
+++ b/src/getfem/dal_tree_sorted.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1995-2016 Yves Renard
+ Copyright (C) 1995-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -50,13 +50,13 @@ namespace dal {
   /* d'insertion ou de suppression.                                        */
   /* ********************************************************************* */
 
-  static const size_t DEPTHMAX__ = size_t(CHAR_BIT*sizeof(size_t)*3) / 2;
+  static const size_t DEPTHMAX__ = 64;
   static const size_t ST_NIL = size_t(-1);
 
-  template<typename T, typename COMP = gmm::less<T>, int pks = 5>
+  template<typename T, typename COMP = gmm::less<T>, unsigned char pks = 5>
     class dynamic_tree_sorted;
 
-  template<typename T, typename COMP, int pks> struct tsa_iterator {
+  template<typename T, typename COMP, unsigned char pks> struct tsa_iterator {
     typedef T                value_type;
     typedef value_type&      reference;
     typedef value_type*      pointer;
@@ -83,7 +83,7 @@ namespace dal {
     inline size_type father(void) const
     { return (depth<=1) ? ST_NIL : path[depth-2];}
     inline size_type index_(void) const
-    { return path[size_t(depth-1)]; }
+    { return path[(depth-1) & 63]; }
     inline short_type direction(void) const
     { return (depth==0) ? 0 : dir[depth-1];}
     inline void up(void) { if (depth > 0) depth--; }
@@ -112,7 +112,7 @@ namespace dal {
     { return !((i.depth == 0 && depth == 0) || (i.index_() == index_())); }
   };
 
-  template<typename T, typename COMP, int pks> 
+  template<typename T, typename COMP, unsigned char pks> 
   void tsa_iterator<T, COMP, pks>::copy(const tsa_iterator<T, COMP, pks> &it) {
     p = it.p; depth = it.depth;
     size_type *p1it=&(path[0]), *pend=&path[depth];
@@ -122,29 +122,29 @@ namespace dal {
     while (p1it != pend) { *p1it++ = *p2it++; *d1it++ = *d2it++; }
   }
   
-  template<typename T, typename COMP, int pks> 
+  template<typename T, typename COMP, unsigned char pks> 
     void tsa_iterator<T, COMP, pks>::down_left(void) {
     GMM_ASSERT3(depth > 0 && depth < DEPTHMAX__ && index() != ST_NIL,
 		"internal error");
     path[depth] = p->left_elt(index_()); dir[depth++] = -1;
   }
 
-  template<typename T, typename COMP, int pks> 
+  template<typename T, typename COMP, unsigned char pks> 
     void tsa_iterator<T, COMP, pks>::down_right(void) { 
     GMM_ASSERT3(depth > 0 && depth < DEPTHMAX__ && index() != ST_NIL,
 		"internal error");
     path[depth] = p->right_elt(index_()); dir[depth++] = 1;
   }
 
-  template<typename T, typename COMP, int pks> 
+  template<typename T, typename COMP, unsigned char pks> 
     void tsa_iterator<T, COMP, pks>::down_left_all(void)
   { while (index_() != ST_NIL) down_left(); up(); }
 
-  template<typename T, typename COMP, int pks> 
+  template<typename T, typename COMP, unsigned char pks> 
     void tsa_iterator<T, COMP, pks>::down_right_all(void)
   { while (index_() != ST_NIL) down_right(); up();}
    
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
     tsa_iterator<T, COMP, pks> &tsa_iterator<T, COMP, pks>::operator ++() {
     if (depth == 0) first();
     if (p->right_elt(index_()) != ST_NIL) { down_right(); down_left_all(); }
@@ -152,7 +152,7 @@ namespace dal {
     return *this;
   }
   
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
     tsa_iterator<T, COMP, pks> &tsa_iterator<T, COMP, pks>::operator --() {
     if (depth == 0) last();
     if (p->left_elt(index_()) != ST_NIL) { down_left(); down_right_all(); }
@@ -161,7 +161,7 @@ namespace dal {
   }
 
 
-  template<typename T, typename COMP, int pks> struct const_tsa_iterator {
+  template<typename T, typename COMP, unsigned char pks> struct const_tsa_iterator {
     typedef T                  value_type;
     typedef const value_type&  reference;
     typedef const value_type*  pointer;
@@ -217,7 +217,7 @@ namespace dal {
     { return !((i.depth == 0 && depth == 0) || (i.index_() == index_())); }
   };
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   std::ostream& operator<<(std::ostream& o,
 			   const const_tsa_iterator<T,COMP,pks>& it) {
     o << "const_tsa_iterator : depth=" << it.depth << ", path/dir=[";
@@ -227,7 +227,7 @@ namespace dal {
     return o;
   }
 
-  template<typename T, typename COMP, int pks> 
+  template<typename T, typename COMP, unsigned char pks> 
   void const_tsa_iterator<T, COMP, pks>::copy
   (const const_tsa_iterator<T, COMP, pks> &it) {
     p = it.p; depth = it.depth;
@@ -238,7 +238,7 @@ namespace dal {
     while (p1it != pend) { *p1it++ = *p2it++; *d1it++ = *d2it++; }
   }
   
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   const_tsa_iterator<T, COMP, pks>::const_tsa_iterator
   (const tsa_iterator<T, COMP, pks> &it) {
     p = it.p; depth = it.depth;
@@ -249,29 +249,29 @@ namespace dal {
     while (p1it != pend) { *p1it++ = *p2it++; *d1it++ = *d2it++; }
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void const_tsa_iterator<T, COMP, pks>::down_left(void) {
     GMM_ASSERT3(depth > 0 && depth < DEPTHMAX__ && index() != ST_NIL,
 		"internal error");
     path[depth] = p->left_elt(index_()); dir[depth++] = -1;
   }
   
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void const_tsa_iterator<T, COMP, pks>::down_right(void) { 
     GMM_ASSERT3(depth > 0 && depth < DEPTHMAX__ && index() != ST_NIL,
 		"internal error");
     path[depth] = p->right_elt(index_()); dir[depth++] = 1;
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void const_tsa_iterator<T, COMP, pks>::down_left_all(void)
   { while (index_() != ST_NIL) down_left(); up(); }
 
-  template<typename T, typename COMP, int pks> 
+  template<typename T, typename COMP, unsigned char pks> 
     void const_tsa_iterator<T, COMP, pks>::down_right_all(void) 
   { while (index_() != ST_NIL) down_right(); up();}
   
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   const_tsa_iterator<T, COMP, pks> &
   const_tsa_iterator<T, COMP, pks>::operator ++() {  
     if (depth == 0) last();
@@ -280,7 +280,7 @@ namespace dal {
     return *this;
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   const_tsa_iterator<T, COMP, pks> &
   const_tsa_iterator<T, COMP, pks>::operator --() {
     if (depth == 0) last();
@@ -293,7 +293,7 @@ namespace dal {
   /* Definitition of dynamic_tree_sorted.                                  */
   /* ********************************************************************* */
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
     class dynamic_tree_sorted : public dynamic_tas<T, pks> {
     public :
 
@@ -404,7 +404,7 @@ namespace dal {
       const_sorted_iterator sorted_ge(const T &elt) const;
   }; 
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   std::ostream& operator <<(std::ostream& o,
 			    dynamic_tree_sorted<T, COMP, pks> &m) {
     o << "Nomber of elt :" << m.card() << '\n';
@@ -415,7 +415,7 @@ namespace dal {
     return o;
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
     typename dynamic_tree_sorted<T, COMP, pks>::size_type
       dynamic_tree_sorted<T, COMP, pks>::rotate_right(size_type i) {
     tree_elt *pni = &(nodes[i]);
@@ -425,7 +425,7 @@ namespace dal {
     return f;
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
     typename dynamic_tree_sorted<T, COMP, pks>::size_type
       dynamic_tree_sorted<T, COMP, pks>::rotate_left(size_type i) {
     tree_elt *pni = &(nodes[i]);
@@ -435,7 +435,7 @@ namespace dal {
     return f;
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
     typename dynamic_tree_sorted<T, COMP, pks>::size_type
       dynamic_tree_sorted<T, COMP, pks>::rotate_left_right(size_type i) {
     tree_elt *pni = &(nodes[i]);
@@ -456,7 +456,7 @@ namespace dal {
     return f;
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   typename dynamic_tree_sorted<T, COMP, pks>::size_type
   dynamic_tree_sorted<T, COMP, pks>::rotate_right_left(size_type i) {
     size_type f = nodes[i].r;
@@ -473,7 +473,7 @@ namespace dal {
     return f;
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
     typename dynamic_tree_sorted<T, COMP, pks>::size_type
       dynamic_tree_sorted<T, COMP, pks>::balance_again(size_type i) {
     tree_elt *pn = &(nodes[i]);
@@ -488,7 +488,7 @@ namespace dal {
     return ST_NIL;
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void dynamic_tree_sorted<T, COMP, pks>::search_sorted_iterator
   (const T &elt, const_sorted_iterator &it) const{
     it.root();
@@ -499,7 +499,7 @@ namespace dal {
     }
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void dynamic_tree_sorted<T, COMP, pks>::find_sorted_iterator
   (size_type i, const_sorted_iterator &it) const {
     const T *pelt = &((*this)[i]);
@@ -515,7 +515,7 @@ namespace dal {
     /* pour eviter de faire tout le tableau en cas de faux indice.         */
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void dynamic_tree_sorted<T, COMP, pks>::insert_path
   (const T &elt, const_sorted_iterator &it) const {
     it.root();
@@ -525,7 +525,7 @@ namespace dal {
     }
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   typename dynamic_tree_sorted<T, COMP, pks>::size_type
   dynamic_tree_sorted<T, COMP, pks>::search_ge(const T &elt) const {
     const_sorted_iterator it(*this); insert_path(elt, it);
@@ -535,7 +535,7 @@ namespace dal {
     return it.index();
   }
   
-//   template<typename T, typename COMP, int pks>
+//   template<typename T, typename COMP, unsigned char pks>
 //     typename dynamic_tree_sorted<T, COMP, pks>::sorted_iterator
 //       dynamic_tree_sorted<T, COMP, pks>::sorted_ge(const T &elt)
 //   {
@@ -545,7 +545,7 @@ namespace dal {
 //     return it;
 //   } 
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   typename dynamic_tree_sorted<T, COMP, pks>::const_sorted_iterator
   dynamic_tree_sorted<T, COMP, pks>::sorted_ge(const T &elt) const {
     const_sorted_iterator it(*this); insert_path(elt, it);
@@ -556,21 +556,21 @@ namespace dal {
   }
   
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   typename dynamic_tree_sorted<T, COMP, pks>::size_type
   dynamic_tree_sorted<T, COMP, pks>::memsize(void) const {
     return dynamic_tas<T, pks>::memsize() + nodes.memsize()
       + sizeof(dynamic_tree_sorted<T, COMP, pks>);
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void dynamic_tree_sorted<T, COMP, pks>::compact(void) {
     if (!this->empty())
       while (this->ind.last_true() >= this->ind.card())
 	swap(this->ind.first_false(), this->ind.last_true());
   }
   
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void dynamic_tree_sorted<T, COMP, pks>::add_index
   (size_type i, const_sorted_iterator &it) {
     nodes[i].init();
@@ -602,7 +602,7 @@ namespace dal {
     }
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   typename dynamic_tree_sorted<T, COMP, pks>::size_type
   dynamic_tree_sorted<T, COMP, pks>::add(const T &f) {
     const_sorted_iterator it(*this); insert_path(f, it);
@@ -611,7 +611,7 @@ namespace dal {
     return num;
   }
 
-  template<typename T, typename COMP, int pks> void
+  template<typename T, typename COMP, unsigned char pks> void
   dynamic_tree_sorted<T, COMP, pks>::add_to_index(size_type i,const T &f) {
     if (!(this->index_valid(i) && compar(f, (*this)[i]) == 0)) {
       if (this->index_valid(i)) sup(i);
@@ -621,7 +621,7 @@ namespace dal {
     }
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   typename dynamic_tree_sorted<T, COMP, pks>::size_type
   dynamic_tree_sorted<T, COMP, pks>::add_norepeat
   (const T &f, bool replace, bool *present) {
@@ -638,7 +638,7 @@ namespace dal {
     return num;
   }
 
-  template<typename T, typename COMP, int pks> 
+  template<typename T, typename COMP, unsigned char pks> 
   void dynamic_tree_sorted<T, COMP, pks>::resort(void)  {
     const_tas_iterator itb
       = ((const dynamic_tree_sorted<T, COMP, pks> *)(this))->tas_begin();
@@ -650,7 +650,7 @@ namespace dal {
     { insert_path(*itb, it); add_index(itb.index(), it); ++itb; }
   }     
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void dynamic_tree_sorted<T, COMP, pks>::sup_index
   (size_type i, const_sorted_iterator &it) {
     size_type f, ni = i, ic;
@@ -700,7 +700,7 @@ namespace dal {
     }
   }
   
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void dynamic_tree_sorted<T, COMP, pks>::sup(size_type i) {
     GMM_ASSERT2(i < INT_MAX, "out of range");
     const_sorted_iterator it(*this); find_sorted_iterator(i, it);
@@ -708,7 +708,7 @@ namespace dal {
     { sup_index(i, it); dynamic_tas<T, pks>::sup(i); }
   }
 
-  template<typename T, typename COMP, int pks>
+  template<typename T, typename COMP, unsigned char pks>
   void dynamic_tree_sorted<T, COMP, pks>::swap(size_type i, size_type j) {
     GMM_ASSERT2(i < INT_MAX && j < INT_MAX, "out of range");
 
@@ -754,7 +754,7 @@ namespace dal {
   };
 
 
-  template<typename T, typename TAB, typename COMP = gmm::less<T>, int pks = 5>
+  template<typename T, typename TAB, typename COMP = gmm::less<T>, unsigned char pks = 5>
   class dynamic_tree_sorted_index : public
   dynamic_tree_sorted<size_t, less_index<T,TAB,COMP>, pks> {
   public :
diff --git a/src/getfem/getfem_Navier_Stokes.h b/src/getfem/getfem_Navier_Stokes.h
index 652d9f1..dd03e3d 100644
--- a/src/getfem/getfem_Navier_Stokes.h
+++ b/src/getfem/getfem_Navier_Stokes.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_arch_config.h b/src/getfem/getfem_arch_config.h
index 7459b6d..a31b369 100644
--- a/src/getfem/getfem_arch_config.h
+++ b/src/getfem/getfem_arch_config.h
@@ -59,11 +59,6 @@
 /* Define to 1 if you have the `mpi_cxx' library (-lmpi_cxx). */
 /* #undef GETFEM_HAVE_LIBMPI_CXX */
 
-/* Define to 1 if you have the `qhull' library (-lqhull). */
-#ifndef GETFEM_HAVE_LIBQHULL 
-#define GETFEM_HAVE_LIBQHULL  1 
-#endif
-
 /* Define to 1 if you have the <libqhull/qhull_a.h> header file. */
 #ifndef GETFEM_HAVE_LIBQHULL_QHULL_A_H 
 #define GETFEM_HAVE_LIBQHULL_QHULL_A_H  1 
@@ -176,7 +171,8 @@
 #define GETFEM_HAVE_ZMUMPS_C_H  1 
 #endif
 
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
 #ifndef GETFEM_LT_OBJDIR 
 #define GETFEM_LT_OBJDIR  ".libs/" 
 #endif
@@ -198,7 +194,7 @@
 
 /* Define to the full name and version of this package. */
 #ifndef GETFEM_PACKAGE_STRING 
-#define GETFEM_PACKAGE_STRING  "getfem 5.1" 
+#define GETFEM_PACKAGE_STRING  "getfem 5.2" 
 #endif
 
 /* Define to the one symbol short name of this package. */
@@ -213,7 +209,7 @@
 
 /* Define to the version of this package. */
 #ifndef GETFEM_PACKAGE_VERSION 
-#define GETFEM_PACKAGE_VERSION  "5.1" 
+#define GETFEM_PACKAGE_VERSION  "5.2" 
 #endif
 
 /* defined if quad-doubles are to be used instead of double-double */
@@ -229,7 +225,7 @@
 
 /* Version number of package */
 #ifndef GETFEM_VERSION 
-#define GETFEM_VERSION  "5.1" 
+#define GETFEM_VERSION  "5.2" 
 #endif
  
 /* once: _SRC_GETFEM_GETFEM_ARCH_CONFIG_H */
diff --git a/src/getfem/getfem_assembling.h b/src/getfem/getfem_assembling.h
index 4dc7051..cfb0f4a 100644
--- a/src/getfem/getfem_assembling.h
+++ b/src/getfem/getfem_assembling.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2000-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -33,7 +33,8 @@
     @author  Yves Renard <Yves.Renard at insa-lyon.fr>
     @author  Julien Pommier <Julien.Pommier at insa-toulouse.fr>
     @date November 17, 2000.
-    @brief Miscelleanous assembly routines for common PDEs.
+    @brief Miscelleanous assembly routines for common terms. Use the low-level
+           generic assembly. Prefer the high-level one.
  */
 
 /** @defgroup asm Assembly routines */
@@ -42,72 +43,68 @@
 #define GETFEM_ASSEMBLING_H__
 
 #include "getfem_assembling_tensors.h"
+#include "getfem_generic_assembly.h"
 
 namespace getfem {
-  
-  template <typename VEC>
-  scalar_type asm_mean_value(const mesh_im &mim, const mesh_fem &mf,
-			     const VEC &U,
-			     mesh_region rg = mesh_region::all_convexes()) {
-    // for parallelized getfem, work only on the mesh subset 
-    // assigned to the current thread
-    mim.linked_mesh().intersect_with_mpi_region(rg);
-    generic_assembly assem;
-    std::vector<scalar_type> v(1), w(1);
-    GMM_ASSERT1(mf.get_qdim() == 1, "expecting qdim=1");
-    assem.set("u=data(#1); V$1()+=comp(); V$2()+=comp(Base(#1))(i).u(i);");
-    assem.push_mi(mim);
-    assem.push_mf(mf);
-    assem.push_data(U);
-    assem.push_vec(v);
-    assem.push_vec(w);
-    assem.assembly(rg);
-    v.push_back(w[0]);
-    w.resize(2);
-    MPI_SUM_VECTOR(v, w);
-    return w[1]/w[0];
-  }
 
   /**
      compute @f$ \|U\|_2 @f$, U might be real or complex
      @ingroup asm
    */
   template<typename VEC>
-  scalar_type asm_L2_norm(const mesh_im &mim, const mesh_fem &mf, const VEC &U,
-			  const mesh_region &rg=mesh_region::all_convexes()) {
-    return
-      sqrt(asm_L2_norm_sqr(mim, mf, U, rg,
-			   typename gmm::linalg_traits<VEC>::value_type()));
-  }
+  inline scalar_type asm_L2_norm
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg=mesh_region::all_convexes())
+  { return sqrt(asm_L2_norm_sqr(mim, mf, U, rg)); }
 
+  template<typename VEC>
+  scalar_type asm_L2_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg=mesh_region::all_convexes()) {
+    return asm_L2_norm_sqr(mim, mf, U, rg,
+			   typename gmm::linalg_traits<VEC>::value_type());
+  }
+  
   template<typename VEC, typename T>
-  scalar_type asm_L2_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
+  inline scalar_type asm_L2_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
 			      const VEC &U, const mesh_region &rg_, T) {
-    mesh_region rg(rg_);
-    mim.linked_mesh().intersect_with_mpi_region(rg);
-    generic_assembly assem;    
-    if (mf.get_qdim() == 1)
-      assem.set("u=data(#1); V()+=u(i).u(j).comp(Base(#1).Base(#1))(i,j)");
-    else
-      assem.set("u=data(#1);"
-		"V()+=u(i).u(j).comp(vBase(#1).vBase(#1))(i,k,j,k)");
-    assem.push_mi(mim);
-    assem.push_mf(mf);
-    assem.push_data(U);
-    std::vector<scalar_type> v(1);
-    assem.push_vec(v);
-    assem.assembly(rg);
-    return MPI_SUM_SCALAR(v[0]);
+    ga_workspace workspace;
+    model_real_plain_vector UU(mf.nb_dof());
+    gmm::copy(U, UU);
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, UU);
+    workspace.add_expression("u.u", mim, rg_);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+  inline scalar_type asm_L2_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
+			      const model_real_plain_vector &U,
+			      const mesh_region &rg_, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, U);
+    workspace.add_expression("u.u", mim, rg_);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
 
   template<typename VEC, typename T>
-  scalar_type asm_L2_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
+  inline scalar_type asm_L2_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
 			      const VEC &U,
 			      const mesh_region &rg, std::complex<T>) {
-    return asm_L2_norm_sqr(mim, mf,gmm::real_part(U),rg,T()) + 
-      asm_L2_norm_sqr(mim, mf,gmm::imag_part(U),rg,T());
+    ga_workspace workspace;
+    model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
+    gmm::copy(gmm::real_part(U), UUR);
+    gmm::copy(gmm::imag_part(U), UUI);
+    gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iur, UUR);
+    workspace.add_fem_variable("v", mf, Iui, UUI);
+    workspace.add_expression("u.u + v.v", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
-
+  
   /**
      Compute the distance between U1 and U2, defined on two different
      mesh_fems (but sharing the same mesh), without interpolating U1 on mf2.
@@ -115,31 +112,61 @@ namespace getfem {
      @ingroup asm
   */
   template<typename VEC1, typename VEC2>
-  scalar_type asm_L2_dist(const mesh_im &mim, 
-			  const mesh_fem &mf1, const VEC1 &U1,
-			  const mesh_fem &mf2, const VEC2 &U2, 
-			  mesh_region rg = mesh_region::all_convexes()) {
-    mim.linked_mesh().intersect_with_mpi_region(rg);
-    generic_assembly assem;    
-    if (mf1.get_qdim() == 1)
-      assem.set("u1=data$1(#1); u2=data$2(#2); "
-		"V()+=u1(i).u1(j).comp(Base(#1).Base(#1))(i,j)"
-		"+ u2(i).u2(j).comp(Base(#2).Base(#2))(i,j)"
-		"- 2*u1(i).u2(j).comp(Base(#1).Base(#2))(i,j)");
-    else 
-      assem.set("u1=data$1(#1); u2=data$2(#2); "
-		"V()+=u1(i).u1(j).comp(vBase(#1).vBase(#1))(i,k,j,k)"
-		"+ u2(i).u2(j).comp(vBase(#2).vBase(#2))(i,k,j,k)"
-		"- 2*u1(i).u2(j).comp(vBase(#1).vBase(#2))(i,k,j,k)");
-    assem.push_mi(mim);
-    assem.push_mf(mf1);
-    assem.push_mf(mf2);
-    assem.push_data(U1);
-    assem.push_data(U2);
-    std::vector<scalar_type> v(1);
-    assem.push_vec(v);
-    assem.assembly(rg);
-    return sqrt(MPI_SUM_SCALAR(v[0]));
+  inline scalar_type asm_L2_dist
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2,
+   mesh_region rg = mesh_region::all_convexes()) {
+    return sqrt(asm_L2_dist_sqr(mim, mf1, U1, mf2, U2, rg,
+			   typename gmm::linalg_traits<VEC1>::value_type()));
+  }
+
+  template<typename VEC1, typename VEC2, typename T>
+  inline scalar_type asm_L2_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2, mesh_region rg, T) {
+    ga_workspace workspace;
+    model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
+    gmm::copy(U1, UU1); gmm::copy(U2, UU2);
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, UU1);
+    workspace.add_fem_variable("u2", mf2, Iu2, UU2);
+    workspace.add_expression("(u2-u1).(u2-u1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+  inline scalar_type asm_L2_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const  model_real_plain_vector &U1,
+   const mesh_fem &mf2, const  model_real_plain_vector &U2, 
+   mesh_region rg, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, U1);
+    workspace.add_fem_variable("u2", mf2, Iu2, U2);
+    workspace.add_expression("(u2-u1).(u2-u1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+  template<typename VEC1, typename VEC2, typename T>
+  inline scalar_type asm_L2_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2, mesh_region rg, std::complex<T>) {
+    ga_workspace workspace;
+    model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
+    model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
+    gmm::copy(gmm::real_part(U1), UU1R); gmm::copy(gmm::imag_part(U1), UU1I);
+    gmm::copy(gmm::real_part(U2), UU2R); gmm::copy(gmm::imag_part(U2), UU2I);
+    gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
+    gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
+    gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1r, UU1R);
+    workspace.add_fem_variable("u2", mf2, Iu2r, UU2R);
+    workspace.add_fem_variable("v1", mf1, Iu1i, UU1I);
+    workspace.add_fem_variable("v2", mf2, Iu2i, UU2I);
+    workspace.add_expression("(u2-u1).(u2-u1) + (v2-v1).(v2-v1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
 
   
@@ -156,74 +183,167 @@ namespace getfem {
   }
 
   template<typename VEC, typename T>
-  scalar_type asm_H1_semi_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
-				   const VEC &U, const mesh_region &rg_, T) {
-    mesh_region rg(rg_);
-    mim.linked_mesh().intersect_with_mpi_region(rg);
-    generic_assembly assem;    
-    if (mf.get_qdim() == 1)
-      assem.set("u=data(#1); V()+=u(i).u(j).comp(Grad(#1).Grad(#1))(i,d,j,d)");
-    else
-      assem.set("u=data(#1);"
-		"V()+=u(i).u(j).comp(vGrad(#1).vGrad(#1))(i,k,d,j,k,d)");
-    assem.push_mi(mim);
-    assem.push_mf(mf);
-    assem.push_data(U);
-    std::vector<scalar_type> v(1);
-    assem.push_vec(v);
-    assem.assembly(rg);
-    return MPI_SUM_SCALAR(v[0]);
+  inline scalar_type asm_H1_semi_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg_, T) {
+    ga_workspace workspace;
+    model_real_plain_vector UU(mf.nb_dof()); gmm::copy(U, UU);
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, UU);
+    workspace.add_expression("Grad_u:Grad_u", mim, rg_);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
 
-  template<typename VEC, typename T>
-  scalar_type asm_H1_semi_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
-				   const VEC &U,
-				   const mesh_region &rg, std::complex<T>) {
-    return asm_H1_semi_norm_sqr(mim, mf, gmm::real_part(U), rg, T()) + 
-      asm_H1_semi_norm_sqr(mim, mf, gmm::imag_part(U), rg, T());
+  inline scalar_type asm_H1_semi_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const model_real_plain_vector &U,
+   const mesh_region &rg_, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, U);
+    workspace.add_expression("Grad_u:Grad_u", mim, rg_);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
+  
 
+  template<typename VEC, typename T>
+  inline scalar_type asm_H1_semi_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg, std::complex<T>) {
+    ga_workspace workspace;
+    model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
+    gmm::copy(gmm::real_part(U), UUR);
+    gmm::copy(gmm::imag_part(U), UUI);
+    gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iur, UUR);
+    workspace.add_fem_variable("v", mf, Iui, UUI);
+    workspace.add_expression("Grad_u:Grad_u + Grad_v:Grad_v", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
   
+  /**
+     Compute the H1 semi-distance between U1 and U2, defined on two different
+     mesh_fems (but sharing the same mesh), without interpolating U1 on mf2.
+     
+     @ingroup asm
+  */
   template<typename VEC1, typename VEC2>
-  scalar_type asm_H1_semi_dist(const mesh_im &mim, 
-			       const mesh_fem &mf1, const VEC1 &U1,
-			       const mesh_fem &mf2, const VEC2 &U2,
-			       mesh_region rg = mesh_region::all_convexes()) {
-    mim.linked_mesh().intersect_with_mpi_region(rg);
-    generic_assembly assem;    
-    if (mf1.get_qdim() == 1)
-      assem.set("u1=data$1(#1); u2=data$2(#2); "
-		"V()+=u1(i).u1(j).comp(Grad(#1).Grad(#1))(i,d,j,d)"
-		"+ u2(i).u2(j).comp(Grad(#2).Grad(#2))(i,d,j,d)"
-		"- 2*u1(i).u2(j).comp(Grad(#1).Grad(#2))(i,d,j,d)");
-    else 
-      assem.set("u1=data$1(#1); u2=data$2(#2); "
-		"V()+=u1(i).u1(j).comp(vGrad(#1).vGrad(#1))(i,k,d,j,k,d)"
-		"+ u2(i).u2(j).comp(vGrad(#2).vGrad(#2))(i,k,d,j,k,d)"
-		"- 2*u1(i).u2(j).comp(vGrad(#1).vGrad(#2))(i,k,d,j,k,d)");
-    assem.push_mi(mim);
-    assem.push_mf(mf1);
-    assem.push_mf(mf2);
-    assem.push_data(U1);
-    assem.push_data(U2);
-    std::vector<scalar_type> v(1);
-    assem.push_vec(v);
-    assem.assembly(rg);
-    return sqrt(MPI_SUM_SCALAR(v[0]));    
+  inline scalar_type asm_H1_semi_dist
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2,
+   mesh_region rg = mesh_region::all_convexes()) {
+    return sqrt(asm_H1_semi_dist_sqr(mim, mf1, U1, mf2, U2, rg,
+			   typename gmm::linalg_traits<VEC1>::value_type()));
+  }
+
+  template<typename VEC1, typename VEC2, typename T>
+  inline scalar_type asm_H1_semi_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2, mesh_region rg, T) {
+    ga_workspace workspace;
+    model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
+    gmm::copy(U1, UU1); gmm::copy(U2, UU2);
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, UU1);
+    workspace.add_fem_variable("u2", mf2, Iu2, UU2);
+    workspace.add_expression("(Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+  inline scalar_type asm_H1_semi_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const  model_real_plain_vector &U1,
+   const mesh_fem &mf2, const  model_real_plain_vector &U2, 
+   mesh_region rg, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, U1);
+    workspace.add_fem_variable("u2", mf2, Iu2, U2);
+    workspace.add_expression("(Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+  template<typename VEC1, typename VEC2, typename T>
+  inline scalar_type asm_H1_semi_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2, mesh_region rg, std::complex<T>) {
+    ga_workspace workspace;
+    model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
+    model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
+    gmm::copy(gmm::real_part(U1), UU1R); gmm::copy(gmm::imag_part(U1), UU1I);
+    gmm::copy(gmm::real_part(U2), UU2R); gmm::copy(gmm::imag_part(U2), UU2I);
+    gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
+    gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
+    gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1r, UU1R);
+    workspace.add_fem_variable("u2", mf2, Iu2r, UU2R);
+    workspace.add_fem_variable("v1", mf1, Iu1i, UU1I);
+    workspace.add_fem_variable("v2", mf2, Iu2i, UU2I);
+    workspace.add_expression("(Grad_u2-Grad_u1):(Grad_u2-Grad_u1)"
+			     "+ (Grad_v2-Grad_v1):(Grad_v2-Grad_v1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
 
   /** 
       compute the H1 norm of U.
       @ingroup asm
   */
+
+  /**
+     compute @f$\|\nabla U\|_2 at f$, U might be real or complex
+     @ingroup asm
+   */
   template<typename VEC>
-  scalar_type asm_H1_norm(const mesh_im &mim, const mesh_fem &mf,
-			  const VEC &U,
-			  const mesh_region &rg
-			  = mesh_region::all_convexes()) {
+  scalar_type asm_H1_norm
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg = mesh_region::all_convexes()) {
     typedef typename gmm::linalg_traits<VEC>::value_type T;
-    return sqrt(asm_L2_norm_sqr(mim, mf, U, rg, T()) +
-		asm_H1_semi_norm_sqr(mim, mf, U, rg, T()));
+    return sqrt(asm_H1_norm_sqr(mim, mf, U, rg, T()));
+  }
+
+  template<typename VEC, typename T>
+  inline scalar_type asm_H1_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg_, T) {
+    ga_workspace workspace;
+    model_real_plain_vector UU(mf.nb_dof()); gmm::copy(U, UU);
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, UU);
+    workspace.add_expression("u.u + Grad_u:Grad_u", mim, rg_);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+  inline scalar_type asm_H1_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const model_real_plain_vector &U,
+   const mesh_region &rg_, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, U);
+    workspace.add_expression("u.u + Grad_u:Grad_u", mim, rg_);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+  
+
+  template<typename VEC, typename T>
+  inline scalar_type asm_H1_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg, std::complex<T>) {
+    ga_workspace workspace;
+    model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
+    gmm::copy(gmm::real_part(U), UUR);
+    gmm::copy(gmm::imag_part(U), UUI);
+    gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iur, UUR);
+    workspace.add_fem_variable("v", mf, Iui, UUI);
+    workspace.add_expression("u.u+v.v + Grad_u:Grad_u+Grad_v:Grad_v", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
   
   /**
@@ -231,86 +351,181 @@ namespace getfem {
      @ingroup asm
    */
   template<typename VEC1, typename VEC2>
-  scalar_type asm_H1_dist(const mesh_im &mim, 
-			  const mesh_fem &mf1, const VEC1 &U1,
-			  const mesh_fem &mf2, const VEC2 &U2,
-			  const mesh_region &rg
-			  = mesh_region::all_convexes()) {
-    return sqrt(gmm::sqr(asm_L2_dist(mim,mf1,U1,mf2,U2,rg)) + 
-		gmm::sqr(asm_H1_semi_dist(mim,mf1,U1,mf2,U2,rg)));
+  inline scalar_type asm_H1_dist
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2,
+   mesh_region rg = mesh_region::all_convexes()) {
+    return sqrt(asm_H1_dist_sqr(mim, mf1, U1, mf2, U2, rg,
+			     typename gmm::linalg_traits<VEC1>::value_type()));
   }
 
-  template<typename VEC, typename T>
-  scalar_type asm_H2_semi_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
-				   const VEC &U, const mesh_region &rg_, T) {
-    mesh_region rg(rg_);
-    mim.linked_mesh().intersect_with_mpi_region(rg);
-    generic_assembly assem;    
-    if (mf.get_qdim() == 1)
-      assem.set("u=data(#1);"
-		"V()+=u(i).u(j).comp(Hess(#1).Hess(#1))(i,d,e,j,d,e)");
-    else
-      assem.set("u=data(#1);"
-		"V()+=u(i).u(j).comp(vHess(#1).vHess(#1))(i,k,d,e,j,k,d,e)");
-    assem.push_mi(mim);
-    assem.push_mf(mf);
-    assem.push_data(U);
-    std::vector<scalar_type> v(1);
-    assem.push_vec(v);
-    assem.assembly(rg);
-    return MPI_SUM_SCALAR(v[0]);
+  template<typename VEC1, typename VEC2, typename T>
+  inline scalar_type asm_H1_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2, mesh_region rg, T) {
+    ga_workspace workspace;
+    model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
+    gmm::copy(U1, UU1); gmm::copy(U2, UU2);
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, UU1);
+    workspace.add_fem_variable("u2", mf2, Iu2, UU2);
+    workspace.add_expression("(u2-u1).(u2-u1)"
+			     "+ (Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
 
-  template<typename VEC, typename T>
-  scalar_type asm_H2_semi_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
-				   const VEC &U,
-				   const mesh_region &rg, std::complex<T>) {
-    return asm_H2_semi_norm_sqr(mim, mf, gmm::real_part(U), rg, T()) + 
-      asm_H2_semi_norm_sqr(mim, mf, gmm::imag_part(U), rg, T());
+  inline scalar_type asm_H1_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const  model_real_plain_vector &U1,
+   const mesh_fem &mf2, const  model_real_plain_vector &U2, 
+   mesh_region rg, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, U1);
+    workspace.add_fem_variable("u2", mf2, Iu2, U2);
+    workspace.add_expression("(u2-u1).(u2-u1)"
+			     "+ (Grad_u2-Grad_u1):(Grad_u2-Grad_u1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
 
-  template<typename VEC1, typename VEC2>
-  scalar_type asm_H2_semi_dist(const mesh_im &mim, 
-			       const mesh_fem &mf1, const VEC1 &U1,
-			       const mesh_fem &mf2, const VEC2 &U2,
-			       mesh_region rg = mesh_region::all_convexes()) {
-    mim.linked_mesh().intersect_with_mpi_region(rg);
-    generic_assembly assem;    
-    if (mf1.get_qdim() == 1)
-      assem.set("u1=data$1(#1); u2=data$2(#2); "
-		"V()+=u1(i).u1(j).comp(Hess(#1).Hess(#1))(i,d,e,j,d,e)"
-		"+ u2(i).u2(j).comp(Hess(#2).Hess(#2))(i,d,e,j,d,e)"
-		"- 2*u1(i).u2(j).comp(Hess(#1).Hess(#2))(i,d,e,j,d,e)");
-    else 
-      assem.set("u1=data$1(#1); u2=data$2(#2); "
-		"V()+=u1(i).u1(j).comp(vHess(#1).vHess(#1))(i,k,d,e,j,k,d,e)"
-		"+ u2(i).u2(j).comp(vHess(#2).vHess(#2))(i,k,d,e,j,k,d,e)"
-		"- 2*u1(i).u2(j).comp(vHess(#1).vHess(#2))(i,k,d,e,j,k,d,e)");
-    assem.push_mi(mim);
-    assem.push_mf(mf1);
-    assem.push_mf(mf2);
-    assem.push_data(U1);
-    assem.push_data(U2);
-    std::vector<scalar_type> v(1);
-    assem.push_vec(v);
-    assem.assembly(rg);
-    return sqrt(MPI_SUM_SCALAR(v[0]));    
+  template<typename VEC1, typename VEC2, typename T>
+  inline scalar_type asm_H1_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2, mesh_region rg, std::complex<T>) {
+    ga_workspace workspace;
+    model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
+    model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
+    gmm::copy(gmm::real_part(U1), UU1R); gmm::copy(gmm::imag_part(U1), UU1I);
+    gmm::copy(gmm::real_part(U2), UU2R); gmm::copy(gmm::imag_part(U2), UU2I);
+    gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
+    gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
+    gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1r, UU1R);
+    workspace.add_fem_variable("u2", mf2, Iu2r, UU2R);
+    workspace.add_fem_variable("v1", mf1, Iu1i, UU1I);
+    workspace.add_fem_variable("v2", mf2, Iu2i, UU2I);
+    workspace.add_expression("(u2-u1).(u2-u1) + (v2-v1).(v2-v1)"
+			     "+ (Grad_u2-Grad_u1):(Grad_u2-Grad_u1)"
+			     "+ (Grad_v2-Grad_v1):(Grad_v2-Grad_v1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
   }
 
-
   /**
      compute @f$\|Hess U\|_2 at f$, U might be real or complex. For C^1 elements
      @ingroup asm
-   */
+  */
+  
   template<typename VEC>
-  scalar_type asm_H2_semi_norm(const mesh_im &mim, const mesh_fem &mf,
-			       const VEC &U,
-			       const mesh_region &rg
-			       = mesh_region::all_convexes()) {
+  scalar_type asm_H2_semi_norm
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg = mesh_region::all_convexes()) {
     typedef typename gmm::linalg_traits<VEC>::value_type T;
     return sqrt(asm_H2_semi_norm_sqr(mim, mf, U, rg, T()));
   }
 
+  template<typename VEC, typename T>
+  inline scalar_type asm_H2_semi_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg_, T) {
+    ga_workspace workspace;
+    model_real_plain_vector UU(mf.nb_dof()); gmm::copy(U, UU);
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, UU);
+    workspace.add_expression("Hess_u:Hess_u", mim, rg_);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+  inline scalar_type asm_H2_semi_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const model_real_plain_vector &U,
+   const mesh_region &rg_, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, U);
+    workspace.add_expression("Hess_u:Hess_u", mim, rg_);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+  
+
+  template<typename VEC, typename T>
+  inline scalar_type asm_H2_semi_norm_sqr
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg, std::complex<T>) {
+    ga_workspace workspace;
+    model_real_plain_vector UUR(mf.nb_dof()), UUI(mf.nb_dof());
+    gmm::copy(gmm::real_part(U), UUR);
+    gmm::copy(gmm::imag_part(U), UUI);
+    gmm::sub_interval Iur(0, mf.nb_dof()), Iui(mf.nb_dof(), mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iur, UUR);
+    workspace.add_fem_variable("v", mf, Iui, UUI);
+    workspace.add_expression("Hess_u:Hess_u + Hess_v:Hess_v", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+
+  template<typename VEC1, typename VEC2>
+  inline scalar_type asm_H2_semi_dist
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2,
+   mesh_region rg = mesh_region::all_convexes()) {
+    return sqrt(asm_H2_semi_dist_sqr(mim, mf1, U1, mf2, U2, rg,
+			   typename gmm::linalg_traits<VEC1>::value_type()));
+  }
+
+  template<typename VEC1, typename VEC2, typename T>
+  inline scalar_type asm_H2_semi_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2, mesh_region rg, T) {
+    ga_workspace workspace;
+    model_real_plain_vector UU1(mf1.nb_dof()), UU2(mf2.nb_dof());
+    gmm::copy(U1, UU1); gmm::copy(U2, UU2);
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, UU1);
+    workspace.add_fem_variable("u2", mf2, Iu2, UU2);
+    workspace.add_expression("(Hess_u2-Hess_u1):(Hess_u2-Hess_u1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+  inline scalar_type asm_H2_semi_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const  model_real_plain_vector &U1,
+   const mesh_fem &mf2, const model_real_plain_vector &U2, 
+   mesh_region rg, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(mf1.nb_dof(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, U1);
+    workspace.add_fem_variable("u2", mf2, Iu2, U2);
+    workspace.add_expression("(Hess_u2-Hess_u1):(Hess_u2-Hess_u1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
+  template<typename VEC1, typename VEC2, typename T>
+  inline scalar_type asm_H2_semi_dist_sqr
+  (const mesh_im &mim, const mesh_fem &mf1, const VEC1 &U1,
+   const mesh_fem &mf2, const VEC2 &U2, mesh_region rg, std::complex<T>) {
+    ga_workspace workspace;
+    model_real_plain_vector UU1R(mf1.nb_dof()), UU2R(mf2.nb_dof());
+    model_real_plain_vector UU1I(mf1.nb_dof()), UU2I(mf2.nb_dof());
+    gmm::copy(gmm::real_part(U1), UU1R); gmm::copy(gmm::imag_part(U1), UU1I);
+    gmm::copy(gmm::real_part(U2), UU2R); gmm::copy(gmm::imag_part(U2), UU2I);
+    gmm::sub_interval Iu1r(0, mf1.nb_dof()), Iu2r(mf1.nb_dof(), mf2.nb_dof());
+    gmm::sub_interval Iu1i(Iu2r.last(), mf1.nb_dof());
+    gmm::sub_interval Iu2i(Iu1i.last(), mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1r, UU1R);
+    workspace.add_fem_variable("u2", mf2, Iu2r, UU2R);
+    workspace.add_fem_variable("v1", mf1, Iu1i, UU1I);
+    workspace.add_fem_variable("v2", mf2, Iu2i, UU2I);
+    workspace.add_expression("(Hess_u2-Hess_u1):(Hess_u2-Hess_u1)"
+			     "+ (Hess_v2-Hess_v1):(Hess_v2-Hess_v1)", mim, rg);
+    workspace.assembly(0);
+    return workspace.assembled_potential();
+  }
+
   /** 
       compute the H2 norm of U (for C^1 elements).
       @ingroup asm
@@ -321,8 +536,7 @@ namespace getfem {
 			  const mesh_region &rg
 			  = mesh_region::all_convexes()) {
     typedef typename gmm::linalg_traits<VEC>::value_type T;
-    return sqrt(asm_L2_norm_sqr(mim, mf, U, rg, T())
-		+ asm_H1_semi_norm_sqr(mim, mf, U, rg, T())
+    return sqrt(asm_H1_norm_sqr(mim, mf, U, rg, T())
 		+ asm_H2_semi_norm_sqr(mim, mf, U, rg, T()));
   }
   
@@ -336,99 +550,254 @@ namespace getfem {
 			  const mesh_fem &mf2, const VEC2 &U2,
 			  const mesh_region &rg
 			  = mesh_region::all_convexes()) {
-    return sqrt(gmm::sqr(asm_L2_dist(mim,mf1,U1,mf2,U2,rg)) + 
-		gmm::sqr(asm_H1_semi_dist(mim,mf1,U1,mf2,U2,rg)) +
-		gmm::sqr(asm_H2_semi_dist(mim,mf1,U1,mf2,U2,rg)));
+    typedef typename gmm::linalg_traits<VEC1>::value_type T;
+    return sqrt(asm_H1_dist_sqr(mim,mf1,U1,mf2,U2,rg,T()) +
+		asm_H2_semi_dist_sqr(mim,mf1,U1,mf2,U2,rg,T()));
   }
 
-
   /*
     assembly of a matrix with 1 parameter (real or complex)
     (the most common here for the assembly routines below)
   */
   template <typename MAT, typename VECT>
-  void asm_real_or_complex_1_param
-  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_data,
-   const VECT &A, const mesh_region &rg, const char *assembly_description,
-   const mesh_fem *mf_mult = 0) {
-    asm_real_or_complex_1_param_
-      (M, mim, mf_u, mf_data, A, rg, assembly_description, mf_mult,
+  inline void asm_real_or_complex_1_param_mat
+  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem *mf_data,
+   const VECT &A, const mesh_region &rg, const char *assembly_description) {
+    asm_real_or_complex_1_param_mat_
+      (M, mim, mf_u, mf_data, A, rg, assembly_description,
        typename gmm::linalg_traits<VECT>::value_type());
   }
 
   /* real version */
   template<typename MAT, typename VECT, typename T>
-  void asm_real_or_complex_1_param_
+  inline void asm_real_or_complex_1_param_mat_
   (const MAT &M, const mesh_im &mim,  const mesh_fem &mf_u,
-   const mesh_fem &mf_data, const VECT &A,  const mesh_region &rg,
-   const char *assembly_description, const mesh_fem *mf_mult, T) {
-    generic_assembly assem(assembly_description);
-    assem.push_mi(mim);
-    assem.push_mf(mf_u);
-    assem.push_mf(mf_data);
-    if (mf_mult) assem.push_mf(*mf_mult);
-    assem.push_data(A);
-    assem.push_mat_or_vec(const_cast<MAT&>(M));
-    assem.assembly(rg);
+   const mesh_fem *mf_data, const VECT &A,  const mesh_region &rg,
+   const char *assembly_description, T) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf_u.nb_dof());
+    base_vector u(mf_u.nb_dof()), AA(gmm::vect_size(A));
+    gmm::copy(A, AA);
+    workspace.add_fem_variable("u", mf_u, Iu, u);
+    if (mf_data)
+      workspace.add_fem_constant("A", *mf_data, AA);
+    else
+      workspace.add_fixed_size_constant("A", AA);
+    workspace.add_expression(assembly_description, mim, rg);
+    workspace.assembly(2);
+    if (gmm::mat_nrows(workspace.assembled_matrix()))
+	gmm::add(workspace.assembled_matrix(), const_cast<MAT &>(M));
+  }
+
+  inline void asm_real_or_complex_1_param_mat_
+  (model_real_sparse_matrix &M, const mesh_im &mim,  const mesh_fem &mf_u,
+   const mesh_fem *mf_data, const model_real_plain_vector &A,
+   const mesh_region &rg,
+   const char *assembly_description, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf_u.nb_dof());
+    base_vector u(mf_u.nb_dof());
+    workspace.add_fem_variable("u", mf_u, Iu, u);
+    if (mf_data)
+      workspace.add_fem_constant("A", *mf_data, A);
+    else
+      workspace.add_fixed_size_constant("A", A);
+    workspace.add_expression(assembly_description, mim, rg);
+    workspace.set_assembled_matrix(M);
+    workspace.assembly(2);
   }
 
   /* complex version */
   template<typename MAT, typename VECT, typename T>
-  void asm_real_or_complex_1_param_
-  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_data,
-   const VECT &A, const mesh_region &rg,const char *assembly_description,
-   const mesh_fem *mf_mult, std::complex<T>) {
-    asm_real_or_complex_1_param_(gmm::real_part(M),mim,mf_u,mf_data,
-				 gmm::real_part(A),rg,
-				 assembly_description, mf_mult, T());
-    asm_real_or_complex_1_param_(gmm::imag_part(M),mim,mf_u,mf_data,
-				 gmm::imag_part(A),rg,
-				 assembly_description, mf_mult, T());
+  inline void asm_real_or_complex_1_param_mat_
+  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem *mf_data,
+   const VECT &A, const mesh_region &rg, const char *assembly_description,
+   std::complex<T>) {
+    asm_real_or_complex_1_param_mat_(gmm::real_part(M),mim,mf_u,mf_data,
+    				     gmm::real_part(A),rg,
+    				     assembly_description, T());
+    asm_real_or_complex_1_param_mat_(gmm::imag_part(M),mim,mf_u,mf_data,
+    				     gmm::imag_part(A),rg,
+    				     assembly_description, T());
+  }
+
+  /*
+    assembly of a vector with 1 parameter (real or complex)
+    (the most common here for the assembly routines below)
+  */
+  template <typename MAT, typename VECT>
+  inline void asm_real_or_complex_1_param_vec
+  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem *mf_data,
+   const VECT &A, const mesh_region &rg, const char *assembly_description) {
+    asm_real_or_complex_1_param_vec_
+      (M, mim, mf_u, mf_data, A, rg, assembly_description,
+       typename gmm::linalg_traits<VECT>::value_type());
+  }
+
+  /* real version */
+  template<typename VECTA, typename VECT, typename T>
+  inline void asm_real_or_complex_1_param_vec_
+  (const VECTA &V, const mesh_im &mim,  const mesh_fem &mf_u,
+   const mesh_fem *mf_data, const VECT &A,  const mesh_region &rg,
+   const char *assembly_description, T) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf_u.nb_dof());
+    base_vector u(mf_u.nb_dof()), AA(gmm::vect_size(A));
+    gmm::copy(A, AA);
+    workspace.add_fem_variable("u", mf_u, Iu, u);
+    if (mf_data)
+      workspace.add_fem_constant("A", *mf_data, AA);
+    else
+      workspace.add_fixed_size_constant("A", AA);
+    workspace.add_expression(assembly_description, mim, rg);
+    workspace.assembly(1);
+    if (gmm::vect_size(workspace.assembled_vector()))
+	gmm::add(workspace.assembled_vector(), const_cast<VECTA &>(V));
+  }
+
+  inline void asm_real_or_complex_1_param_vec_
+  (model_real_plain_vector &V, const mesh_im &mim,  const mesh_fem &mf_u,
+   const mesh_fem *mf_data, const model_real_plain_vector &A,
+   const mesh_region &rg,
+   const char *assembly_description, scalar_type) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf_u.nb_dof());
+    base_vector u(mf_u.nb_dof());
+    workspace.add_fem_variable("u", mf_u, Iu, u);
+    if (mf_data)
+      workspace.add_fem_constant("A", *mf_data, A);
+    else
+      workspace.add_fixed_size_constant("A", A);
+    workspace.add_expression(assembly_description, mim, rg);
+    workspace.set_assembled_vector(V);
+    workspace.assembly(1);
   }
 
+  /* complex version */
+  template<typename MAT, typename VECT, typename T>
+  inline void asm_real_or_complex_1_param_vec_
+  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem *mf_data,
+   const VECT &A, const mesh_region &rg,const char *assembly_description,
+   std::complex<T>) {
+    asm_real_or_complex_1_param_vec_(gmm::real_part(M),mim,mf_u,mf_data,
+				     gmm::real_part(A),rg,
+				     assembly_description, T());
+    asm_real_or_complex_1_param_vec_(gmm::imag_part(M),mim,mf_u,mf_data,
+				     gmm::imag_part(A),rg,
+				     assembly_description, T());
+  }
+ 
   /** 
       generic mass matrix assembly (on the whole mesh or on the specified
       convex set or boundary) 
       @ingroup asm
   */
   template<typename MAT>
-  void asm_mass_matrix(const MAT &M, const mesh_im &mim,
-		       const mesh_fem &mf_u1,
-		       const mesh_region &rg = mesh_region::all_convexes()) {
-    generic_assembly assem;
-    if (mf_u1.get_qdim() == 1)
-      assem.set("M(#1,#1)+=sym(comp(Base(#1).Base(#1)))");
-    else
-      assem.set("M(#1,#1)+=sym(comp(vBase(#1).vBase(#1))(:,i,:,i));");
-    assem.push_mi(mim);
-    assem.push_mf(mf_u1);
-    assem.push_mat(const_cast<MAT &>(M));
-    assem.assembly(rg);
+  inline void asm_mass_matrix
+  (const MAT &M, const mesh_im &mim, const mesh_fem &mf1,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof());
+    base_vector u1(mf1.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, u1);
+    workspace.add_expression("Test_u1.Test2_u1", mim, rg);
+    workspace.assembly(2);
+    if (gmm::mat_nrows(workspace.assembled_matrix()))
+	gmm::add(workspace.assembled_matrix(), const_cast<MAT &>(M));
+  }
+
+  inline void asm_mass_matrix
+  (model_real_sparse_matrix &M, const mesh_im &mim,
+   const mesh_fem &mf1,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof());
+    base_vector u1(mf1.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, u1);
+    workspace.add_expression("Test_u1.Test2_u1", mim, rg);
+    workspace.set_assembled_matrix(M);
+    workspace.assembly(2);
   }
 
   /** 
    *  generic mass matrix assembly (on the whole mesh or on the specified
    *  boundary) 
    */
+
   template<typename MAT>
-  void asm_mass_matrix(const MAT &M, const mesh_im &mim, const mesh_fem &mf_u1,
-		       const mesh_fem &mf_u2,
-		       const mesh_region &rg = mesh_region::all_convexes()) {
-    generic_assembly assem;
-    if (mf_u1.get_qdim() == 1 && mf_u2.get_qdim() == 1)
-      assem.set("M(#1,#2)+=comp(Base(#1).Base(#2))");
-    else if (mf_u1.get_qdim() == 1)
-      assem.set("M(#1,#2)+=comp(Base(#1).vBase(#2))(:,:,1);"); // could be i in place of 1
-    else if (mf_u2.get_qdim() == 1)
-      assem.set("M(#1,#2)+=comp(vBase(#1).Base(#2))(:,1,:);");
-    else
-      assem.set("M(#1,#2)+=comp(vBase(#1).vBase(#2))(:,i,:,i);");
-    assem.push_mi(mim);
-    assem.push_mf(mf_u1);
-    assem.push_mf(mf_u2);
-    assem.push_mat(const_cast<MAT &>(M));
-    assem.assembly(rg);
+  inline void asm_mass_matrix
+  (const MAT &M, const mesh_im &mim, const mesh_fem &mf1, const mesh_fem &mf2,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(Iu1.last(), mf2.nb_dof());
+    base_vector u1(mf1.nb_dof()), u2(mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, u1);
+    workspace.add_fem_variable("u2", mf2, Iu2, u2);
+    workspace.add_expression("Test_u1.Test2_u2", mim, rg);
+    workspace.assembly(2);
+    if (gmm::mat_nrows(workspace.assembled_matrix()))
+	gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Iu1, Iu2),
+		 const_cast<MAT &>(M));
   }
+  
+  inline void asm_mass_matrix
+  (model_real_sparse_matrix &M, const mesh_im &mim,
+   const mesh_fem &mf1, const mesh_fem &mf2,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(0, mf2.nb_dof());
+    base_vector u1(mf1.nb_dof()), u2(mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, u1);
+    workspace.add_fem_variable("u2", mf2, Iu2, u2);
+    workspace.add_expression("Test_u1.Test2_u2", mim, rg);
+    workspace.set_assembled_matrix(M);
+    workspace.assembly(2);
+  }
+
+  /**
+     generic mass matrix assembly with an additional parameter
+     (on the whole mesh or on the specified boundary) 
+     @ingroup asm
+  */
+  template<typename MAT, typename VECT>
+  inline void asm_mass_matrix_param
+  (const MAT &M, const mesh_im &mim, const mesh_fem &mf1, const mesh_fem &mf2,
+   const mesh_fem &mf_data, const VECT &A,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(Iu1.last(), mf2.nb_dof());
+    base_vector u1(mf1.nb_dof()), u2(mf2.nb_dof()), AA(mf_data.nb_dof());
+    gmm::copy(A, AA);
+    workspace.add_fem_variable("u1", mf1, Iu1, u1);
+    workspace.add_fem_variable("u2", mf2, Iu2, u2);
+    workspace.add_fem_constant("A", mf_data, AA);
+    workspace.add_expression("(A*Test_u1).Test2_u2", mim, rg);
+    workspace.assembly(2);
+    if (gmm::mat_nrows(workspace.assembled_matrix()))
+	gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Iu1, Iu2),
+		 const_cast<MAT &>(M));
+  }
+
+  inline void asm_mass_matrix_param
+  (model_real_sparse_matrix &M, const mesh_im &mim,
+   const mesh_fem &mf1, const mesh_fem &mf2,
+   const mesh_fem &mf_data, const model_real_plain_vector &A,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+
+    ga_workspace workspace;
+    gmm::sub_interval Iu1(0, mf1.nb_dof()), Iu2(0, mf2.nb_dof());
+    base_vector u1(mf1.nb_dof()), u2(mf2.nb_dof());
+    workspace.add_fem_variable("u1", mf1, Iu1, u1);
+    workspace.add_fem_variable("u2", mf2, Iu2, u2);
+    workspace.add_fem_constant("A", mf_data, A);
+    workspace.add_expression("(A*Test_u1).Test2_u2", mim, rg);
+    workspace.set_assembled_matrix(M);
+    workspace.assembly(2);
+  }
+    
+
 
   /** 
      generic mass matrix assembly with an additional parameter
@@ -439,40 +808,23 @@ namespace getfem {
   void asm_mass_matrix_param
   (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_data,
    const VECT &F, const mesh_region &rg = mesh_region::all_convexes()) {
-    asm_real_or_complex_1_param
-      (M, mim, mf_u, mf_data, F, rg, (mf_u.get_qdim() == 1) ? 
-       "F=data(#2);"
-       "M(#1,#1)+=sym(comp(Base(#1).Base(#1).Base(#2))(:,:,i).F(i))"
-       : "F=data(#2);"
-       "M(#1,#1)+=sym(comp(vBase(#1).vBase(#1).Base(#2))(:,i,:,i,j).F(j));");
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf_u, &mf_data, F, rg, "(A*Test_u):Test2_u");
   }
-
-
+    
   /** 
-     generic mass matrix assembly with an additional parameter
+     generic mass matrix assembly with an additional constant parameter
      (on the whole mesh or on the specified boundary) 
      @ingroup asm
    */
   template<typename MAT, typename VECT>
-  void asm_mass_matrix_param
-  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u1, const mesh_fem &mf_u2,
-   const mesh_fem &mf_data, const VECT &F,
-   const mesh_region &rg = mesh_region::all_convexes()) {
-    generic_assembly assem;
-    if (mf_u1.get_qdim() == 1 && mf_u2.get_qdim() == 1)
-      assem.set("F=data(#3);M(#1,#2)+=comp(Base(#1).Base(#2).Base(#3))(:,:,i).F(i)");
-    else
-      assem.set("F=data(#3);M(#1,#2)+=comp(vBase(#1).vBase(#2).Base(#3))(:,i,:,i,j).F(j);");
-    assem.push_mi(mim);
-    assem.push_mf(mf_u1);
-    assem.push_mf(mf_u2);
-    assem.push_mf(mf_data);
-    assem.push_mat(const_cast<MAT &>(M));
-    assem.push_data(F);
-    assem.assembly(rg);
+  void asm_mass_matrix_homogeneous_param
+  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u,
+   const VECT &F, const mesh_region &rg = mesh_region::all_convexes()) {
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf_u, 0, F, rg, "(A*Test_u):Test2_u");
   }
 
-    
   /** 
       source term (for both volumic sources and boundary (Neumann) sources).
       @ingroup asm
@@ -484,18 +836,8 @@ namespace getfem {
     GMM_ASSERT1(mf_data.get_qdim() == 1 ||
 		mf_data.get_qdim() == mf.get_qdim(),
 		"invalid data mesh fem (same Qdim or Qdim=1 required)");
-
-    const char *st;
-    if (mf.get_qdim() == 1)
-      st = "F=data(#2); V(#1)+=comp(Base(#1).Base(#2))(:,j).F(j);";
-    else if (mf_data.get_qdim() == 1)
-      st = "F=data(qdim(#1),#2);"
-	"V(#1)+=comp(vBase(#1).Base(#2))(:,i,j).F(i,j);";
-    else
-      st = "F=data(#2);"
-	"V(#1)+=comp(vBase(#1).vBase(#2))(:,i,j,i).F(j);";
-    
-    asm_real_or_complex_1_param(const_cast<VECT1 &>(B),mim,mf,mf_data,F,rg,st);
+    asm_real_or_complex_1_param_vec
+      (const_cast<VECT1 &>(B), mim, mf, &mf_data, F, rg, "A:Test_u");
   }
 
   /** 
@@ -507,16 +849,10 @@ namespace getfem {
   void asm_homogeneous_source_term(const VECT1 &B, const mesh_im &mim,
 				   const mesh_fem &mf, const VECT2 &F,
 		       const mesh_region &rg = mesh_region::all_convexes()) {
-    const char *st;
-    if (mf.get_qdim() == 1)
-      st = "F=data(1); V(#1)+=comp(Base(#1))(:).F(i);";
-    else
-      st = "F=data(qdim(#1)); V(#1)+=comp(vBase(#1))(:,i).F(i);";
-    
-    asm_real_or_complex_1_param(const_cast<VECT1 &>(B),mim,mf,mf,F,rg,st);
+    asm_real_or_complex_1_param_vec
+      (const_cast<VECT1 &>(B), mim, mf, 0, F, rg, "A:Test_u");
   }
 
-
   /** 
       Normal source term (for boundary (Neumann) condition).
       @ingroup asm
@@ -526,22 +862,8 @@ namespace getfem {
 			      const mesh_fem &mf,
 			      const mesh_fem &mf_data, const VECT2 &F,
 			      const mesh_region &rg) {
-    GMM_ASSERT1(mf_data.get_qdim() == 1 ||
-		mf_data.get_qdim() == mf.get_qdim(),
-		"invalid data mesh_fem (same Qdim or Qdim=1 required)");
-
-    const char *st;
-    if (mf.get_qdim() == 1)
-      st = "F=data(mdim(#1),#2);"
-	"V(#1)+=comp(Base(#1).Base(#2).Normal())(:,j,k).F(k,j);";
-    else if (mf_data.get_qdim() == 1)
-      st = "F=data(qdim(#1),mdim(#1),#2);"
-	"V(#1)+=comp(vBase(#1).Base(#2).Normal())(:,i,j,k).F(i,k,j);";
-    else
-      st = "F=data(mdim(#1),#2);"
-	"V(#1)+=comp(vBase(#1).vBase(#2).Normal())(:,i,j,i,k).F(k,j);";
-
-    asm_real_or_complex_1_param(B, mim, mf, mf_data, F, rg, st);
+    asm_real_or_complex_1_param_vec(B, mim, mf, &mf_data, F, rg,
+             		  "(Reshape(A, qdim(u), meshdim).Normal):Test_u");
   }
 
   /** 
@@ -549,33 +871,11 @@ namespace getfem {
       @ingroup asm
    */
   template<typename VECT1, typename VECT2>
-  void asm_homogeneous_normal_source_term(VECT1 &B, const mesh_im &mim,
-					  const mesh_fem &mf,
-					  const VECT2 &F,
-					  const mesh_region &rg) {
-    const char *st;
-    if (mf.get_qdim() == 1)
-      st = "F=data(mdim(#1));"
-	"V(#1)+=comp(Base(#1).Normal())(:,k).F(k);";
-    else
-      st = "F=data(qdim(#1),mdim(#1));"
-	"V(#1)+=comp(vBase(#1).Normal())(:,i,j).F(i,j);";
-
-    asm_real_or_complex_1_param(B, mim, mf, mf, F, rg, st);
-  }
-
-  template <typename V> bool is_Q_symmetric(const V& Q, size_type q,
-					    size_type nbd) {
-    /* detect the symmetricity of Q (in that case the symmetricity of
-     * the final matrix will be ensured, and computations will be
-     * slightly speed up */
-    for (size_type k=0; k < nbd; ++k)
-      for (size_type i=1; i < q; ++i)
-	for (size_type j=0; j < i; ++j)
-	  if (Q[k*q*q+i*q+j] != Q[k*q*q+j*q+i])
-	    return false;
-    return true;
-  }
+  void asm_homogeneous_normal_source_term
+  (VECT1 &B, const mesh_im &mim, const mesh_fem &mf, const VECT2 &F,
+   const mesh_region &rg)
+  { asm_real_or_complex_1_param_vec(B, mim, mf, 0,F,rg,
+			 "(Reshape(A, qdim(u), meshdim).Normal):Test_u"); }
 
   /**
      assembly of @f$\int{qu.v}@f$
@@ -600,81 +900,66 @@ namespace getfem {
   void asm_qu_term(MAT &M, const mesh_im &mim, const mesh_fem &mf_u, 
 		   const mesh_fem &mf_d, const VECT &Q, 
 		   const mesh_region &rg) {
-    generic_assembly assem;
-    GMM_ASSERT1(mf_d.get_qdim() == 1,
-		"invalid data mesh fem (Qdim=1 required)");
-    const char *asm_str = "";
-    if (mf_u.get_qdim() == 1)
-      asm_str = "Q=data$1(#2);"
-	"M(#1,#1)+=comp(Base(#1).Base(#1).Base(#2))(:,:,k).Q(k);";
-    else
-      if (is_Q_symmetric(Q,mf_u.get_qdim(),mf_d.nb_dof()))
-	asm_str = "Q=data$1(qdim(#1),qdim(#1),#2);"
-		  "M(#1,#1)+=sym(comp(vBase(#1).vBase(#1).Base(#2))"
-		  "(:,i,:,j,k).Q(i,j,k));";
-      else
-        asm_str = "Q=data$1(qdim(#1),qdim(#1),#2);"
-		  "M(#1,#1)+=comp(vBase(#1).vBase(#1).Base(#2))"
-		  "(:,i,:,j,k).Q(i,j,k);";
-    asm_real_or_complex_1_param(M, mim, mf_u, mf_d, Q, rg, asm_str);
+    if (mf_d.get_qdim() == 1 && gmm::vect_size(Q) > mf_d.nb_dof())
+      asm_real_or_complex_1_param_mat
+	(M, mim,mf_u,&mf_d,Q,rg,"(Reshape(A,qdim(u),qdim(u)).Test_u):Test2_u");
+    else if (mf_d.get_qdim() == mf_u.get_qdim())
+      asm_real_or_complex_1_param_mat
+	(M, mim, mf_u, &mf_d, Q, rg, "(A*Test_u):Test2_u");
+    else GMM_ASSERT1(false, "invalid data mesh fem");
   }
 
   template<typename MAT, typename VECT>
   void asm_homogeneous_qu_term(MAT &M, const mesh_im &mim,
 			       const mesh_fem &mf_u, const VECT &Q, 
 			       const mesh_region &rg) {
-    generic_assembly assem;
-    const char *asm_str = "";
-    if (mf_u.get_qdim() == 1)
-      asm_str = "Q=data$1(1);"
-	"M(#1,#1)+=comp(Base(#1).Base(#1))(:,:).Q(i);";
+    if (gmm::vect_size(Q) == 1)
+      asm_real_or_complex_1_param_mat
+	(M, mim,mf_u,0,Q,rg,"(A*Test_u):Test2_u");
     else
-      if (is_Q_symmetric(Q,mf_u.get_qdim(),1))
-	asm_str = "Q=data$1(qdim(#1),qdim(#1));"
-		  "M(#1,#1)+=sym(comp(vBase(#1).vBase(#1))"
-		  "(:,i,:,j).Q(i,j));";
-      else
-        asm_str = "Q=data$1(qdim(#1),qdim(#1));"
-		  "M(#1,#1)+=comp(vBase(#1).vBase(#1))"
-		  "(:,i,:,j).Q(i,j);";
-    asm_real_or_complex_1_param(M, mim, mf_u, mf_u, Q, rg, asm_str);
+      asm_real_or_complex_1_param_mat
+	(M, mim,mf_u,0,Q,rg,"(Reshape(A,qdim(u),qdim(u)).Test_u):Test2_u");
   }
-
+  
   /** 
       Stiffness matrix for linear elasticity, with Lam� coefficients
       @ingroup asm
   */
   template<class MAT, class VECT>
-  void asm_stiffness_matrix_for_linear_elasticity
-  (const MAT &RM_, const mesh_im &mim, const mesh_fem &mf,
+  inline void asm_stiffness_matrix_for_linear_elasticity
+  (const MAT &M, const mesh_im &mim, const mesh_fem &mf,
    const mesh_fem &mf_data, const VECT &LAMBDA, const VECT &MU,
    const mesh_region &rg = mesh_region::all_convexes()) {
-    MAT &RM = const_cast<MAT &>(RM_);
-    GMM_ASSERT1(mf_data.get_qdim() == 1,
-		"invalid data mesh fem (Qdim=1 required)");
-    
-    GMM_ASSERT1(mf.get_qdim() == mf.linked_mesh().dim(),
-		"wrong qdim for the mesh_fem");
-    /* e = strain tensor,
-       M = 2*mu*e(u):e(v) + lambda*tr(e(u))*tr(e(v))
-    */
-    generic_assembly assem("lambda=data$1(#2); mu=data$2(#2);"
-			   "t=comp(vGrad(#1).vGrad(#1).Base(#2));"
-			   //"e=(t{:,2,3,:,5,6,:}+t{:,3,2,:,5,6,:}"
-			   //"+t{:,2,3,:,6,5,:}+t{:,3,2,:,6,5,:})/4;"
-			   //"e=(t{:,2,3,:,5,6,:}+t{:,3,2,:,5,6,:})*0.5;"
-			   /*"M(#1,#1)+= sym(2*e(:,i,j,:,i,j,k).mu(k)"
-                             " + e(:,i,i,:,j,j,k).lambda(k))");*/
-                           "M(#1,#1)+= sym(t(:,i,j,:,i,j,k).mu(k)"
-			   "+ t(:,j,i,:,i,j,k).mu(k)"
-			   "+ t(:,i,i,:,j,j,k).lambda(k))");
-    assem.push_mi(mim);
-    assem.push_mf(mf);
-    assem.push_mf(mf_data);
-    assem.push_data(LAMBDA);
-    assem.push_data(MU);
-    assem.push_mat(RM);
-    assem.assembly(rg);
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    base_vector u(mf.nb_dof()), lambda(gmm::vect_size(LAMBDA));
+    base_vector mu(gmm::vect_size(MU));
+    gmm::copy(LAMBDA, lambda); gmm::copy(MU, mu); 
+    workspace.add_fem_variable("u", mf, Iu, u);
+    workspace.add_fem_constant("lambda", mf_data, lambda);
+    workspace.add_fem_constant("mu", mf_data, mu);
+    workspace.add_expression("((lambda*Div_Test_u)*Id(meshdim)"
+    			     "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
+    workspace.assembly(2);
+    if (gmm::mat_nrows(workspace.assembled_matrix()))
+       gmm::add(workspace.assembled_matrix(), const_cast<MAT &>(M));
+  }
+
+  inline void asm_stiffness_matrix_for_linear_elasticity
+  (model_real_sparse_matrix &M, const mesh_im &mim, const mesh_fem &mf,
+   const mesh_fem &mf_data, const model_real_plain_vector &LAMBDA,
+   const model_real_plain_vector &MU,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    base_vector u(mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, u);
+    workspace.add_fem_constant("lambda", mf_data, LAMBDA);
+    workspace.add_fem_constant("mu", mf_data, MU);
+    workspace.add_expression("((lambda*Div_Test_u)*Id(meshdim)"
+    			     "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
+    workspace.set_assembled_matrix(M);
+    workspace.assembly(2);
   }
 
 
@@ -683,24 +968,40 @@ namespace getfem {
       @ingroup asm
   */
   template<class MAT, class VECT>
-  void asm_stiffness_matrix_for_homogeneous_linear_elasticity
-  (const MAT &RM_, const mesh_im &mim, const mesh_fem &mf,
+  inline void asm_stiffness_matrix_for_homogeneous_linear_elasticity
+  (const MAT &M, const mesh_im &mim, const mesh_fem &mf,
    const VECT &LAMBDA, const VECT &MU,
    const mesh_region &rg = mesh_region::all_convexes()) {
-    MAT &RM = const_cast<MAT &>(RM_);
-    GMM_ASSERT1(mf.get_qdim() == mf.linked_mesh().dim(),
-		"wrong qdim for the mesh_fem");
-    generic_assembly assem("lambda=data$1(1); mu=data$2(1);"
-			   "t=comp(vGrad(#1).vGrad(#1));"
-                           "M(#1,#1)+= sym(t(:,i,j,:,i,j).mu(1)"
-			   "+ t(:,j,i,:,i,j).mu(1)"
-			   "+ t(:,i,i,:,j,j).lambda(1))");
-    assem.push_mi(mim);
-    assem.push_mf(mf);
-    assem.push_data(LAMBDA);
-    assem.push_data(MU);
-    assem.push_mat(RM);
-    assem.assembly(rg);
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    base_vector u(mf.nb_dof()), lambda(gmm::vect_size(LAMBDA));
+    base_vector mu(gmm::vect_size(MU));
+    gmm::copy(LAMBDA, lambda); gmm::copy(MU, mu);
+    workspace.add_fem_variable("u", mf, Iu, u);
+    workspace.add_fixed_size_constant("lambda", lambda);
+    workspace.add_fixed_size_constant("mu", mu);
+    workspace.add_expression("((lambda*Div_Test_u)*Id(meshdim)"
+    			     "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
+    workspace.assembly(2);
+    if (gmm::mat_nrows(workspace.assembled_matrix()))
+      gmm::add(workspace.assembled_matrix(), const_cast<MAT &>(M));
+  }
+
+  
+  inline void asm_stiffness_matrix_for_homogeneous_linear_elasticity
+  (model_real_sparse_matrix &M, const mesh_im &mim, const mesh_fem &mf,
+   const model_real_plain_vector &LAMBDA, const model_real_plain_vector &MU,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    base_vector u(mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, u);
+    workspace.add_fixed_size_constant("lambda", LAMBDA);
+    workspace.add_fixed_size_constant("mu", MU);
+    workspace.add_expression("((lambda*Div_Test_u)*Id(meshdim)"
+    			     "+(2*mu)*Sym(Grad_Test_u)):Grad_Test2_u", mim, rg);
+    workspace.set_assembled_matrix(M);
+    workspace.assembly(2);
   }
 
   /** 
@@ -720,127 +1021,106 @@ namespace getfem {
     asm_stiffness_matrix_for_vector_elliptic(RM, mim, mf, mf_data, H, rg);
   }
 
-
-  /** two-in-one assembly of stokes equation:
-     linear elasticty part and p.div(v) term are assembled at the
-     same time. 
-
-     @ingroup asm
-   */
-  template<typename MAT, typename VECT>
-  void asm_stokes(MAT &K, MAT &BT, 
-		  const mesh_im &mim, 
-		  const mesh_fem &mf_u, const mesh_fem &mf_p,
-		  const mesh_fem &mf_d, const VECT &viscos,
-		  const mesh_region &rg = mesh_region::all_convexes()) {
-    GMM_ASSERT1(mf_d.get_qdim() == 1,
-		"invalid data mesh fem (Qdim=1 required)");
-    generic_assembly assem("visc=data$1(#3); "
-			   "t=comp(vGrad(#1).vGrad(#1).Base(#3));"
-			   "e=(t{:,2,3,:,5,6,:}+t{:,3,2,:,5,6,:}"
-			   "  +t{:,2,3,:,6,5,:}+t{:,3,2,:,6,5,:})/4;"
-			   // visc*D(u):D(v)
-			   "M$1(#1,#1)+=sym(e(:,i,j,:,i,j,k).visc(k));"
-			   // p.div v
-			   "M$2(#1,#2)+=comp(vGrad(#1).Base(#2))(:,i,i,:);");
-    assem.push_mi(mim);
-    assem.push_mf(mf_u);
-    assem.push_mf(mf_p);
-    assem.push_mf(mf_d);
-    assem.push_data(viscos);
-    assem.push_mat(K);
-    assem.push_mat(BT);
-    assem.assembly(rg);
-  }
-
   /**
      Build the mixed pressure term @f$ B = - \int p.div u @f$
 
      @ingroup asm
   */
-     
   template<typename MAT>
-  void asm_stokes_B(MAT &B, const mesh_im &mim, const mesh_fem &mf_u,
-		    const mesh_fem &mf_p, 
-		    const mesh_region &rg = mesh_region::all_convexes()) {
-    GMM_ASSERT1(mf_p.get_qdim() == 1,
-		"invalid data mesh fem (Qdim=1 required)");
-    //generic_assembly assem("M$1(#1,#2)+=comp(vGrad(#1).Base(#2))(:,i,i,:);");
-    generic_assembly assem("M$1(#1,#2)+=-comp(Base(#1).vGrad(#2))(:,:,i,i);");
-    assem.push_mi(mim);
-    assem.push_mf(mf_p);
-    assem.push_mf(mf_u);
-    assem.push_mat(B);
-    assem.assembly(rg);
+  inline void asm_stokes_B(const MAT &B, const mesh_im &mim,
+			   const mesh_fem &mf_u, const mesh_fem &mf_p, 
+			   const mesh_region &rg=mesh_region::all_convexes()) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf_u.nb_dof()), Ip(Iu.last(), mf_p.nb_dof());
+    base_vector u(mf_u.nb_dof()), p(mf_p.nb_dof());
+    workspace.add_fem_variable("u", mf_u, Iu, u);
+    workspace.add_fem_variable("p", mf_p, Ip, p);
+    workspace.add_expression("Test_p*Div_Test2_u", mim, rg);
+    workspace.assembly(2);
+    if (gmm::mat_nrows(workspace.assembled_matrix()))
+	gmm::add(gmm::sub_matrix(workspace.assembled_matrix(), Ip, Iu),
+		 const_cast<MAT &>(B));
   }
 
+  inline void asm_stokes_B(model_real_sparse_matrix &B, const mesh_im &mim,
+			   const mesh_fem &mf_u, const mesh_fem &mf_p, 
+			   const mesh_region &rg=mesh_region::all_convexes()) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf_u.nb_dof()), Ip(0, mf_p.nb_dof());
+    base_vector u(mf_u.nb_dof()), p(mf_p.nb_dof());
+    workspace.add_fem_variable("u", mf_u, Iu, u);
+    workspace.add_fem_variable("p", mf_p, Ip, p);
+    workspace.add_expression("Test_p*Div_Test2_u", mim, rg);
+    workspace.set_assembled_matrix(B);
+    workspace.assembly(2);
+  }
+  
+
   /**
      assembly of @f$\int_\Omega \nabla u.\nabla v at f$.
 
      @ingroup asm
    */
   template<typename MAT>
-  void asm_stiffness_matrix_for_homogeneous_laplacian
-  (const MAT &M_, const mesh_im &mim, const mesh_fem &mf,
+  inline void asm_stiffness_matrix_for_homogeneous_laplacian
+  (const MAT &M, const mesh_im &mim, const mesh_fem &mf,
    const mesh_region &rg = mesh_region::all_convexes()) {
-    MAT &M = const_cast<MAT &>(M_);
-    generic_assembly 
-      assem("M$1(#1,#1)+=sym(comp(Grad(#1).Grad(#1))(:,i,:,i))");
-    assem.push_mi(mim);
-    assem.push_mf(mf);
-    assem.push_mat(M);
-    assem.assembly(rg);
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    base_vector u(mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, u);
+    workspace.add_expression("Grad_Test_u:Grad_Test2_u", mim, rg);
+    workspace.assembly(2);
+    if (gmm::mat_nrows(workspace.assembled_matrix()))
+    	gmm::add(workspace.assembled_matrix(), const_cast<MAT &>(M));
   }
 
+  inline void asm_stiffness_matrix_for_homogeneous_laplacian
+  (model_real_sparse_matrix &M, const mesh_im &mim, const mesh_fem &mf,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    ga_workspace workspace;
+    gmm::sub_interval Iu(0, mf.nb_dof());
+    base_vector u(mf.nb_dof());
+    workspace.add_fem_variable("u", mf, Iu, u);
+    workspace.add_expression("Grad_Test_u:Grad_Test2_u", mim, rg);
+    workspace.set_assembled_matrix(M);
+    workspace.assembly(2);
+  }
 
   /**
      assembly of @f$\int_\Omega \nabla u.\nabla v at f$.
      @ingroup asm
    */
   template<typename MAT>
-  void asm_stiffness_matrix_for_homogeneous_laplacian_componentwise
-  (const MAT &M_, const mesh_im &mim, const mesh_fem &mf, 
+  inline void asm_stiffness_matrix_for_homogeneous_laplacian_componentwise
+  (const MAT &M, const mesh_im &mim, const mesh_fem &mf, 
    const mesh_region &rg = mesh_region::all_convexes()) {
-    MAT &M = const_cast<MAT &>(M_);
-     generic_assembly
-       assem("M$1(#1,#1)+="
-	     "sym(comp(vGrad(#1).vGrad(#1))(:,k,i,:,k,i))");
-    assem.push_mi(mim);
-    assem.push_mf(mf);
-    assem.push_mat(M);
-    assem.assembly(rg);
+    return asm_stiffness_matrix_for_homogeneous_laplacian(M, mim, mf, rg);
   }
 
   /**
      assembly of @f$\int_\Omega a(x)\nabla u.\nabla v at f$ , where @f$a(x)@f$
      is scalar.
      @ingroup asm
-   */
+  */
   template<typename MAT, typename VECT>
-  void asm_stiffness_matrix_for_laplacian
+  inline void asm_stiffness_matrix_for_laplacian
   (MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data,
    const VECT &A, const mesh_region &rg = mesh_region::all_convexes()) {
-    GMM_ASSERT1(mf_data.get_qdim() == 1, 
-		"invalid data mesh fem (Qdim=1 required)");
-    asm_real_or_complex_1_param
-      (M, mim, mf, mf_data, A, rg, "a=data$1(#2); M$1(#1,#1)+="
-       "sym(comp(Grad(#1).Grad(#1).Base(#2))(:,i,:,i,j).a(j))");
+    GMM_ASSERT1(mf_data.get_qdim() == 1
+		&& gmm::vect_size(A) == mf_data.nb_dof(), "invalid data");
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf, &mf_data, A, rg, "(A*Grad_Test_u):Grad_Test2_u");
   }
-  
-
 
   /** The same as getfem::asm_stiffness_matrix_for_laplacian , but on
       each component of mf when mf has a qdim > 1
   */
   template<typename MAT, typename VECT>
-  void asm_stiffness_matrix_for_laplacian_componentwise
+  inline void asm_stiffness_matrix_for_laplacian_componentwise
   (MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data,
    const VECT &A, const mesh_region &rg = mesh_region::all_convexes()) {
-    GMM_ASSERT1(mf_data.get_qdim() == 1,
-		"invalid data mesh fem (Qdim=1 required)");
-    asm_real_or_complex_1_param
-      (M, mim, mf, mf_data, A, rg, "a=data$1(#2); M$1(#1,#1)+="
-       "sym(comp(vGrad(#1).vGrad(#1).Base(#2))(:,k,i,:,k,i,j).a(j))");
+    asm_stiffness_matrix_for_laplacian(M, mim, mf, mf_data, A, rg);
   }
 
   /**
@@ -870,12 +1150,9 @@ namespace getfem {
   void asm_stiffness_matrix_for_scalar_elliptic
   (MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data,
    const VECT &A, const mesh_region &rg = mesh_region::all_convexes()) {
-    /*GMM_ASSERT1(mf_data.get_qdim() == 1,
-      "invalid data mesh fem (Qdim=1 required)");*/
-    asm_real_or_complex_1_param(M,mim,mf,mf_data,A,rg,
-				"a=data$1(mdim(#1),mdim(#1),#2);"
-				"M$1(#1,#1)+=comp(Grad(#1).Grad(#1).Base(#2))"
-				"(:,i,:,j,k).a(j,i,k)");
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf, &mf_data, A, rg,
+       "(Reshape(A,meshdim,meshdim)*Grad_Test_u):Grad_Test2_u");
   }
 
   /** The same but with a constant matrix
@@ -884,12 +1161,9 @@ namespace getfem {
   void asm_stiffness_matrix_for_homogeneous_scalar_elliptic
   (MAT &M, const mesh_im &mim, const mesh_fem &mf,
    const VECT &A, const mesh_region &rg = mesh_region::all_convexes()) {
-    /*GMM_ASSERT1(mf_data.get_qdim() == 1,
-      "invalid data mesh fem (Qdim=1 required)");*/
-    asm_real_or_complex_1_param(M,mim,mf,mf,A,rg,
-				"a=data$1(mdim(#1),mdim(#1));"
-				"M$1(#1,#1)+=comp(Grad(#1).Grad(#1))"
-				"(:,i,:,j).a(j,i)");
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf, 0, A, rg,
+       "(Reshape(A,meshdim,meshdim)*Grad_Test_u):Grad_Test2_u");
   }
 
   /** The same but on each component of mf when mf has a qdim > 1 
@@ -899,12 +1173,9 @@ namespace getfem {
   (MAT &M, const mesh_im &mim, const mesh_fem &mf,
    const mesh_fem &mf_data, const VECT &A, 
    const mesh_region &rg = mesh_region::all_convexes()) {
-    /* GMM_ASSERT1(mf_data.get_qdim() == 1,
-       "invalid data mesh fem (Qdim=1 required)");*/
-    asm_real_or_complex_1_param
-      (M,mim,mf,mf_data,A,rg, "a=data$1(mdim(#1),mdim(#1),#2);"
-       "M$1(#1,#1)+=comp(vGrad(#1).vGrad(#1).Base(#2))"
-       "(:,l,i,:,l,j,k).a(j,i,k)");
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf, &mf_data, A, rg,
+       "(Grad_Test_u*(Reshape(A,meshdim,meshdim)')):Grad_Test2_u");
   }
 
   /** The same but with a constant matrix 
@@ -913,55 +1184,40 @@ namespace getfem {
   void asm_stiffness_matrix_for_homogeneous_scalar_elliptic_componentwise
   (MAT &M, const mesh_im &mim, const mesh_fem &mf, const VECT &A, 
    const mesh_region &rg = mesh_region::all_convexes()) {
-    /* GMM_ASSERT1(mf_data.get_qdim() == 1,
-       "invalid data mesh fem (Qdim=1 required)");*/
-    asm_real_or_complex_1_param
-      (M,mim,mf,mf,A,rg, "a=data$1(mdim(#1),mdim(#1));"
-       "M$1(#1,#1)+=comp(vGrad(#1).vGrad(#1))"
-       "(:,l,i,:,l,j).a(j,i)");
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf, 0, A, rg,
+       "(Grad_Test_u*(Reshape(A,meshdim,meshdim)')):Grad_Test2_u");
   }
 
 
   /**
      Assembly of @f$\int_\Omega A(x)\nabla u.\nabla v at f$, where @f$A(x)@f$
-     is a NxNxNxN (symmetric positive definite) tensor defined on mf_data.
+     is a NxNxQxQ (symmetric positive definite) tensor defined on mf_data.
   */
   template<typename MAT, typename VECT> void
   asm_stiffness_matrix_for_vector_elliptic
   (MAT &M, const mesh_im &mim, const mesh_fem &mf, const mesh_fem &mf_data, 
    const VECT &A, const mesh_region &rg = mesh_region::all_convexes()) {
-    /* GMM_ASSERT1(mf_data.get_qdim() == 1,
-       "invalid data mesh fem (Qdim=1 required)");*/
-    /* 
-       M = a_{i,j,k,l}D_{i,j}(u)D_{k,l}(v)
-    */
-    asm_real_or_complex_1_param
-      (M,mim,mf,mf_data,A,rg, 
-       "a=data$1(qdim(#1),mdim(#1),qdim(#1),mdim(#1),#2);"
-       "t=comp(vGrad(#1).vGrad(#1).Base(#2));"
-       "M(#1,#1)+= t(:,i,j,:,k,l,p).a(i,j,k,l,p)");
+   /* M = a_{i,j,k,l}D_{i,j}(u)D_{k,l}(v) */
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf, &mf_data, A, rg,
+       "(Reshape(A,qdim(u),meshdim,qdim(u),meshdim):Grad_Test_u):Grad_Test2_u");
   }
 
   /**
      Assembly of @f$\int_\Omega A(x)\nabla u.\nabla v at f$, where @f$A(x)@f$
-     is a NxNxNxN (symmetric positive definite) constant tensor.
+     is a NxNxQxQ (symmetric positive definite) constant tensor.
   */
   template<typename MAT, typename VECT> void
   asm_stiffness_matrix_for_homogeneous_vector_elliptic
   (MAT &M, const mesh_im &mim, const mesh_fem &mf,
    const VECT &A, const mesh_region &rg = mesh_region::all_convexes()) {
-    /* 
-       M = a_{i,j,k,l}D_{i,j}(u)D_{k,l}(v)
-    */
-    asm_real_or_complex_1_param
-      (M,mim,mf,mf,A,rg, 
-       "a=data$1(qdim(#1),mdim(#1),qdim(#1),mdim(#1));"
-       "t=comp(vGrad(#1).vGrad(#1));"
-       "M(#1,#1)+= t(:,i,j,:,k,l).a(i,j,k,l)");
+    /* M = a_{i,j,k,l}D_{i,j}(u)D_{k,l}(v) */
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf, 0, A, rg,
+       "(Reshape(A,qdim(u),meshdim,qdim(u),meshdim):Grad_Test_u):Grad_Test2_u");
   }
 
-
-
   /** 
       assembly of the term @f$\int_\Omega Kuv - \nabla u.\nabla v at f$, 
       for the helmholtz equation (@f$\Delta u + k^2u = 0 at f$, with @f$K=k^2 at f$).
@@ -974,64 +1230,62 @@ namespace getfem {
   void asm_Helmholtz(MAT &M, const mesh_im &mim, const mesh_fem &mf_u,
 		     const mesh_fem &mf_data, const VECT &K_squared, 
 		     const mesh_region &rg = mesh_region::all_convexes()) {
-    asm_Helmholtz(M, mim, mf_u, mf_data, K_squared,rg,
-		  typename gmm::linalg_traits<VECT>::value_type());
+    typedef typename gmm::linalg_traits<MAT>::value_type T;
+    asm_Helmholtz_(M, mim, mf_u, &mf_data, K_squared, rg, T());
   }
 
   template<typename MAT, typename VECT, typename T>
-  void asm_Helmholtz(MAT &M, const mesh_im &mim, const mesh_fem &mf_u,
-		     const mesh_fem &mf_data,
-		     const VECT &K_squared, const mesh_region &rg, T) {
-    asm_Helmholtz_real(M, mim, mf_u, mf_data, K_squared, rg);
+  void asm_Helmholtz_(MAT &M, const mesh_im &mim, const mesh_fem &mf_u,
+		      const mesh_fem *mf_data, const VECT &K_squared, 
+		      const mesh_region &rg, T) {
+    asm_real_or_complex_1_param_mat
+      (M, mim, mf_u, mf_data, K_squared, rg,
+       "(A*Test_u).Test2_u - Grad_Test_u:Grad_Test2_u");
   }
 
   template<typename MAT, typename VECT, typename T>
-  void asm_Helmholtz(MAT &M, const mesh_im &mim, const mesh_fem &mf_u,
-		     const mesh_fem &mf_data, const VECT &K_squared,
-		     const mesh_region &rg, std::complex<T>) {
-    asm_Helmholtz_cplx(gmm::real_part(M), gmm::imag_part(M), mim, mf_u,
-		       mf_data, gmm::real_part(K_squared),
-		       gmm::imag_part(K_squared), rg);
-  }
-
-
-  template<typename MATr, typename MATi, typename VECTr, typename VECTi>  
-  void asm_Helmholtz_cplx(const MATr &Mr, const MATi &Mi, const mesh_im &mim,
-			  const mesh_fem &mf_u, const mesh_fem &mf_data,
-			  const VECTr &K_squaredr, const VECTi &K_squaredi, 
-			  const mesh_region &rg=mesh_region::all_convexes()) {
-    generic_assembly assem("Kr=data$1(#2); Ki=data$2(#2);"
-			   "m = comp(Base(#1).Base(#1).Base(#2)); "
-			   "M$1(#1,#1)+=sym(m(:,:,i).Kr(i) - "
-			   "comp(Grad(#1).Grad(#1))(:,i,:,i));"
-			   "M$2(#1,#1)+=sym(m(:,:,i).Ki(i));");
-    assem.push_mi(mim);
-    assem.push_mf(mf_u);
-    assem.push_mf(mf_data);
-    assem.push_data(K_squaredr); //gmm::real_part(K_squared));
-    assem.push_data(K_squaredi); //gmm::imag_part(K_squared));
-    assem.push_mat(const_cast<MATr&>(Mr));
-    assem.push_mat(const_cast<MATi&>(Mi));
-    assem.assembly(rg);
-  }
-
-  template<typename MAT, typename VECT>  
-  void asm_Helmholtz_real(const MAT &M, const mesh_im &mim,
-			  const mesh_fem &mf_u, const mesh_fem &mf_data,
-			  const VECT &K_squared, 
-			  const mesh_region &rg=mesh_region::all_convexes()) {
-    generic_assembly assem("K=data$1(#2);"
-			   "m = comp(Base(#1).Base(#1).Base(#2)); "
-			   "M$1(#1,#1)+=sym(m(:,:,i).K(i) - "
-			   "comp(Grad(#1).Grad(#1))(:,i,:,i));");
-    assem.push_mi(mim);
-    assem.push_mf(mf_u);
-    assem.push_mf(mf_data);
-    assem.push_data(K_squared);
-    assem.push_mat(const_cast<MAT&>(M));
-    assem.assembly(rg);
-  }
+  void asm_Helmholtz_(MAT &M, const mesh_im &mim, const mesh_fem &mf_u,
+		     const mesh_fem *mf_data, const VECT &K_squared, 
+		      const mesh_region &rg, std::complex<T>) {
+    // asm_real_or_complex_1_param_mat
+    //   (M, mim, mf_u, &mf_data, gmm::real_part(K_squared), rg,
+    //    "(A*Test_u).Test2_u - Grad_Test_u:Grad_Test2_u");
+    // asm_real_or_complex_1_param_mat
+    //   (M, mim, mf_u, &mf_data, gmm::imag_part(K_squared), rg,
+    //    "(A*Test_u).Test2_u");
+
+
+    ga_workspace workspace;
+    gmm::sub_interval Iur(0, mf_u.nb_dof()), Iui(Iur.last(), mf_u.nb_dof());
+    base_vector u(mf_u.nb_dof());
+    base_vector AR(gmm::vect_size(K_squared)), AI(gmm::vect_size(K_squared));
+    gmm::copy(gmm::real_part(K_squared), AR);
+    gmm::copy(gmm::imag_part(K_squared), AI);
+    workspace.add_fem_variable("u", mf_u, Iur, u);
+    workspace.add_fem_variable("ui", mf_u, Iui, u);
+
+    if (mf_data) {
+      workspace.add_fem_constant("A",  *mf_data, AR);
+      workspace.add_fem_constant("AI", *mf_data, AI);
+    } else {
+      workspace.add_fixed_size_constant("A",  AR);
+      workspace.add_fixed_size_constant("AI", AI);
+    }
+    workspace.add_expression("(A*Test_u).Test2_u - Grad_Test_u:Grad_Test2_u",
+			     mim, rg);
+    workspace.add_expression("(AI*Test_ui).Test2_ui", mim, rg);
+    workspace.assembly(2);
+    
+    if (gmm::mat_nrows(workspace.assembled_matrix()))
+      gmm::add(gmm::sub_matrix(workspace.assembled_matrix(),Iur,Iur),
+    	       const_cast<MAT &>(M));
+    if (gmm::mat_nrows(workspace.assembled_matrix()) > mf_u.nb_dof())
+      gmm::add(gmm::sub_matrix(workspace.assembled_matrix(),Iui,Iui),
+    	       gmm::imag_part(const_cast<MAT &>(M)));
+      
+
 
+  }
 
   /** 
       assembly of the term @f$\int_\Omega Kuv - \nabla u.\nabla v at f$, 
@@ -1045,65 +1299,8 @@ namespace getfem {
   void asm_homogeneous_Helmholtz
   (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const VECT &K_squared, 
    const mesh_region &rg = mesh_region::all_convexes()) {
-    asm_homogeneous_Helmholtz(M, mim, mf_u, K_squared, rg,
-		  typename gmm::linalg_traits<VECT>::value_type());
-  }
-
-  template<typename MAT, typename VECT, typename T>
-  void asm_homogeneous_Helmholtz(MAT &M, const mesh_im &mim,
-				 const mesh_fem &mf_u,
-				 const VECT &K_squared,
-				 const mesh_region &rg, T) {
-    asm_homogeneous_Helmholtz_real(M, mim, mf_u, K_squared, rg);
-  }
-
-  template<typename MAT, typename VECT, typename T>
-  void asm_homogeneous_Helmholtz(MAT &M, const mesh_im &mim,
-				 const mesh_fem &mf_u,
-				 const VECT &K_squared,
-				 const mesh_region &rg, std::complex<T>) {
-    asm_homogeneous_Helmholtz_cplx(gmm::real_part(M),
-				   gmm::imag_part(M), mim, mf_u,
-				   gmm::real_part(K_squared),
-				   gmm::imag_part(K_squared), rg);
-  }
-
-
-  template<typename MATr, typename MATi, typename VECTr, typename VECTi>  
-  void asm_homogeneous_Helmholtz_cplx(const MATr &Mr, const MATi &Mi,
-				      const mesh_im &mim,
-				      const mesh_fem &mf_u,
-				      const VECTr &K_squaredr,
-				      const VECTi &K_squaredi, 
-				      const mesh_region &rg) {
-    generic_assembly assem("Kr=data$1(1); Ki=data$2(1);"
-			   "m = comp(Base(#1).Base(#1)); "
-			   "M$1(#1,#1)+=sym(m(:,:).Kr(j) - "
-			   "comp(Grad(#1).Grad(#1))(:,i,:,i));"
-			   "M$2(#1,#1)+=sym(m(:,:).Ki(j));");
-    assem.push_mi(mim);
-    assem.push_mf(mf_u);
-    assem.push_data(K_squaredr);
-    assem.push_data(K_squaredi);
-    assem.push_mat(const_cast<MATr&>(Mr));
-    assem.push_mat(const_cast<MATi&>(Mi));
-    assem.assembly(rg);
-  }
-
-  template<typename MAT, typename VECT>  
-  void asm_homogeneous_Helmholtz_real(const MAT &M, const mesh_im &mim,
-				      const mesh_fem &mf_u,
-				      const VECT &K_squared, 
-				      const mesh_region &rg) {
-    generic_assembly assem("K=data(1);"
-			   "m = comp(Base(#1).Base(#1)); "
-			   "M$1(#1,#1)+=sym(m(:,:).K(j) - "
-			   "comp(Grad(#1).Grad(#1))(:,i,:,i));");
-    assem.push_mi(mim);
-    assem.push_mf(mf_u);
-    assem.push_data(K_squared);
-    assem.push_mat(const_cast<MAT&>(M));
-    assem.assembly(rg);
+    typedef typename gmm::linalg_traits<MAT>::value_type T;
+    asm_Helmholtz_(M, mim, mf_u, 0, K_squared, rg, T());
   }
 
   enum { ASMDIR_BUILDH = 1, ASMDIR_BUILDR = 2, ASMDIR_SIMPLIFY = 4,
@@ -1134,7 +1331,7 @@ namespace getfem {
    const VECT2 &r_data, const mesh_region &region,
    int version =  ASMDIR_BUILDALL) {
     typedef typename gmm::linalg_traits<VECT1>::value_type value_type;
-    // typedef typename gmm::number_traits<value_type>::magnitude_type magn_type;
+    typedef typename gmm::number_traits<value_type>::magnitude_type magn_type;
 
     if ((version & ASMDIR_SIMPLIFY) &&
 	(mf_u.is_reduced() || mf_mult.is_reduced() || mf_r.is_reduced())) {
@@ -1147,14 +1344,12 @@ namespace getfem {
 		"invalid data mesh fem (Qdim=1 required)");
     if (version & ASMDIR_BUILDH) {
       asm_mass_matrix(H, mim, mf_mult, mf_u, region);
-//       gmm::clean(H, gmm::default_tol(magn_type()) // � remettre !
-// 		 * gmm::mat_maxnorm(H) * magn_type(1000));
+      gmm::clean(H, gmm::default_tol(magn_type())
+ 		 * gmm::mat_maxnorm(H) * magn_type(1000));
     }
     if (version & ASMDIR_BUILDR)
       asm_source_term(R, mim, mf_mult, mf_r, r_data, region);
 
-    return; // � enlever !
-
     // Verifications and simplifications
 
     pfem pf_u, pf_r, pf_m;
@@ -1252,65 +1447,42 @@ namespace getfem {
     }
   }
 
-
-
-    /**
-     Assembly of Dirichlet constraints on the normal component of a
-     vector field: u(x)n = r(x) (where n is the outward unit normal)
-     in a weak form
-     @f[ \int_{\Gamma} (u(x)n)v(x) = \int_{\Gamma} r(x)v(x) \forall v at f],
-     where @f$ v @f$ is in the space of multipliers corresponding to
-     mf_mult.
-
-     size(r_data) = Q   * nb_dof(mf_rh) or Q * N * nb_dof(mf_rh);
-
-     In the case size(r_data) = Q * N * nb_dof(mf_rh), the right hand
-     side is @f[ \int_{\Gamma} (r(x).n(x))v(x) \forall v at f]
-
-     version = |ASMDIR_BUILDH : build H
-     |ASMDIR_BUILDR : build R
-     |ASMDIR_BUILDALL : do everything.
-
-     @ingroup asm
-  */
-
-  template<typename MAT, typename VECT1, typename VECT2>
-  void asm_normal_component_dirichlet_constraints
-  (MAT &H, VECT1 &R, const mesh_im &mim, const mesh_fem &mf_u,
-   const mesh_fem &mf_mult, const mesh_fem &mf_r,
-   const VECT2 &r_data, const mesh_region &region,
-   int version =  ASMDIR_BUILDALL) {
-    typedef typename gmm::linalg_traits<VECT1>::value_type value_type;
-    typedef typename gmm::number_traits<value_type>::magnitude_type magn_type;
-    size_type N = mf_u.linked_mesh().dim(), Q = mf_mult.get_qdim();
-    
-    region.from_mesh(mim.linked_mesh()).error_if_not_faces();
-    GMM_ASSERT1(mf_mult.get_qdim() == mf_u.get_qdim() / N,
-		"invalid mesh fem for the normal component Dirichlet "
-		"constraint (Qdim=" << mf_u.get_qdim() / N << " required)");
-    if (version & ASMDIR_BUILDH) {
-      generic_assembly assem;
-      if (Q == 1)
-	assem.set("M(#2,#1)+=comp(Base(#2).vBase(#1).Normal())(:,:,i,i);");
-      else
-	assem.set("M(#2,#1)+=comp(vBase(#2).mBase(#1).Normal())(:,i,:,i,j,j);");
-      assem.push_mi(mim);
-      assem.push_mf(mf_u);
-      assem.push_mf(mf_mult);
-      assem.push_mat(H);
-      assem.assembly(region);
-    }
-    if (version & ASMDIR_BUILDR) {
-      if (gmm::vect_size(r_data) == mf_r.nb_dof() * Q)
-	asm_source_term(R, mim, mf_mult, mf_r, r_data, region);
-      else if (gmm::vect_size(r_data) == mf_r.nb_dof() * Q * N)
-	asm_normal_source_term(R, mim, mf_mult, mf_r, r_data, region);
-      else GMM_ASSERT1(false, "Wrong size of data vector");
+  template<typename MATRM, typename VECT1, typename VECT2>
+  void assembling_Dirichlet_condition
+  (MATRM &RM, VECT1 &B, const getfem::mesh_fem &mf, size_type boundary,
+   const VECT2 &F) {
+    // Works only for Lagrange dofs.
+    size_type Q=mf.get_qdim();
+    GMM_ASSERT1(!(mf.is_reduced()), "This function is not adapted to "
+		"reduced finite element methods"); 
+    dal::bit_vector nndof = mf.basic_dof_on_region(boundary);
+    getfem::pfem pf1;
+    for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
+      pf1 = mf.fem_of_element(cv);
+      getfem::pdof_description ldof = getfem::lagrange_dof(pf1->dim());
+      size_type nbd = pf1->nb_dof(cv);
+      for (size_type i = 0; i < nbd; i++) {
+	size_type dof1 = mf.ind_basic_dof_of_element(cv)[i*Q];
+	if (nndof.is_in(dof1) && pf1->dof_types()[i] == ldof) {
+	  // cout << "dof : " << i << endl;
+	  for (size_type j = 0; j < nbd; j++) {
+	    size_type dof2 = mf.ind_basic_dof_of_element(cv)[j*Q];
+	    for (size_type k = 0; k < Q; ++k)
+	      for (size_type l = 0; l < Q; ++l) {
+		if (!(nndof.is_in(dof2)) &&
+		    getfem::dof_compatibility(pf1->dof_types()[j],
+					      getfem::lagrange_dof(pf1->dim())))
+		  B[dof2+k] -= RM(dof2+k, dof1+l) * F[dof1+l];
+		RM(dof2+k, dof1+l) = RM(dof1+l, dof2+k) = 0;
+	      }
+	  }
+	  for (size_type k = 0; k < Q; ++k)
+	    { RM(dof1+k, dof1+k) = 1; B[dof1+k] = F[dof1+k]; }
+	}
+      }
     }
-    gmm::clean(H, gmm::default_tol(magn_type())
-	       * gmm::mat_maxnorm(H) * magn_type(100));
   }
-
+  
   /**
      Assembly of generalized Dirichlet constraints h(x)u(x) = r(x),
      where h is a QxQ matrix field (Q == mf_u.get_qdim()), outputs a
@@ -1404,7 +1576,7 @@ namespace getfem {
 		< 1.0E-14) {
 	      /* the dof might be "duplicated" */
 	      for (size_type q = 0; q < Q; ++q) {
-		size_type dof_u = mf_u.ind_basic_dof_of_element(cv)[ind_u*Q + q];
+		size_type dof_u = mf_u.ind_basic_dof_of_element(cv)[ind_u*Q+q];
 		
 		/* "erase" the row */
 		if (version & ASMDIR_BUILDH)
@@ -1428,87 +1600,6 @@ namespace getfem {
     }
   }
 
-  /**
-     Faster (and simpler) assembly of simple Dirichlet conditions (
-     u(x) = F(x) on a boundary). 
-
-     @param mf should be Lagrangian.
-     @param boundary the boundary number.
-     @param F the dirichlet condition value.
-     @param RM,B are modified to enforce the Dirichlet condition. The
-     symmetry properties of RM are kept.
-
-     @ingroup asm
-  */
-  template<typename MATRM, typename VECT1, typename VECT2>
-  void assembling_Dirichlet_condition
-  (MATRM &RM, VECT1 &B, const mesh_fem &mf, size_type boundary,
-   const VECT2 &F) {
-    // Marche uniquement pour des ddl de lagrange.
-    size_type Q=mf.get_qdim();
-    GMM_ASSERT1(!(mf.is_reduced()), "This function is not adapted to "
-		"reduced finite element methods"); 
-    dal::bit_vector nndof = mf.basic_dof_on_region(boundary);
-    pfem pf1;
-    for (dal::bv_visitor cv(mf.convex_index()); !cv.finished(); ++cv) {
-      pf1 = mf.fem_of_element(cv);
-      pdof_description ldof = lagrange_dof(pf1->dim());
-      size_type nbd = pf1->nb_dof(cv);
-      for (size_type i = 0; i < nbd; i++) {
-	size_type dof1 = mf.ind_basic_dof_of_element(cv)[i*Q];
-	if (nndof.is_in(dof1) && pf1->dof_types()[i] == ldof) {
-	  // cout << "dof : " << i << endl;
-	  for (size_type j = 0; j < nbd; j++) {
-	    size_type dof2 = mf.ind_basic_dof_of_element(cv)[j*Q];
-	    for (size_type k = 0; k < Q; ++k)
-	      for (size_type l = 0; l < Q; ++l) {
-		if (!(nndof.is_in(dof2)) &&
-		    dof_compatibility(pf1->dof_types()[j],
-				      lagrange_dof(pf1->dim())))
-		  B[dof2+k] -= RM(dof2+k, dof1+l) * F[dof1+l];
-		RM(dof2+k, dof1+l) = RM(dof1+l, dof2+k) = 0;
-	      }
-	  }
-	  for (size_type k = 0; k < Q; ++k)
-	    { RM(dof1+k, dof1+k) = 1; B[dof1+k] = F[dof1+k]; }
-	}
-      }
-    }
-  }
-  
-  /* add a dirichlet condition on a single dof, modifiying the matrix
-     RM and the rhs B.  (keeping the symmetry properties) */
-  template<typename MATRM, typename VECT1>
-  void add_Dirichlet_dof(MATRM &RM, VECT1 &B,
-			 const mesh_fem &mf,
-			 size_type dof, 
-			 typename gmm::linalg_traits<MATRM>::value_type
-			 dof_val) {
-    size_type Q=mf.get_qdim();
-    const mesh::ind_cv_ct &dofcv = mf.convex_to_dof(dof);
-    pfem pf1;
-
-    for (mesh::ind_cv_ct::const_iterator it = dofcv.begin();
-	 it != dofcv.end(); ++it) {
-      pf1 = mf.fem_of_element(*it);
-      GMM_ASSERT1(pf1->target_dim() == 1, "sorry, to be done ... ");
-      size_type nbd = pf1->nb_dof(*it);
-      for (size_type i = 0; i < nbd * Q; i++) {
-	size_type dof1 = mf.ind_dof_of_element(*it)[i];
-	if (dof == dof1) {
-	  for (size_type j = 0; j < nbd * Q; j++) {
-	    size_type dof2 = mf.ind_dof_of_element(*it)[j];
-	    if (!(dof == dof2)) {
-	      B[dof2] -= RM(dof2, dof1) * dof_val;
-	      RM(dof2, dof1) = RM(dof1, dof2) = 0;
-	    }
-	  }
-	  RM(dof1, dof1) = 1; B[dof1] = dof_val;
-	}
-      }
-    }
-  }
-
   /** 
       Build an orthogonal basis of the kernel of H in NS, gives the
       solution of minimal norm of H*U = R in U0 and return the
@@ -1521,13 +1612,6 @@ namespace getfem {
   size_type Dirichlet_nullspace(const MAT1 &H, MAT2 &NS,
 				const VECT1 &R, VECT2 &U0) {
 
-    // To be finalized.
-    //  . In order to be used with any sparse matrix type
-    //  . transpose the result and give the effective dimension of the kernel
-    //  . Compute the ctes / H.
-    //  . Optimization (suppress temporary ...). 
-    //  . Verify sizes of data
-
     typedef typename gmm::linalg_traits<MAT1>::value_type T;
     typedef typename gmm::number_traits<T>::magnitude_type MAGT;
     typedef typename gmm::temporary_vector<MAT1>::vector_type TEMP_VECT;
diff --git a/src/getfem/getfem_assembling_tensors.h b/src/getfem/getfem_assembling_tensors.h
index 21239bd..1ec7dab 100644
--- a/src/getfem/getfem_assembling_tensors.h
+++ b/src/getfem/getfem_assembling_tensors.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Julien Pommier
+ Copyright (C) 2003-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -650,6 +650,7 @@ namespace getfem {
     void push_mf(const mesh_fem& mf_) { mftab.push_back(&mf_); }
     /// Add a new mesh_im
     void push_mi(const mesh_im& im_) { imtab.push_back(&im_); }
+    void push_im(const mesh_im& im_) { imtab.push_back(&im_); }
     /// Add a new non-linear term
     void push_nonlinear_term(pnonlinear_elem_term net) {
       innonlin.push_back(net);
diff --git a/src/getfem/getfem_config.h b/src/getfem/getfem_config.h
index 0b1f414..978c100 100644
--- a/src/getfem/getfem_config.h
+++ b/src/getfem/getfem_config.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -218,7 +218,7 @@ namespace getfem {
 
   using std::endl; using std::cout; using std::cerr;
   using std::ends; using std::cin;
-
+  using gmm::vref;
 
 #if GETFEM_PARA_LEVEL > 1
   template <typename T> inline T MPI_SUM_SCALAR(T a) {
diff --git a/src/getfem/getfem_contact_and_friction_common.h b/src/getfem/getfem_contact_and_friction_common.h
index 0eaadd5..29be271 100644
--- a/src/getfem/getfem_contact_and_friction_common.h
+++ b/src/getfem/getfem_contact_and_friction_common.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2011-2016 Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2011-2017 Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
@@ -38,7 +38,7 @@
 #ifndef GETFEM_CONTACT_AND_FRICTION_COMMON_H__
 #define GETFEM_CONTACT_AND_FRICTION_COMMON_H__
 
-#include "getfem_generic_assembly.h"
+#include "getfem_models.h"
 #include "getfem_assembling_tensors.h"
 #include "getfem/bgeot_rtree.h"
 #include <getfem/getfem_mesher.h>
@@ -801,6 +801,74 @@ namespace getfem {
   (ga_workspace &workspace, const std::string &transname,
    const std::string &expr, size_type N);
 
+  //=========================================================================
+  //
+  //  Projection Interpolate transformation
+  //
+  //=========================================================================
+
+  /** Add a projection interpolate transformation called 'transname' to a model
+      to be used by the generic assembly bricks.
+  */
+  void add_projection_transformation
+  (model &md, const std::string &transname, scalar_type release_distance);
+
+  /** Add a projection interpolate transformation called 'transname' to a
+      workspace to be used by the generic assembly bricks.
+  */
+  void add_projection_transformation
+  (ga_workspace &workspace, const std::string &transname,
+   scalar_type release_distance);
+
+  /** Add a master boundary with corresponding displacement variable
+      'dispname' on a specific boundary 'region' to an existing projection
+      interpolate transformation called 'transname'.
+  */
+  void add_master_contact_boundary_to_projection_transformation
+  (model &md, const std::string &transname,const mesh &m, 
+   const std::string &dispname, size_type region);
+  /** Add a master boundary with corresponding displacement variable
+      'dispname' on a specific boundary 'region' to an existing projection
+      interpolate transformation called 'transname'.
+  */
+  void add_master_contact_boundary_to_projection_transformation
+  (ga_workspace &workspace, const std::string &transname, const mesh &m, 
+   const std::string &dispname, size_type region);
+
+  /** Add a slave boundary with corresponding displacement variable
+      'dispname' on a specific boundary 'region' to an existing projection
+      interpolate transformation called 'transname'.
+  */
+  void add_slave_contact_boundary_to_projection_transformation
+  (model &md, const std::string &transname, const mesh &m, 
+   const std::string &dispname, size_type region);
+
+  /** Add a slave boundary with corresponding displacement variable
+      'dispname' on a specific boundary 'region' to an existing projection
+      interpolate transformation called 'transname'.
+  */
+  void add_slave_contact_boundary_to_projection_transformation
+  (ga_workspace &workspace, const std::string &transname, const mesh &m,
+   const std::string &dispname, size_type region);
+
+  /** Add a rigid obstacle whose geometry corresponds to the zero level-set
+      of the high-level generic assembly expression `expr`
+      to an existing projection interpolate transformation called 'transname'.
+      In `expr`, the current position is denoted `X` with components
+      `X(1), X(2), ...`. It is also allowed to use `x` instead of `X(1)`,
+      `y` instead of `X(2)`, `z` instead of `X(3)` and `w` instead of `X(4)`. 
+  */
+  void add_rigid_obstacle_to_projection_transformation
+  (model &md, const std::string &transname,
+   const std::string &expr, size_type N);
+
+  /** Add a rigid obstacle whose geometry corresponds to the zero level-set
+      of the high-level generic assembly expression 'expr'
+      to an existing projection interpolate transformation called 'transname'.
+  */
+  void add_rigid_obstacle_to_projection_transformation
+  (ga_workspace &workspace, const std::string &transname,
+   const std::string &expr, size_type N);
 }  /* end of namespace getfem.                                             */
 
 
diff --git a/src/getfem/getfem_contact_and_friction_integral.h b/src/getfem/getfem_contact_and_friction_integral.h
index 84bd745..60f9960 100644
--- a/src/getfem/getfem_contact_and_friction_integral.h
+++ b/src/getfem/getfem_contact_and_friction_integral.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2011-2016 Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2011-2017 Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_contact_and_friction_large_sliding.h b/src/getfem/getfem_contact_and_friction_large_sliding.h
index 725d651..26f12a0 100644
--- a/src/getfem/getfem_contact_and_friction_large_sliding.h
+++ b/src/getfem/getfem_contact_and_friction_large_sliding.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2013-2016 Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2013-2017 Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
@@ -122,6 +122,64 @@ namespace getfem {
    const std::string &dataname_alpha = std::string());
 
 
+  /** Adds a large sliding contact with friction brick to the model based on Nitsche's method.
+      This brick is able to deal with self-contact, contact between
+      several deformable bodies and contact with rigid obstacles.
+      It uses the high-level generic assembly. It adds to the model
+      a raytracing_interpolate_transformation object.
+      For each slave boundary a  material law should be defined as a function of the dispacement variable on this boundary.
+      The release distance should be determined with care
+      (generally a few times a mean element size, and less than the
+      thickness of the body). Initially, the brick is added with no contact
+      boundaries. The contact boundaries and rigid bodies are added with
+      special functions.
+  */
+  size_type add_Nitsche_large_sliding_contact_brick_raytracing
+  (model &md, bool is_unbiased, const std::string &Nitsche_param,
+   scalar_type release_distance, const std::string &f_coeff = "0",
+   const std::string &alpha = "1",
+   bool sym_v = false, bool frame_indifferent = false);
+
+  /** Adds a contact boundary to an existing large sliding contact
+      with friction brick. When a boundary is declared slave, a multiplier
+      `lambda` has to be given which whould be defined on the boundary
+      `region`. The integration of contact terms is performed on each
+      slave boundary. A boundary can be both declare master and slave
+      which allows self-contact detection.
+  */
+  void add_contact_boundary_to_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick, const mesh_im &mim, size_type region,
+   bool is_master, bool is_slave, bool is_unbiased, const std::string &u,
+   const std::string &lambda = "", const std::string &w = "");
+
+  /** Adds a rigid obstacle to an existing large sliding contact
+      with friction brick. `expr` is an expression using the high-level
+      generic assembly language (where `x` is the current position)
+      which should be a signed distance to the obstacle.
+      `N` is the mesh dimension.
+  */
+  void add_rigid_obstacle_to_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick, const std::string &expr, size_type N);
+
+  /** Gives the name of the group of variables corresponding to the
+      sliding data for an existing large sliding contact brick.
+  */
+  const std::string &sliding_data_group_name_of_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick);
+
+  /** Gives the name of the group of variables corresponding to the
+      displacement for an existing large sliding contact brick.
+  */
+  const std::string &displacement_group_name_of_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick);
+
+  /** Gives the name of the raytracing interpolate transformation
+      for an existing large sliding contact brick.
+  */
+  const std::string &transformation_name_of_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick);
+
+   
 
 
 #if 0   // Old brick, to be adapted ...
diff --git a/src/getfem/getfem_contact_and_friction_nodal.h b/src/getfem/getfem_contact_and_friction_nodal.h
index d8f9433..a016e71 100644
--- a/src/getfem/getfem_contact_and_friction_nodal.h
+++ b/src/getfem/getfem_contact_and_friction_nodal.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2004-2017 Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_context.h b/src/getfem/getfem_context.h
index adcd3b3..064e611 100644
--- a/src/getfem/getfem_context.h
+++ b/src/getfem/getfem_context.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -97,15 +97,16 @@ namespace getfem {
 
     void sup_dependent_(const context_dependencies &cd) const;
     void sup_dependency_(const context_dependencies &cd) const;
-    void invalid_context(void) const;
+    void invalid_context() const;
+    bool go_check() const;
 
   public :
     
     /** this function has to be defined and should update the object when
 	the context is modified. */
-    virtual void update_from_context(void) const = 0;
+    virtual void update_from_context() const = 0;
 
-    void change_context(void) const
+    void change_context() const
     { 
       if (state == CONTEXT_NORMAL) 
       { 
@@ -125,11 +126,12 @@ namespace getfem {
     void clear_dependencies();
 
 
-    bool is_context_valid(void) const { return (state != CONTEXT_INVALID); }
+    bool is_context_valid() const { return (state != CONTEXT_INVALID); }
     bool is_context_changed() const { return (state == CONTEXT_CHANGED); }
     /** return true if update_from_context was called */
-    bool context_check(void) const;
-    void touch(void) const;
+    bool context_check() const
+    { if (state == CONTEXT_NORMAL) return false; return go_check(); }
+    void touch() const;
     virtual ~context_dependencies();
     context_dependencies() : state(CONTEXT_NORMAL), touched( ) {touched = false;}
     context_dependencies(const context_dependencies& cd);
diff --git a/src/getfem/getfem_continuation.h b/src/getfem/getfem_continuation.h
index 0b622c9..71c6184 100644
--- a/src/getfem/getfem_continuation.h
+++ b/src/getfem/getfem_continuation.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2011-2016 Tomas Ligursky, Yves Renard, Konstantinos Poulios
+ Copyright (C) 2011-2017 Tomas Ligursky, Yves Renard, Konstantinos Poulios
 
  This file is a part of GetFEM++
 
@@ -30,7 +30,7 @@
 ===========================================================================*/
 
 /** @file getfem_continuation.h
-    @author Tomas Ligursky <tomas.ligursky at gmail.com>
+    @author Tomas Ligursky <tomas.ligursky at ugn.cas.cz>
     @author Yves Renard <Yves.Renard at insa-lyon.fr>
     @author Konstantinos Poulios <logari81 at googlemail.com>
     @date October 17, 2011.
@@ -102,7 +102,7 @@ namespace getfem {
       gmm::add(gmm::scaled(g, tgamma), y);      // y += tgamma * g
       double r = norm(y);
       if (r > 1.e-10)
-        GMM_WARNING1("Tangent computed with the residual " << r);
+        GMM_WARNING2("Tangent computed with the residual " << r);
     }
 
   private:
@@ -140,7 +140,7 @@ namespace getfem {
       VECT X(x), tX(tx);
 
       if (noisy() > 0) cout << "Trying a simple tangent switch" << endl;
-      if (noisy() > 0) cout << "Starting computing a new tangent" << endl;
+      if (noisy() > 1) cout << "Computing a new tangent" << endl;
       h *= 1.5;
       scaled_add(x, gamma, tx, tgamma, h, X, Gamma);  // [X,Gamma] = [x,gamma] + h * [tx,tgamma]
       compute_tangent(X, Gamma, tX, tGamma);
@@ -148,7 +148,7 @@ namespace getfem {
       // (tx, tgamma), for sure, and increase h_min if it were greater or
       // equal to mincos(). However, this seems to be superfluous.
 
-      if (noisy() > 0)
+      if (noisy() > 1)
         cout << "Starting testing the computed tangent" << endl;
       double h_test = -0.9 * h_min();
       bool accepted(false);
@@ -196,7 +196,7 @@ namespace getfem {
                              const VECT &tx, double tgamma) {
       set_tau_lp(tgamma);
       if (this->singularities > 1) {
-        if (noisy() > 0) cout << "Starting computing an initial value of the "
+        if (noisy() > 1) cout << "Computing an initial value of the "
                               << "test function for bifurcations" << endl;
         set_tau_bp_2(test_function_bp(x, gamma, tx, tgamma));
       }
@@ -225,7 +225,7 @@ namespace getfem {
       double q = sp(cc_x(nn), v_x) + cc_gamma * v_gamma + dd * tau - 1.;
       r = sqrt(sp(y, y) + r * r + q * q);
       if (r > 1.e-10)
-        GMM_WARNING1("Test function evaluated with the residual " << r);
+        GMM_WARNING2("Test function evaluated with the residual " << r);
 
       return tau;
     }
@@ -324,7 +324,7 @@ namespace getfem {
       double Delta_Gamma, res(0), diff;
       VECT f(X), g(X), Delta_X(X), y(X);
 
-      if (noisy() == 1) cout << "Starting correction" << endl;
+      if (noisy() > 1) cout << "Starting correction" << endl;
       F(X, Gamma, f);                                          // f = F(X, Gamma) = -rhs(X, Gamma)
 //CHANGE 1: line search
 //double res0 = norm(f);
@@ -335,7 +335,7 @@ namespace getfem {
                                                                // Delta_X = F_x(X, Gamma)^-1 * f
         Delta_Gamma = sp(tX, Delta_X) / (sp(tX, y) - tGamma);  // Delta_Gamma = tX.Delta_X / (tX.y - tGamma)
         if (isnan(Delta_Gamma)) {
-          if (noisy() > 0) cout << "Newton correction failed with NaN" << endl;
+          if (noisy() > 1) cout << "Newton correction failed with NaN" << endl;
           return false;
         }
         gmm::add(gmm::scaled(y, -Delta_Gamma), Delta_X);       // Delta_X -= Delta_Gamma * y
@@ -372,7 +372,7 @@ namespace getfem {
           break;
         }
       }
-      if (noisy() == 1) cout << "Correction finished with Gamma = "
+      if (noisy() > 1) cout << "Correction finished with Gamma = "
                              << Gamma << endl;
       return converged;
     }
@@ -394,7 +394,7 @@ namespace getfem {
       while (!converged) { //step control
         // prediction
         scaled_add(x, gamma, tx, tgamma, h, X, Gamma);   // [X,Gamma] = [x,gamma] + h * [tx,tgamma]
-        if (noisy() > 0)
+        if (noisy() > 1)
           cout << "(TPD) Prediction   : Gamma = " << Gamma
                << " (for h = " << h << ", tgamma = " << tgamma << ")" << endl;
         copy(tx, tgamma, tX, tGamma);
@@ -427,13 +427,13 @@ namespace getfem {
       VECT x0(x), X(x), tx0(tx), tX(tx), v_x(tx);
 
       if (noisy() > 0)
-        cout  << "Starting locating the bifurcation point" << endl;
+        cout  << "Starting locating a bifurcation point" << endl;
 
       // predictor-corrector steps with a secant-type step-length adaptation
       h *= tau1 / (tau0 - tau1);
       for (size_type i=0; i < 10 && (gmm::abs(h) >= h_min()); ++i) {
         scaled_add(x0, gamma0, tx0, tgamma0, h, X, Gamma); // [X,Gamma] = [x0,gamma0] + h * [tx0,tgamma0]
-        if (noisy() > 0)
+        if (noisy() > 1)
           cout << "(TSBP) Prediction   : Gamma = " << Gamma
                << " (for h = " << h << ", tgamma = " << tgamma << ")" << endl;
         if (newton_corr(X, Gamma, tX, tGamma, tx0, tgamma0)) {
@@ -467,11 +467,11 @@ namespace getfem {
   public:
 
     /* A tool for approximating a non-smooth point close to (x, gamma) and
-       locating one-sided smooth solution branches emanating from there. It is
-       supposed that (x, gamma) is a point on a smooth solution branch within
-       the distance of h_min() from the end point of this branch and
-       (tx, tgamma) is the corresponding tangent that is directed towards the
-       end point. The boolean set_next determines whether the first new
+       consequent locating one-sided smooth solution branches emanating from
+       there. It is supposed that (x, gamma) is a point on a smooth solution
+       branch within the distance of h_min() from the end point of this
+       branch and (tx, tgamma) is the corresponding tangent directed towards
+       the end point. The boolean set_next determines whether the first new
        branch found (if any) is to be chosen for further continuation. */
     void treat_nonsmooth_point(const VECT &x, double gamma,
                                const VECT &tx, double tgamma, bool set_next) {
@@ -494,7 +494,7 @@ namespace getfem {
       h /= 2.;
       for (size_type i = 0; i < 15; i++) {
         scaled_add(x0, gamma0, tx0, tgamma0, h, X, Gamma);    // [X,Gamma] = [x0,gamma0] + h*[tx0,tgamma0]
-        if (noisy() > 0)
+        if (noisy() > 1)
           cout << "(TNSBP) Prediction   : Gamma = " << Gamma
                << " (for h = " << h << ", tgamma = " << tgamma << ")" << endl;
         if (newton_corr(X, Gamma, tX, tGamma, tx0, tgamma0)
@@ -507,13 +507,13 @@ namespace getfem {
         h /= 2.;
       }
       if (noisy() > 0)
-        cout  << "A non-smooth point located" << endl;
+        cout  << "Non-smooth point located" << endl;
       set_sing_point(x0, gamma0);
 
       // take two reference vectors to span a subspace of directions emanating
       // from the end point
       if (noisy() > 0)
-        cout << "Starting a thorough search for other branches" << endl;
+        cout << "Starting a thorough search for different branches" << endl;
       double tgamma1 = tgamma0, tgamma2 = tgamma0;
       VECT tx1(tx0), tx2(tx0);
       scale(tx1, tgamma1, -1.);                                     // [tx1,tgamma1] *= -1
@@ -542,7 +542,7 @@ namespace getfem {
               || (i == 0 && nspan == 0)) {
             copy(tX, tGamma, tx0, tgamma0);
             if (insert_tangent_predict(tX, tGamma)) {
-              if (noisy() > 0)
+              if (noisy() > 1)
                 cout << "New potential tangent vector found, "
                      << "trying one predictor-corrector step" << endl;
               copy(x0, gamma0, X, Gamma);
@@ -553,6 +553,8 @@ namespace getfem {
                       // => (tX, tGamma) = (tx2, tgamma2)
                       && (gmm::abs(cosang(tX, tx0, tGamma, tgamma0))
                           >= mincos())) { i2 = 1; }
+		  if (noisy() > 0) cout << "A new branch located (for nspan = "
+					<< nspan << ")" << endl;
                   if (set_next) set_next_point(X, Gamma);
 
                 }
@@ -562,9 +564,12 @@ namespace getfem {
 
               scale(tX, tGamma, -1.);                               // [tX,tGamma] *= -1
               if (test_predict_dir(X, Gamma, tX, tGamma)
-                  && insert_tangent_sing(tX, tGamma) && set_next)
-                set_next_point(X, Gamma);
-            }
+                  && insert_tangent_sing(tX, tGamma)) {
+		if (noisy() > 0) cout << "A new branch located (for nspan = "
+				      << nspan << ")" << endl;
+		if (set_next) set_next_point(X, Gamma);
+	      }
+	    }
           }
         }
 
@@ -588,7 +593,8 @@ namespace getfem {
       } while (++nspan < nbspan());
 
       if (noisy() > 0)
-        cout << "Located branches " << nb_tangent_sing() << endl;
+        cout << "Number of branches emanating from the non-smooth point "
+	     << nb_tangent_sing() << endl;
     }
 
 
@@ -597,8 +603,8 @@ namespace getfem {
                                          double &tgamma, double &h) {
       gmm::clear(tx);
       tgamma = (tgamma >= 0) ? 1. : -1.;
-      if (noisy() > 0)
-        cout << "Starting computing an initial tangent" << endl;
+      if (noisy() > 1)
+        cout << "Computing an initial tangent" << endl;
       compute_tangent(x, gamma, tx, tgamma);
       h = h_init();
       if (this->singularities > 0)
@@ -623,7 +629,7 @@ namespace getfem {
         h0 = h;
         // prediction
         scaled_add(x, gamma, tx, tgamma, h, X, Gamma);              // [X,Gamma] = [x,gamma] + h*[tx,tgamma]
-        if (noisy() > 0)
+        if (noisy() > 1)
           cout << " Prediction    : Gamma = " << Gamma
                << " (for h = " << std::scientific << std::setprecision(3) << h
                << ", tgamma = " << tgamma << ")" << endl;
@@ -641,8 +647,8 @@ namespace getfem {
               if (noisy() > 0) cout << "Limit point detected!" << endl;
             }
             if (this->singularities > 1) { // Treat bifurcations
-              if (noisy() > 0)
-                cout << "New point found, starting computing a test function "
+              if (noisy() > 1)
+                cout << "New point found, computing a test function "
                      << "for bifurcations" << endl;
               if (!tangent_switched) {
                 if (test_smooth_bifurcation(X, Gamma, tX, tGamma)) {
@@ -678,7 +684,7 @@ namespace getfem {
             if (noisy() > 0)
               cout << "Restarting the classical continuation" << endl;
           } else break;
-        } else new_point = true;
+        } else break;
       } while (!new_point);
 
       if (new_point) {
@@ -692,8 +698,8 @@ namespace getfem {
             set_sing_label("limit point");
             if (noisy() > 0) cout << "Limit point detected!" << endl;
           }
-          if (noisy() > 0)
-            cout << "Starting computing a test function for bifurcations"
+          if (noisy() > 1)
+            cout << "Computing a test function for bifurcations"
                  << endl;
           bool bifurcation_detected = (nb_tangent_sing() > 2);
           if (bifurcation_detected) {
diff --git a/src/getfem/getfem_convect.h b/src/getfem/getfem_convect.h
index ad44c56..04da9d1 100644
--- a/src/getfem/getfem_convect.h
+++ b/src/getfem/getfem_convect.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard
+ Copyright (C) 2009-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_copyable_ptr.h b/src/getfem/getfem_copyable_ptr.h
index 1eebbaf..f72f32f 100644
--- a/src/getfem/getfem_copyable_ptr.h
+++ b/src/getfem/getfem_copyable_ptr.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2012-2016 Andriy Andreykiv
+ Copyright (C) 2012-2017 Andriy Andreykiv
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_crack_sif.h b/src/getfem/getfem_crack_sif.h
index d011e67..1efbd45 100644
--- a/src/getfem/getfem_crack_sif.h
+++ b/src/getfem/getfem_crack_sif.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard,  Julien Pommier
+ Copyright (C) 2007-2017 Yves Renard,  Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_deformable_mesh.h b/src/getfem/getfem_deformable_mesh.h
index 353772f..511bdff 100644
--- a/src/getfem/getfem_deformable_mesh.h
+++ b/src/getfem/getfem_deformable_mesh.h
@@ -1,141 +1,148 @@
-/* -*- c++ -*- (enables emacs c++ mode) */
-/*===========================================================================
-
- Copyright (C) 2012-2016 Andriy Andreykiv
-
- This file is a part of GetFEM++
-
- GetFEM++  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 along with the GCC Runtime Library
- Exception either version 3.1 or (at your option) any later version.
- This program  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 and GCC Runtime Library Exception for more details.
- You  should  have received a copy of the GNU Lesser General Public License
- along  with  this program;  if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
-
- As a special exception, you  may use  this file  as it is a part of a free
- software  library  without  restriction.  Specifically,  if   other  files
- instantiate  templates  or  use macros or inline functions from this file,
- or  you compile this  file  and  link  it  with other files  to produce an
- executable, this file  does  not  by itself cause the resulting executable
- to be covered  by the GNU Lesser General Public License.  This   exception
- does not  however  invalidate  any  other  reasons why the executable file
- might be covered by the GNU Lesser General Public License.
-
-===========================================================================*/
-
-/** @file getfem_deformable_mesh.h
- at author "Andriy Andreykiv" <andriy.andreykiv at gmail.com>
- at date August 7, 2012.
- at brief A class adaptor to deform a mesh.
-*/
-
-#pragma once
-#ifndef GETFEM_DEFORMABLE_MESH_H__
-#define GETFEM_DEFORMABLE_MESH_H__
-
-#include <getfem/getfem_mesh.h>
-#include <getfem/getfem_mesh_fem.h>
-#include <getfem/getfem_models.h>
-
-namespace getfem {
-
-  /** An object function that first deforms and then remembers 
-  to restore a mesh if it has to be restored 
-  for other bricks. By default the mesh is deformed on 
-  construct and undeformed in the destructor (by RAII principle)
-  but it's also possible to specify deform_on_construct = false 
-  and then call explicitely deform() and undeform() methods.
-  Optional to_be_restored flag will control whether the mesh will be restored
-  when the deformator destructs.
-  */
-  template<class VECTOR = model_real_plain_vector> 
-  class temporary_mesh_deformator
-  {
-  public:
-    temporary_mesh_deformator(const mesh_fem &mf, const VECTOR &dU,
-      bool deform_on_construct = true, bool to_be_restored = true)
-       : dU_(mf.nb_basic_dof()),
-         mf_(mf), 
-         deform_on_construct_(deform_on_construct),
-         is_deformed_(false),
-         to_be_restored_(to_be_restored){
-      mf.extend_vector(dU, dU_);
-      if (deform_on_construct_) deform();
-    }
-
-    void deform(){
-      if (is_deformed_) return;
-      deforming_mesh_(dU_);
-      is_deformed_ = true;
-    }
-
-    void undeform(){
-      if (!is_deformed_) return;
-      VECTOR dU_inverted(dU_);
-      gmm::scale(dU_inverted, scalar_type(-1.0));
-      deforming_mesh_(dU_inverted);
-      is_deformed_ = false;
-    }
-
-    ~temporary_mesh_deformator(){
-      if (to_be_restored_ && deform_on_construct_){
-        undeform();
-      }
-    }
-
-  private:
-    void deforming_mesh_(VECTOR &dU){
-      auto &m_ = const_cast<getfem::mesh &>(mf_.linked_mesh());
-      auto &ppts = m_.points();
-      auto init_nb_points = ppts.card();
-
-      dal::bit_vector conv_indices = mf_.convex_index();
-      //this vector will track if a point can be deformed
-      std::vector<bool> deform_pt_flag(ppts.size(), true);
-      size_type cv;
-      for (cv << conv_indices; cv != bgeot::size_type(-1); cv << conv_indices)
-      {
-        getfem::mesh::ind_cv_ct pt_index = m_.ind_points_of_convex(cv);
-        getfem::mesh_fem::ind_dof_ct dof = mf_.ind_basic_dof_of_element(cv);
-        bgeot::size_type num_points = m_.structure_of_convex(cv)->nb_points();
-
-        GMM_ASSERT2(dof.size() % num_points == 0,
-          "mesh_fem should be isoparametric to the mesh, "
-          "with nb_points() of convex == size of ind_basic_dof_of_element / qdim()");
-
-        size_type ddim = dof.size() / num_points;
-        GMM_ASSERT2(ddim <= 3, "dimension of dof is greater than 3");
-
-        for (size_type pt = 0; pt < num_points; ++pt)
-        {
-          /** iterate through each components of point [pt]and deform the component*/
-          if (deform_pt_flag[pt_index[pt]])
-          for (size_type comp = 0; comp < ddim; ++comp)
-            //move pts by dU;
-            ppts[pt_index[pt]][comp] += dU[dof[pt*ddim + comp]];
-
-          //flag current [pt] to deformed
-          deform_pt_flag[pt_index[pt]] = false;
-        }
-        ppts.resort();
-      }
-      GMM_ASSERT1(ppts.card() == init_nb_points, 
-                  "Error, after deforming the mesh, number of nodes are different.");
-    }
-
-    VECTOR dU_;
-    const mesh_fem &mf_;
-    bool deform_on_construct_;
-    bool is_deformed_;
-    bool to_be_restored_;
-  };
-
-}//end of getfem namespace
-
-#endif //GETFEM_DEFORMABLE_MESH_H__
+/* -*- c++ -*- (enables emacs c++ mode) */
+/*===========================================================================
+
+ Copyright (C) 2012-2017 Andriy Andreykiv
+
+ This file is a part of GetFEM++
+
+ GetFEM++  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 along with the GCC Runtime Library
+ Exception either version 3.1 or (at your option) any later version.
+ This program  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 and GCC Runtime Library Exception for more details.
+ You  should  have received a copy of the GNU Lesser General Public License
+ along  with  this program;  if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ As a special exception, you  may use  this file  as it is a part of a free
+ software  library  without  restriction.  Specifically,  if   other  files
+ instantiate  templates  or  use macros or inline functions from this file,
+ or  you compile this  file  and  link  it  with other files  to produce an
+ executable, this file  does  not  by itself cause the resulting executable
+ to be covered  by the GNU Lesser General Public License.  This   exception
+ does not  however  invalidate  any  other  reasons why the executable file
+ might be covered by the GNU Lesser General Public License.
+
+===========================================================================*/
+
+/** @file getfem_deformable_mesh.h
+ at author "Andriy Andreykiv" <andriy.andreykiv at gmail.com>
+ at date August 7, 2012.
+ at brief A class adaptor to deform a mesh.
+*/
+
+#pragma once
+#ifndef GETFEM_DEFORMABLE_MESH_H__
+#define GETFEM_DEFORMABLE_MESH_H__
+
+#include <getfem/getfem_mesh.h>
+#include <getfem/getfem_mesh_fem.h>
+#include <getfem/getfem_models.h>
+
+namespace getfem {
+
+  /** An object function that first deforms and then remembers 
+  to restore a mesh if it has to be restored 
+  for other bricks. By default the mesh is deformed on 
+  construct and undeformed in the destructor (by RAII principle)
+  but it's also possible to specify deform_on_construct = false 
+  and then call explicitely deform() and undeform() methods.
+  Optional to_be_restored flag will control whether the mesh will be restored
+  when the deformator destructs.
+  */
+  template<class VECTOR = model_real_plain_vector> 
+  class temporary_mesh_deformator
+  {
+  public:
+    temporary_mesh_deformator(const mesh_fem &mf, const VECTOR &dU,
+      bool deform_on_construct = true, bool to_be_restored = true)
+       : dU_(mf.nb_basic_dof()),
+         mf_(mf), 
+         deform_on_construct_(deform_on_construct),
+         is_deformed_(false),
+         to_be_restored_(to_be_restored){
+      mf.extend_vector(dU, dU_);
+      if (deform_on_construct_) deform();
+    }
+
+    void deform(){
+      if (is_deformed_) return;
+      initial_nodes_ = mf_.linked_mesh().points();
+      deforming_mesh_(dU_);
+      is_deformed_ = true;
+    }
+
+    void undeform(){
+      if (!is_deformed_) return;
+      restore_();
+      is_deformed_ = false;
+    }
+
+    ~temporary_mesh_deformator(){
+      if (to_be_restored_ && deform_on_construct_){
+        undeform();
+      }
+    }
+
+  private:
+    void deforming_mesh_(VECTOR &dU){
+      auto &m_ = const_cast<getfem::mesh &>(mf_.linked_mesh());
+      auto &ppts = m_.points();
+      auto init_nb_points = ppts.card();
+
+      dal::bit_vector conv_indices = mf_.convex_index();
+      //this vector will track if a point can be deformed
+      std::vector<bool> deform_pt_flag(ppts.size(), true);
+      size_type cv;
+      for (cv << conv_indices; cv != bgeot::size_type(-1); cv << conv_indices)
+      {
+        getfem::mesh::ind_cv_ct pt_index = m_.ind_points_of_convex(cv);
+        getfem::mesh_fem::ind_dof_ct dof = mf_.ind_basic_dof_of_element(cv);
+        bgeot::size_type num_points = m_.structure_of_convex(cv)->nb_points();
+
+        GMM_ASSERT2(dof.size() % num_points == 0,
+          "mesh_fem should be isoparametric to the mesh, "
+          "with nb_points() of convex == size of ind_basic_dof_of_element / qdim()");
+
+        size_type ddim = dof.size() / num_points;
+        GMM_ASSERT2(ddim <= 3, "dimension of dof is greater than 3");
+
+        for (size_type pt = 0; pt < num_points; ++pt)
+        {
+          /** iterate through each components of point [pt]and deform the component*/
+          if (deform_pt_flag[pt_index[pt]])
+          for (size_type comp = 0; comp < ddim; ++comp)
+            //move pts by dU;
+            ppts[pt_index[pt]][comp] += dU[dof[pt*ddim + comp]];
+
+          //flag current [pt] to deformed
+          deform_pt_flag[pt_index[pt]] = false;
+        }
+        ppts.resort();
+      }
+      GMM_ASSERT1(ppts.card() == init_nb_points, 
+                  "Error, after deforming the mesh, number of nodes are different.");
+    }
+
+    void restore_()
+    {
+      auto &pts = const_cast<getfem::mesh &>(mf_.linked_mesh()).points();
+      GMM_ASSERT1(pts.size() == initial_nodes_.size(), "Internal error, incorrect number of points.");
+      for (size_type i = 0; i < pts.size(); ++i) gmm::copy(initial_nodes_[i], pts[i]);
+    }
+
+    VECTOR dU_;
+    const mesh_fem &mf_;
+    getfem::mesh::PT_TAB initial_nodes_;
+    bool deform_on_construct_;
+    bool is_deformed_;
+    bool to_be_restored_;
+  };
+
+}//end of getfem namespace
+
+#endif //GETFEM_DEFORMABLE_MESH_H__
diff --git a/src/getfem/getfem_derivatives.h b/src/getfem/getfem_derivatives.h
index c4aff3f..dcc9d33 100644
--- a/src/getfem/getfem_derivatives.h
+++ b/src/getfem/getfem_derivatives.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_error_estimate.h b/src/getfem/getfem_error_estimate.h
index 1050867..8c5a25a 100644
--- a/src/getfem/getfem_error_estimate.h
+++ b/src/getfem/getfem_error_estimate.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard, Julien Pommier
+ Copyright (C) 1999-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -55,7 +55,7 @@ namespace getfem {
     const mesh &m = mim.linked_mesh();
     rg.from_mesh(m);
     GMM_ASSERT3(&m == &mf.linked_mesh() &&
-		gmm::vect_size(err) >= m.convex_index().last_true()+1, "");
+		gmm::vect_size(err) >= m.nb_allocated_convex(), "");
     
     const mesh_fem &mf0 = classical_mesh_fem(m, 0);
 
diff --git a/src/getfem/getfem_export.h b/src/getfem/getfem_export.h
index a6bda7b..37a2df5 100644
--- a/src/getfem/getfem_export.h
+++ b/src/getfem/getfem_export.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2001-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2001-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -88,12 +88,14 @@ namespace getfem {
                    VTK_VOXEL = 11,
                    VTK_HEXAHEDRON = 12,
                    VTK_WEDGE = 13,
+                   VTK_PYRAMID = 14,
                    VTK_QUADRATIC_EDGE = 21,
                    VTK_QUADRATIC_TRIANGLE = 22,
                    VTK_QUADRATIC_QUAD = 23,
                    VTK_QUADRATIC_TETRA = 24,
                    VTK_QUADRATIC_HEXAHEDRON = 25,
                    /*VTK_QUADRATIC_WEDGE = 26,*/
+		   VTK_QUADRATIC_PYRAMID = 27,
                    VTK_BIQUADRATIC_QUAD = 28,
                    VTK_TRIQUADRATIC_HEXAHEDRON = 29 } vtk_cell_type;
     vtk_export(const std::string& fname, bool ascii_ = false);
@@ -568,13 +570,14 @@ namespace getfem {
 
   public:
     typedef enum {
-                   POS_PT = 0, //point
-                   POS_LN = 1, //line
-                   POS_TR = 2, //triangles
-                   POS_QU = 3, //quadrangles
-                   POS_SI = 4, //tetrahedra
-                   POS_HE = 5, //hexahedra
-                   POS_PR = 6  //prisms
+                   POS_PT = 0, // point
+                   POS_LN = 1, // line
+                   POS_TR = 2, // triangles
+                   POS_QU = 3, // quadrangles
+                   POS_SI = 4, // tetrahedra
+                   POS_HE = 5, // hexahedra
+                   POS_PR = 6, // prisms
+                   POS_PY = 7  // pyramids
     } pos_cell_types;
 
     pos_export(const std::string& fname);
@@ -667,7 +670,7 @@ namespace getfem {
   }
 
   template <class VECT>
-  void pos_export::write(const VECT& V, const size_type qdim_v){
+  void pos_export::write(const VECT& V, const size_type qdim_v) {
     int t;
     std::vector<unsigned> cell_dof;
     std::vector<scalar_type> cell_dof_val;
@@ -684,7 +687,7 @@ namespace getfem {
 
   template <class VECT>
   void pos_export::write_cell(const int& t, const std::vector<unsigned>& dof,
-                                            const VECT& val){
+                                            const VECT& val) {
     size_type qdim_cell = val.size()/dof.size();
     size_type dim3D = size_type(-1);
     if (1==qdim_cell){
@@ -705,6 +708,7 @@ namespace getfem {
       case POS_SI: os << "S("; break; // tetrahedra (simplex)
       case POS_HE: os << "H("; break; // hexahedra
       case POS_PR: os << "I("; break; // prism
+      case POS_PY: os << "Y("; break; // pyramid
     }
     for (size_type i=0; i<dof.size(); ++i){
       for(size_type j=0; j<dim; ++j){
diff --git a/src/getfem/getfem_fem.h b/src/getfem/getfem_fem.h
index 9ab6bce..56721a7 100644
--- a/src/getfem/getfem_fem.h
+++ b/src/getfem/getfem_fem.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -88,23 +88,29 @@
    - "FEM_REDUCED_QUADC1_COMPOSITE" : quadrilateral element, composite
       P3 element and C^1 (12 dof).
 
-   - "FEM_PK_HIERARCHICAL(N,K)" : PK element with a hierarchical basis
+   - "FEM_PK_HIERARCHICAL(N,K)" : PK element with a hierarchical basis.
 
-   - "FEM_QK_HIERARCHICAL(N,K)" : QK element with a hierarchical basis
+   - "FEM_QK_HIERARCHICAL(N,K)" : QK element with a hierarchical basis.
 
    - "FEM_PK_PRISM_HIERARCHICAL(N,K)" : PK element on a prism with a
-   hierarchical basis
+   hierarchical basis.
 
    - "FEM_STRUCTURED_COMPOSITE(FEM, K)" : Composite fem on a grid with
-   K divisions
+   K divisions.
 
    - "FEM_PK_HIERARCHICAL_COMPOSITE(N,K,S)" : PK composite element on
-   a grid with S subdivisions and with a hierarchical basis
+   a grid with S subdivisions and with a hierarchical basis.
 
    - "FEM_PK_FULL_HIERARCHICAL_COMPOSITE(N,K,S)" : PK composite
    element with S subdivisions and a hierarchical basis on both degree
-   and subdivision
+   and subdivision.
 
+   - "FEM_PYRAMID_LAGRANGE(K)" : Lagrange element on a 3D pyramid of degree
+   K=0, 1 or 2. Can be connected to a standard P1/P2 lagrange on its
+   triangular faces and standard Q1/Q2 Lagrange on its quadrangular face.
+
+   - "FEM_PYRAMID_DISCONTINUOUS_LAGRANGE(K)" : Discontinuous Lagrange element
+   on a 3D pyramid of degree K = 0, 1 or 2.
 */
 
 #ifndef GETFEM_FEM_H__
@@ -253,6 +259,7 @@ namespace getfem {
     bool is_pol;            // true if the FEM is polynomial
     bool is_polycomp;       // true if the FEM is polynomial composite
     bool real_element_defined;
+    bool is_standard_fem;   // is_equiv && !real_element_defined && scalar
     short_type es_degree;   // estimated polynomial degree of the FEM
     short_type hier_raff;   // hierarchical refinement of the FEM
     vec_type vtype; // for vectorial elements, type of transformation
@@ -328,10 +335,12 @@ namespace getfem {
     /// true if the base functions are polynomials
     bool is_polynomial() const { return is_pol; }
     bool is_polynomialcomp() const { return is_polycomp; }
+    bool is_standard() const { return is_standard_fem; }
     bool &is_polynomialcomp() { return is_polycomp; }
     bool &is_equivalent() { return is_equiv; }
     bool &is_lagrange() { return is_lag; }
     bool &is_polynomial() { return is_pol; }
+    bool &is_standard() { return is_standard_fem; }
     short_type estimated_degree() const { return es_degree; }
     short_type &estimated_degree() { return es_degree; }
 
@@ -453,7 +462,7 @@ namespace getfem {
     virtual_fem() {
       DAL_STORED_OBJECT_DEBUG_CREATED(this, "Fem");
       ntarget_dim = 1; dim_ = 1;
-      is_equiv = is_pol = is_polycomp = is_lag = false;
+      is_equiv = is_pol = is_polycomp = is_lag = is_standard_fem = false;
       pspt_valid = false; hier_raff = 0; real_element_defined = false;
       es_degree = 5;
       vtype = VECTORIAL_NOTRANSFORM_TYPE;
@@ -476,7 +485,35 @@ namespace getfem {
   template <class FUNC> class fem : public virtual_fem {
   protected :
     std::vector<FUNC> base_;
+    mutable std::vector<std::vector<FUNC>> grad_, hess_;
 
+    void compute_grad_() const {
+      size_type R = nb_base_components(0);
+      dim_type n = dim();
+      grad_.resize(R);
+      for (size_type i = 0; i < R; ++i) {
+	grad_[i].resize(n);
+	for (dim_type j = 0; j < n; ++j) {
+	  grad_[i][j] = base_[i]; grad_[i][j].derivative(j);
+	}
+      }
+    }
+
+    void compute_hess_() const {
+      size_type R = nb_base_components(0);
+      dim_type n = dim();
+      hess_.resize(R);
+      for (size_type i = 0; i < R; ++i) {
+	hess_[i].resize(n*n);
+	for (dim_type j = 0; j < n; ++j) {
+	  for (dim_type k = 0; k < n; ++k) {
+	    hess_[i][j+k*n] = base_[i];
+	    hess_[i][j+k*n].derivative(j); hess_[i][j+k*n].derivative(k);
+	  }
+	}
+      }
+    }
+    
   public :
 
     /// Gives the array of basic functions (components).
@@ -497,6 +534,7 @@ namespace getfem {
         reference element directions 0,..,dim-1 and returns the result in
         t(nb_base,target_dim,dim) */
     void grad_base_value(const base_node &x, base_tensor &t) const {
+      if (!(grad_.size())) compute_grad_();
       bgeot::multi_index mi(3);
       dim_type n = dim();
       mi[2] = n; mi[1] = target_dim(); mi[0] = short_type(nb_base(0));
@@ -505,12 +543,13 @@ namespace getfem {
       base_tensor::iterator it = t.begin();
       for (dim_type j = 0; j < n; ++j)
         for (size_type i = 0; i < R; ++i, ++it)
-          { FUNC f = base_[i]; f.derivative(j); *it = bgeot::to_scalar(f.eval(x.begin())); }
+	  *it = bgeot::to_scalar(grad_[i][j].eval(x.begin()));
     }
     /** Evaluates at point x, the hessian of all base functions w.r.t. the
         reference element directions 0,..,dim-1 and returns the result in
         t(nb_base,target_dim,dim,dim) */
     void hess_base_value(const base_node &x, base_tensor &t) const {
+      if (!(hess_.size())) compute_hess_();
       bgeot::multi_index mi(4);
       dim_type n = dim();
       mi[3] = n; mi[2] = n; mi[1] = target_dim();
@@ -520,19 +559,18 @@ namespace getfem {
       base_tensor::iterator it = t.begin();
       for (dim_type k = 0; k < n; ++k)
         for (dim_type j = 0; j < n; ++j)
-          for (size_type i = 0; i < R; ++i, ++it) {
-            FUNC f = base_[i];
-            f.derivative(j); f.derivative(k);
-            *it = bgeot::to_scalar(f.eval(x.begin()));
-          }
+          for (size_type i = 0; i < R; ++i, ++it)
+	    *it = bgeot::to_scalar(hess_[i][j+k*n].eval(x.begin()));
     }
 
   };
 
   /** Classical polynomial FEM. */
-  typedef const fem<base_poly> * ppolyfem;
+  typedef const fem<bgeot::base_poly> * ppolyfem;
   /** Polynomial composite FEM */
   typedef const fem<bgeot::polynomial_composite> * ppolycompfem;
+  /** Rational fration FEM */
+  typedef const fem<bgeot::base_rational_fraction> * prationalfracfem;
 
   /** Give a pointer on the structures describing the classical
       polynomial fem of degree k on a given convex type.
@@ -686,10 +724,14 @@ namespace getfem {
         at point @c this->xref())
     */
     void base_value(base_tensor& t, bool withM = true) const;
+    // Optimized function for high level generic assembly
+    void pfp_base_value(base_tensor& t, const pfem_precomp &pfp__);
     /** fill the tensor with the gradient of the base functions (taken
         at point @c this->xref())
     */
     void grad_base_value(base_tensor& t, bool withM = true) const;
+    // Optimized function for high level generic assembly
+    void pfp_grad_base_value(base_tensor& t, const pfem_precomp &pfp__);
     /** fill the tensor with the hessian of the base functions (taken
         at point @c this->xref())
     */
@@ -699,6 +741,7 @@ namespace getfem {
     /** get the current convex number */
     size_type convex_num() const;
     bool is_convex_num_valid() const;
+    void invalid_convex_num() { convex_num_ = size_type(-1); }
     /** set the current face number */
     void set_face_num(short_type f) { face_num_ = f; }
     /** get the current face number */
@@ -711,23 +754,59 @@ namespace getfem {
     void set_pf(pfem newpf);
     int xfem_side() const { return xfem_side_; }
     void set_xfem_side(int side) { xfem_side_ = side; }
-    fem_interpolation_context();
+    void change(bgeot::pgeotrans_precomp pgp__,
+		pfem_precomp pfp__, size_type ii__,
+		const base_matrix& G__, size_type convex_num__,
+		short_type face_num__ = short_type(-1)) {
+      bgeot::geotrans_interpolation_context::change(pgp__,ii__,G__);
+      convex_num_ = convex_num__; face_num_ = face_num__;  xfem_side_ = 0;
+      set_pfp(pfp__);
+    }
+    void change(bgeot::pgeometric_trans pgt__,
+		pfem_precomp pfp__, size_type ii__,
+		const base_matrix& G__, size_type convex_num__,
+		short_type face_num__ = short_type(-1)) {
+      bgeot::geotrans_interpolation_context::change
+	(pgt__, pfp__->get_ppoint_tab(), ii__, G__);
+      convex_num_ = convex_num__; face_num_ = face_num__; xfem_side_ = 0;
+      set_pfp(pfp__);
+    }
+    void change(bgeot::pgeometric_trans pgt__,
+		pfem pf__, const base_node& xref__, const base_matrix& G__,
+		size_type convex_num__,	short_type face_num__=short_type(-1)) {
+      bgeot::geotrans_interpolation_context::change(pgt__,xref__,G__);
+      pf_ = pf__; pfp_ = 0; convex_num_ = convex_num__; face_num_ = face_num__;
+      xfem_side_ = 0;
+    }
+    fem_interpolation_context()
+      : bgeot::geotrans_interpolation_context(),
+	convex_num_(size_type(-1)), face_num_(short_type(-1)), xfem_side_(0) {}
     fem_interpolation_context(bgeot::pgeotrans_precomp pgp__,
                               pfem_precomp pfp__, size_type ii__,
                               const base_matrix& G__,
                               size_type convex_num__,
-                              short_type face_num__ = short_type(-1));
+                              short_type face_num__ = short_type(-1))
+      : bgeot::geotrans_interpolation_context(pgp__,ii__,G__),
+	convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
+    { set_pfp(pfp__); }
     fem_interpolation_context(bgeot::pgeometric_trans pgt__,
                               pfem_precomp pfp__, size_type ii__,
                               const base_matrix& G__,
                               size_type convex_num__,
-                              short_type face_num__ = short_type(-1));
+                              short_type face_num__ = short_type(-1))
+      : bgeot::geotrans_interpolation_context(pgt__,pfp__->get_ppoint_tab(),
+					      ii__, G__),
+	convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
+    { set_pfp(pfp__); }
     fem_interpolation_context(bgeot::pgeometric_trans pgt__,
                               pfem pf__,
                               const base_node& xref__,
                               const base_matrix& G__,
                               size_type convex_num__,
-                              short_type face_num__ = short_type(-1));
+                              short_type face_num__ = short_type(-1))
+      : bgeot::geotrans_interpolation_context(pgt__,xref__,G__),
+	pf_(pf__), pfp_(0), convex_num_(convex_num__), face_num_(face_num__),
+	xfem_side_(0) {}
   };
 
   // IN : coeff(Qmult,nb_dof)
diff --git a/src/getfem/getfem_fem_global_function.h b/src/getfem/getfem_fem_global_function.h
index 42a1eae..3e44d5c 100644
--- a/src/getfem/getfem_fem_global_function.h
+++ b/src/getfem/getfem_fem_global_function.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
  Copyright (C) 2016      Konstantinos Poulios
 
  This file is a part of GetFEM++
@@ -52,12 +52,21 @@ namespace getfem {
     const mesh_im &mim;
     const bool has_mesh_im;
 
-    mutable bgeot::multi_index mib,mig,mih;
     mutable std::vector<std::vector<size_type> > index_of_global_dof_;
     mutable bgeot::pstored_point_tab pspt_override;
 
-    mutable std::vector< std::map<bgeot::pstored_point_tab, std::vector<base_tensor> > >
-      precompval, precompgrad, precomphess; // store values, gradients and hessians of base functions
+    struct precomp_data { std::vector<base_tensor> val, grad, hess; };
+
+    class precomp_pool
+    : virtual public dal::static_stored_object,
+      public std::vector< std::map<bgeot::pstored_point_tab,
+                                   precomp_data > >
+    {};
+
+    // store values, gradients and hessians of base functions
+    mutable std::shared_ptr<precomp_pool> precomps;
+
+    DAL_SIMPLE_KEY(precomp_pool_key, std::shared_ptr<precomp_pool>);
 
     void init();
     virtual void update_from_context() const;
diff --git a/src/getfem/getfem_fem_level_set.h b/src/getfem/getfem_fem_level_set.h
index 0fbbffd..e67c1c1 100644
--- a/src/getfem/getfem_fem_level_set.h
+++ b/src/getfem/getfem_fem_level_set.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_fourth_order.h b/src/getfem/getfem_fourth_order.h
index d40ac1f..be44a8a 100644
--- a/src/getfem/getfem_fourth_order.h
+++ b/src/getfem/getfem_fourth_order.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard
+ Copyright (C) 2006-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -165,25 +165,39 @@ namespace getfem {
 
     size_type Q = gmm::vect_size(F) / mf_data.nb_dof();
 
+    // const char *s;
+    // if (mf.get_qdim() == 1 && Q == 1)
+    //   s = "F=data(#2);"
+    //     "V(#1)+=comp(Grad(#1).Normal().Base(#2))(:,i,i,j).F(j);";
+    // else if (mf.get_qdim() == 1 && Q == gmm::sqr(mf.linked_mesh().dim()))
+    //   s = "F=data(mdim(#1),mdim(#1),#2);"
+    //     "V(#1)+=comp(Grad(#1).Normal().Normal().Normal().Base(#2))"
+    //     "(:,i,i,k,l,j).F(k,l,j);";
+    // else if (mf.get_qdim() > size_type(1) && Q == mf.get_qdim())
+    //   s = "F=data(qdim(#1),#2);"
+    //     "V(#1)+=comp(vGrad(#1).Normal().Base(#2))(:,i,k,k,j).F(i,j);";
+    // else if (mf.get_qdim() > size_type(1) &&
+    //          Q == size_type(mf.get_qdim()*gmm::sqr(mf.linked_mesh().dim())))
+    //   s = "F=data(qdim(#1),mdim(#1),mdim(#1),#2);"
+    //     "V(#1)+=comp(vGrad(#1).Normal().Normal().Normal().Base(#2))"
+    //     "(:,i,k,k,l,m,j).F(i,l,m,j);";
+    // else
+    //   GMM_ASSERT1(false, "invalid rhs vector");
+    // asm_real_or_complex_1_param(B, mim, mf, mf_data, F, rg, s);
+
     const char *s;
     if (mf.get_qdim() == 1 && Q == 1)
-      s = "F=data(#2);"
-        "V(#1)+=comp(Grad(#1).Normal().Base(#2))(:,i,i,j).F(j);";
+      s = "Grad_Test_u.(A*Normal)";
     else if (mf.get_qdim() == 1 && Q == gmm::sqr(mf.linked_mesh().dim()))
-      s = "F=data(mdim(#1),mdim(#1),#2);"
-        "V(#1)+=comp(Grad(#1).Normal().Normal().Normal().Base(#2))"
-        "(:,i,i,k,l,j).F(k,l,j);";
+      s = "Grad_Test_u.(((Reshape(A,meshdim,meshdim)*Normal).Normal)*Normal)";
     else if (mf.get_qdim() > size_type(1) && Q == mf.get_qdim())
-      s = "F=data(qdim(#1),#2);"
-        "V(#1)+=comp(vGrad(#1).Normal().Base(#2))(:,i,k,k,j).F(i,j);";
+      s = "((Grad_Test_u')*A).Normal";
     else if (mf.get_qdim() > size_type(1) &&
              Q == size_type(mf.get_qdim()*gmm::sqr(mf.linked_mesh().dim())))
-      s = "F=data(qdim(#1),mdim(#1),mdim(#1),#2);"
-        "V(#1)+=comp(vGrad(#1).Normal().Normal().Normal().Base(#2))"
-        "(:,i,k,k,l,m,j).F(i,l,m,j);";
+      s = "((((Grad_Test_u').Reshape(A,qdim(u),meshdim,meshdim)).Normal).Normal).Normal";
     else
       GMM_ASSERT1(false, "invalid rhs vector");
-    asm_real_or_complex_1_param(B, mim, mf, mf_data, F, rg, s);
+    asm_real_or_complex_1_param_vec(B, mim, mf, &mf_data, F, rg, s);
   }
 
   template<typename VECT1, typename VECT2>
@@ -193,25 +207,39 @@ namespace getfem {
     
     size_type Q = gmm::vect_size(F);
 
+    // const char *s;
+    // if (mf.get_qdim() == 1 && Q == 1)
+    //   s = "F=data(1);"
+    //     "V(#1)+=comp(Grad(#1).Normal())(:,i,i).F(1);";
+    // else if (mf.get_qdim() == 1 && Q == gmm::sqr(mf.linked_mesh().dim()))
+    //   s = "F=data(mdim(#1),mdim(#1));"
+    //     "V(#1)+=comp(Grad(#1).Normal().Normal().Normal())"
+    //     "(:,i,i,l,j).F(l,j);";
+    // else if (mf.get_qdim() > size_type(1) && Q == mf.get_qdim())
+    //   s = "F=data(qdim(#1));"
+    //     "V(#1)+=comp(vGrad(#1).Normal())(:,i,k,k).F(i);";
+    // else if (mf.get_qdim() > size_type(1) &&
+    //          Q == size_type(mf.get_qdim()*gmm::sqr(mf.linked_mesh().dim())))
+    //   s = "F=data(qdim(#1),mdim(#1),mdim(#1));"
+    //     "V(#1)+=comp(vGrad(#1).Normal().Normal().Normal())"
+    //     "(:,i,k,k,l,m).F(i,l,m);";
+    // else
+    //   GMM_ASSERT1(false, "invalid rhs vector");
+    // asm_real_or_complex_1_param(B, mim, mf, mf, F, rg, s);
+
     const char *s;
     if (mf.get_qdim() == 1 && Q == 1)
-      s = "F=data(1);"
-        "V(#1)+=comp(Grad(#1).Normal())(:,i,i).F(1);";
+      s = "Test_Grad_u.(A*Normal)";
     else if (mf.get_qdim() == 1 && Q == gmm::sqr(mf.linked_mesh().dim()))
-      s = "F=data(mdim(#1),mdim(#1));"
-        "V(#1)+=comp(Grad(#1).Normal().Normal().Normal())"
-        "(:,i,i,l,j).F(l,j);";
+      s = "Test_Grad_u.(((Reshape(A,meshdim,meshdim)*Normal).Normal)*Normal)";
     else if (mf.get_qdim() > size_type(1) && Q == mf.get_qdim())
-      s = "F=data(qdim(#1));"
-        "V(#1)+=comp(vGrad(#1).Normal())(:,i,k,k).F(i);";
+      s = "((Test_Grad_u')*A).Normal";
     else if (mf.get_qdim() > size_type(1) &&
              Q == size_type(mf.get_qdim()*gmm::sqr(mf.linked_mesh().dim())))
-      s = "F=data(qdim(#1),mdim(#1),mdim(#1));"
-        "V(#1)+=comp(vGrad(#1).Normal().Normal().Normal())"
-        "(:,i,k,k,l,m).F(i,l,m);";
+      s = "((((Test_Grad_u').Reshape(A,qdim(u),meshdim,meshdim)).Normal).Normal).Normal";
     else
       GMM_ASSERT1(false, "invalid rhs vector");
-    asm_real_or_complex_1_param(B, mim, mf, mf, F, rg, s);
+    asm_real_or_complex_1_param_vec(B, mim, mf, 0, F, rg, s);
   }
 
 
@@ -352,9 +380,11 @@ namespace getfem {
       if (!R_must_be_derivated) {
         asm_normal_source_term(R, mim, mf_mult, mf_r, r_data, rg);
       } else {
-        asm_real_or_complex_1_param
-          (R, mim, mf_mult, mf_r, r_data, rg,
-           "R=data(#2); V(#1)+=comp(Base(#1).Grad(#2).Normal())(:,i,j,j).R(i)");
+	asm_real_or_complex_1_param_vec(R, mim, mf_mult, &mf_r, r_data, rg,
+					"(Grad_A.Normal)*Test_u");
+        // asm_real_or_complex_1_param
+        //   (R, mim, mf_mult, mf_r, r_data, rg,
+        //    "R=data(#2); V(#1)+=comp(Base(#1).Grad(#2).Normal())(:,i,j,j).R(i)");
       }
     }
   }
diff --git a/src/getfem/getfem_generic_assembly.h b/src/getfem/getfem_generic_assembly.h
index 9ede7d4..045451c 100644
--- a/src/getfem/getfem_generic_assembly.h
+++ b/src/getfem/getfem_generic_assembly.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2013-2016 Yves Renard
+ Copyright (C) 2013-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -40,8 +40,8 @@
 #define GETFEM_GENERIC_ASSEMBLY_H__
 
 #include <map>
-#include "getfem/getfem_models.h"
 #include "getfem/getfem_interpolation.h"
+#include "getfem/getfem_mesh_slice.h"
 
 
 #ifdef _WIN32
@@ -54,11 +54,82 @@
 
 namespace getfem {
 
-  class ga_tree;
+  struct ga_tree;
+  class model;
+  class ga_workspace;
+
+  typedef gmm::rsvector<scalar_type> model_real_sparse_vector;
+  typedef gmm::rsvector<complex_type> model_complex_sparse_vector;
+  typedef std::vector<scalar_type> model_real_plain_vector;
+  typedef std::vector<complex_type> model_complex_plain_vector;
+
+  typedef gmm::col_matrix<model_real_sparse_vector> model_real_sparse_matrix;
+  typedef gmm::col_matrix<model_complex_sparse_vector>
+  model_complex_sparse_matrix;
+
+  typedef gmm::row_matrix<model_real_sparse_vector>
+  model_real_row_sparse_matrix;
+  typedef gmm::row_matrix<model_complex_sparse_vector>
+  model_complex_row_sparse_matrix;
+  
 
   int ga_check_name_validity(const std::string &name);
 
   //=========================================================================
+  //  Virtual interpolate_transformation object.
+  //=========================================================================
+
+  struct var_trans_pair {
+    std::string varname, transname;
+    bool operator <(const var_trans_pair &vt) const {
+      return (varname < vt.varname) ||
+             (!(varname > vt.varname) && transname < vt.transname);
+    }
+    var_trans_pair() : varname(), transname() {}
+    var_trans_pair(const std::string &v, const std::string &t)
+      : varname(v), transname(t) {}
+  };
+
+  class APIDECL virtual_interpolate_transformation {
+
+  public:
+    virtual void extract_variables
+    (const ga_workspace &workspace, std::set<var_trans_pair> &vars,
+     bool ignore_data, const mesh &m,
+     const std::string &interpolate_name) const = 0;
+    virtual void init(const ga_workspace &workspace) const = 0;
+    virtual int transform
+    (const ga_workspace &workspace, const mesh &m,
+     fem_interpolation_context &ctx_x, const base_small_vector &Normal,
+     const mesh **m_t, size_type &cv, short_type &face_num,
+     base_node &P_ref, base_small_vector &N_y,
+     std::map<var_trans_pair, base_tensor> &derivatives,
+     bool compute_derivatives) const = 0;
+    virtual void finalize() const = 0;
+
+    virtual ~virtual_interpolate_transformation() {}
+  };
+
+  typedef std::shared_ptr<const virtual_interpolate_transformation>
+  pinterpolate_transformation;
+
+  //=========================================================================
+  //  Virtual elementary_transformation object.
+  //=========================================================================
+
+  class APIDECL virtual_elementary_transformation {
+
+  public:
+    
+    virtual void give_transformation(const mesh_fem &mf, size_type cv,
+                                     base_matrix &M) const = 0;
+    virtual ~virtual_elementary_transformation() {}
+  };
+
+  typedef std::shared_ptr<const virtual_elementary_transformation>
+  pelementary_transformation;
+
+  //=========================================================================
   // Structure dealing with predefined operators.
   //=========================================================================
 
@@ -156,17 +227,23 @@ namespace getfem {
 
     struct tree_description { // CAUTION: Specific copy constructor
       size_type order; // 0: potential, 1: weak form, 2: tangent operator
+      // -1 : interpolation/ assignment all order,
+      // -2 : assignment on potential, -3 : assignment on weak form
+      // -3 : assignment on tangent operator
+      size_type interpolation; // O : assembly, 1 : interpolate before assembly
+                               // 2 : interpolate after assembly. 
+      std::string varname_interpolation; // Where to interpolate
       std::string name_test1, name_test2;
       std::string interpolate_name_test1, interpolate_name_test2;
       const mesh_im *mim;
       const mesh *m;
       const mesh_region *rg;
       ga_tree *ptree;
-      base_vector elem;
       tree_description()
-        : name_test1(""), name_test2(""),
+        : interpolation(0), varname_interpolation(""),
+          name_test1(""), name_test2(""),
           interpolate_name_test1(""), interpolate_name_test2(""),
-          mim(0), m(0), rg(0), ptree(0), elem(0) {}
+          mim(0), m(0), rg(0), ptree(0) {}
       void copy(const tree_description& td);
       tree_description(const tree_description& td) { copy(td); }
       tree_description &operator =(const tree_description& td);
@@ -210,8 +287,9 @@ namespace getfem {
 
     void add_tree(ga_tree &tree, const mesh &m, const mesh_im &mim,
                   const mesh_region &rg,
-                  const std::string &expr, size_type add_derivative_order = 2,
-                  bool scalar_expr = true);
+                  const std::string &expr, size_type add_derivative_order,
+                  bool scalar_expr, size_type for_interpolation,
+		  const std::string varname_interpolation);
 
 
     std::shared_ptr<model_real_sparse_matrix> K;
@@ -254,10 +332,16 @@ namespace getfem {
     /* Internal use */
     void add_function_expression(const std::string &expr);
     /* Internal use */
-    void add_interpolation_expression(const std::string &expr, const mesh &m,
-                                      const mesh_region &rg=mesh_region::all_convexes());
-    void add_interpolation_expression(const std::string &expr, const mesh_im &mim,
-                                      const mesh_region &rg=mesh_region::all_convexes());
+    void add_interpolation_expression
+    (const std::string &expr, const mesh &m,
+     const mesh_region &rg = mesh_region::all_convexes());
+    void add_interpolation_expression
+    (const std::string &expr, const mesh_im &mim,
+     const mesh_region &rg = mesh_region::all_convexes());
+    void add_assignment_expression
+    (const std::string &dataname, const std::string &expr,
+     const mesh_region &rg_ = mesh_region::all_convexes(),
+     size_type order = 1, bool before = false);
 
     /** Delete all previously added expressions. */
     void clear_expressions();
@@ -282,8 +366,10 @@ namespace getfem {
     void add_im_data(const std::string &name, const im_data &imd,
                      const model_real_plain_vector &VV);
 
-    bool used_variables(model::varnamelist &vl, model::varnamelist &vl_test1,
-                        model::varnamelist &vl_test2, model::varnamelist &dl,
+    bool used_variables(std::vector<std::string> &vl,
+			std::vector<std::string> &vl_test1,
+                        std::vector<std::string> &vl_test2,
+			std::vector<std::string> &dl,
                         size_type order);
 
     bool variable_exists(const std::string &name) const;
@@ -325,7 +411,6 @@ namespace getfem {
     bgeot::multi_index qdims(const std::string &name) const;
 
     const model_real_plain_vector &value(const std::string &name) const;
-
     scalar_type get_time_step() const;
 
     // macros
@@ -387,14 +472,14 @@ namespace getfem {
   std::string ga_substitute(const std::string &expr,
                             const std::map<std::string, std::string> &dict);
 
-  inline std::string ga_subsitute(const std::string &expr,
+  inline std::string ga_substitute(const std::string &expr,
                                   const std::string &o1,const std::string &s1) {
     std::map<std::string, std::string> dict;
     dict[o1] = s1;
     return ga_substitute(expr, dict);
   }
 
-  inline std::string ga_subsitute(const std::string &expr,
+  inline std::string ga_substitute(const std::string &expr,
                                   const std::string &o1,const std::string &s1,
                                   const std::string &o2,const std::string &s2) {
     std::map<std::string, std::string> dict;
@@ -402,7 +487,7 @@ namespace getfem {
     return ga_substitute(expr, dict);
   }
 
-  inline std::string ga_subsitute(const std::string &expr,
+  inline std::string ga_substitute(const std::string &expr,
                                   const std::string &o1,const std::string &s1,
                                   const std::string &o2,const std::string &s2,
                                   const std::string &o3,const std::string &s3) {
@@ -411,7 +496,7 @@ namespace getfem {
     return ga_substitute(expr, dict);
   }
 
-  inline std::string ga_subsitute(const std::string &expr,
+  inline std::string ga_substitute(const std::string &expr,
                                   const std::string &o1,const std::string &s1,
                                   const std::string &o2,const std::string &s2,
                                   const std::string &o3,const std::string &s3,
@@ -491,12 +576,19 @@ namespace getfem {
    size_type nbdof_ = size_type(-1));
 
   void ga_interpolation_im_data
+  (ga_workspace &workspace, const im_data &imd, base_vector &result);
+
+  void ga_interpolation_im_data
   (const getfem::model &md, const std::string &expr, const im_data &imd,
    base_vector &result, const mesh_region &rg=mesh_region::all_convexes());
 
-  void ga_interpolation_im_data
-  (ga_workspace &workspace, const im_data &imd, base_vector &result,
-   const mesh_region &rg=mesh_region::all_convexes());
+  void ga_interpolation_mesh_slice
+  (ga_workspace &workspace, const stored_mesh_slice &sl, base_vector &result);
+
+  void ga_interpolation_mesh_slice
+  (const getfem::model &md, const std::string &expr, const stored_mesh_slice &sl,
+   base_vector &result, const mesh_region &rg=mesh_region::all_convexes());
+
 
   //=========================================================================
   // Local projection functions
@@ -532,6 +624,27 @@ namespace getfem {
   (ga_workspace &workspace, const std::string &transname,
    const mesh &source_mesh, const mesh &target_mesh, const std::string &expr);
 
+  /** Add a transformation to the workspace that creates an identity mapping between
+      two meshes in deformed state. Conceptually, it can be viewed as a transformation
+      from expression Xsource + Usource - Utarget, except such an expression
+      cannot be used directly in the transformation from expression (function above),
+      as Utarget needs to be interpolated though an inversion of the transformation of
+      the target domain.
+      Thread safe if added to thread local workspace.
+  */
+  void add_interpolate_transformation_on_deformed_domains
+  (ga_workspace &workspace, const std::string &transname,
+   const mesh &source_mesh, const std::string &source_displacements,
+   const mesh_region &source_region, const mesh &target_mesh,
+   const std::string &target_displacements, const mesh_region &target_region);
+
+  /**.. the same as above, but adding transformation to the model.
+  Note, this version is not thread safe.*/
+  void add_interpolate_transformation_on_deformed_domains
+  (model &md, const std::string &transname,
+   const mesh &source_mesh, const std::string &source_displacements,
+   const mesh_region &source_region, const mesh &target_mesh,
+   const std::string &target_displacements, const mesh_region &target_region);
 
   /** Create a new instance of a transformation corresponding to the
       interpolation on the neighbour element. Can only be applied to the
@@ -540,6 +653,37 @@ namespace getfem {
   */
   pinterpolate_transformation interpolate_transformation_neighbour_instance();
 
+  /* Add a special interpolation transformation which represents the identity
+     transformation but allows to evaluate the expression on another element
+     than the current element by polynomial extrapolation. It is used for
+     stabilization term in fictitious domain applications. the map elt_cor
+     list the element concerned by the transformation and associate them
+     to the element on which the extrapolation has to be made. If an element
+     is not listed in elt_cor the evaluation is just made on the current
+     element.
+  */
+  void add_element_extrapolation_transformation
+  (model &md, const std::string &name, const mesh &sm,
+   std::map<size_type, size_type> &elt_corr);
+
+  void add_element_extrapolation_transformation
+  (ga_workspace &workspace, const std::string &name, const mesh &sm,
+   std::map<size_type, size_type> &elt_corr);
+  
+  /* Change the correspondance map of an element extrapolation interpolate
+     transformation.
+  */
+  void set_element_extrapolation_correspondance
+  (model &md, const std::string &name,
+   std::map<size_type, size_type> &elt_corr);
+  
+  void set_element_extrapolation_correspondance
+  (ga_workspace &workspace, const std::string &name,
+   std::map<size_type, size_type> &elt_corr);
+    
+ 
+
+
 }  /* end of namespace getfem.                                             */
 
 
diff --git a/src/getfem/getfem_global_function.h b/src/getfem/getfem_global_function.h
index 82734f2..6b1c187 100644
--- a/src/getfem/getfem_global_function.h
+++ b/src/getfem/getfem_global_function.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
  Copyright (C) 2016      Konstantinos Poulios
 
  This file is a part of GetFEM++
@@ -99,6 +99,7 @@ namespace getfem {
     mutable model_real_plain_vector pt_;
   public:
     virtual scalar_type val(const base_node &pt) const;
+    virtual const base_tensor &tensor_val(const base_node &pt) const;
     virtual void grad(const base_node &pt, base_small_vector &g) const;
     virtual void hess(const base_node &pt, base_matrix &h) const;
 
@@ -117,8 +118,14 @@ namespace getfem {
     virtual scalar_type val(const fem_interpolation_context&) const;
     virtual void grad(const fem_interpolation_context&, base_small_vector&) const;
     virtual void hess(const fem_interpolation_context&, base_matrix&) const;
+    virtual bool is_in_support(const base_node &p) const;
+    virtual void bounding_box(base_node &bmin_, base_node &bmax_) const;
     global_function_sum(const std::vector<pglobal_function> &funcs);
     global_function_sum(pglobal_function f1, pglobal_function f2);
+    global_function_sum(pglobal_function f1, pglobal_function f2,
+                        pglobal_function f3);
+    global_function_sum(pglobal_function f1, pglobal_function f2,
+                        pglobal_function f3, pglobal_function f4);
     virtual ~global_function_sum()
     { DAL_STORED_OBJECT_DEBUG_DESTROYED(this, "Global function sum"); }
   };
@@ -129,6 +136,8 @@ namespace getfem {
     virtual scalar_type val(const fem_interpolation_context&) const;
     virtual void grad(const fem_interpolation_context&, base_small_vector&) const;
     virtual void hess(const fem_interpolation_context&, base_matrix&) const;
+    virtual bool is_in_support(const base_node &p) const;
+    virtual void bounding_box(base_node &bmin_, base_node &bmax_) const;
     global_function_product(pglobal_function f1_, pglobal_function f2_);
     virtual ~global_function_product()
     { DAL_STORED_OBJECT_DEBUG_DESTROYED(this, "Global function product"); }
diff --git a/src/getfem/getfem_im_data.h b/src/getfem/getfem_im_data.h
index 347f592..4106e67 100644
--- a/src/getfem/getfem_im_data.h
+++ b/src/getfem/getfem_im_data.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2012-2016 Liang Jin Lim
+ Copyright (C) 2012-2017 Liang Jin Lim
 
  This file is a part of GetFEM++
 
@@ -28,389 +28,389 @@
  might be covered by the GNU Lesser General Public License.
 
 ===========================================================================*/
-/**
- at file getfem_im_data.h
- at brief Provides indexing of integration points for mesh_im.
- at date Feb 2014
- at author Liang Jin Lim
-*/
-
-#pragma once
-
-#ifndef GETFEM_IM_DATA_H__
-#define GETFEM_IM_DATA_H__
-
-#include <getfem/getfem_mesh_im.h>
-
-namespace getfem{
-  using bgeot::size_type;
-  using bgeot::scalar_type;
-
-  /**check if a given tensor size is equivalent to a vector*/
-  bool is_equivalent_with_vector(const bgeot::multi_index &sizes, size_type vector_size);
-  /**check if a given tensor size is equivalent to a matrix*/
-  bool is_equivalent_with_matrix(const bgeot::multi_index &sizes, size_type nrows, size_type ncols);
-
-  /** im_data provides indexing to the integration points of a mesh
-  im object. The im_data data contains a reference of mesh_im object
-  . The index can be filtered by region, and each im_data has its 
-  own tensorial size.
-
-  Filtered methods will provide filtered index on the region.
-  This class also provides reading and writing tensor( including
-  matrix, vector and scalar) from a vector data (generally a
-  fixed-size variable from the model.)
-  
-  im_data can be used to provide integration point index on convex or
-  on faces of convex, but not both. To create an im_data that represents
-  integration points on a face, the filter region provided has to contain
-  only faces.
-  */
-  class im_data : public context_dependencies, virtual public dal::static_stored_object {
-  public:
-    /**
-    * Constructor
-    * @param mim Reference mesh_im object
-    * @param tensor_size tensor dimension of each integration points
-    * @param filtered_region index not in the region will be filtered
-    *        out. If filtered_region can contain only convexes or only
-    *        faces or both convexes and faces.
-    */
-    im_data(const mesh_im& mim_, bgeot::multi_index tensor_size,
-            size_type filtered_region_ = size_type(-1));
-
-    /**
-    * Constructor. The tensor size by default is a scalar value.
-    * @param mim Reference mesh_im object
-    * @param filtered_region index not in the region will be filtered
-    *        out. If filtered_region can contain only convexes or only
-    *        faces or both convexes and faces.
-    */
-    im_data(const mesh_im& mim_, size_type filtered_region_ = size_type(-1));
-
-    /**set filtered region id*/
-    void set_region(size_type region);
-
-    /**return filtered region id*/
-    inline size_type filtered_region() const {return region_;}
-
-    /**Returns the index of an integration point with no filtering*/
-    size_type index_of_point(size_type cv, size_type i,
-                             bool use_filter = false) const;
-
-    /**Returns the index of an integration point with filtering*/
-    size_type filtered_index_of_point(size_type cv, size_type i) const;
-
-    /**Returns the index of the first integration point with no filtering*/
-    size_type index_of_first_point(size_type cv, short_type f = short_type(-1),
-                                   bool use_filter = false) const;
-
-    /**Returns the index of the first integration point with filtering*/
-    size_type filtered_index_of_first_point(size_type cv, short_type f = short_type(-1)) const;
-
-    /**Total numbers of index (integration points)*/
-    size_type nb_index(bool use_filter=false) const;
-
-    /**Total numbers of filtered index (integration points)*/
-    size_type nb_filtered_index() const
-    { return nb_index(true); }
-
-    /**Total number of points in element cv*/
-    size_type nb_points_of_element(size_type cv, bool use_filter=false) const;
-
-    /**Number of points in element cv, on face f (or in the interior)*/
-    size_type nb_points_of_element(size_type cv, short_type f, bool use_filter=false) const;
-
-    /**Total number of points in element cv, which lie in filtered_region()*/
-    size_type nb_filtered_points_of_element(size_type cv) const
-    { return nb_points_of_element(cv, true); }
-
-    /**Number of points in element cv, on face f (or in the interior),
-    which lie in filtered_region()*/
-    size_type nb_filtered_points_of_element(size_type cv, short_type f) const
-    { return nb_points_of_element(cv, f, true); }
-
-    /**Number of (active) faces in element cv*/
-    short_type nb_faces_of_element(size_type cv) const;
-
-    /**sum of tensor elements, M(3,3) will have 3*3=9 elements*/
-    size_type nb_tensor_elem() const;
-
-    /**List of convexes*/
-    dal::bit_vector convex_index(bool use_filter=false) const;
-
-    /**List of convex in filtered region*/
-    dal::bit_vector filtered_convex_index() const
-    { return convex_index(true); }
-
-    /**called automatically when there is a change in dependencies*/
-    void update_from_context () const;
-
-    /**linked mesh im*/
-    inline const mesh_im &linked_mesh_im() const { return im_; }
-
-    /**implicit conversion to mesh im*/
-    inline operator const mesh_im &() const { return im_; }
-
-    /**linked mesh*/
-    inline const mesh &linked_mesh () const { return im_.linked_mesh(); }
-
-    getfem::papprox_integration approx_int_method_of_element(size_type cv) const
-    { return im_.int_method_of_element(cv)->approx_method(); }
-
-    inline const bgeot::multi_index& tensor_size () const { return tensor_size_;}
-
-    void set_tensor_size (const bgeot::multi_index& tensor_size);
-
-    inline gmm::uint64_type version_number() const { context_check(); return v_num_; }
-
-    /**Extend a vector from filtered size to full size and copy the data to correct index*/
-    template <typename VECT>
-    void extend_vector(const VECT &V1, VECT &V2) const {
-      if (V1.size() == 0 && V2.size() == 0)
-        return;
-      size_type nb_data = V1.size()/nb_filtered_index();
-      GMM_ASSERT1(V1.size() == nb_data*nb_filtered_index(), "Invalid size of vector V1");
-      GMM_ASSERT1(V2.size() == nb_data*nb_index(), "Invalid size of vector V2");
-      if (nb_filtered_index() == nb_index()) {
-        gmm::copy(V1, V2);
-        return;
-      }
-
-      const getfem::mesh_region &rg = im_.linked_mesh().region(filtered_region());
-      for (getfem::mr_visitor v(rg); !v.finished(); ++v) {
-        size_type nb_pts = nb_points_of_element(v.cv(), v.f());
-        size_type first_id = (v.f() == short_type(-1))
-                           ? convexes[v.cv()].first_int_pt_id
-                           : convexes[v.cv()].first_int_pt_onface_id[v.f()];
-        size_type first_fid = (v.f() == short_type(-1))
-                            ? convexes[v.cv()].first_int_pt_fid
-                            : convexes[v.cv()].first_int_pt_onface_fid[v.f()];
-        if (first_fid != size_type(-1))
-          gmm::copy(
-            gmm::sub_vector(V1, gmm::sub_interval(first_fid*nb_data, nb_pts*nb_data)),
-            gmm::sub_vector(V2, gmm::sub_interval(first_id*nb_data, nb_pts*nb_data)));
-      }
-    }
-
-    /**Filter a vector from full size to filtered size and copy the data to correct index*/    
-    template <typename VECT>
-    void reduce_vector(const VECT &V1, VECT &V2) const {
-      if (V1.size() == 0 && V2.size() == 0)
-        return;
-      size_type nb_data = V1.size()/nb_index();
-      GMM_ASSERT1(V1.size() == nb_data*nb_index(), "Invalid size of vector V1");
-      GMM_ASSERT1(V2.size() == nb_data*nb_filtered_index(), 
-                               "Invalid size of vector V2");
-      if (nb_filtered_index() == nb_index()) {
-        gmm::copy(V1, V2);
-        return;
-      }
-
-      const getfem::mesh_region &rg = im_.linked_mesh().region(filtered_region());
-      for (getfem::mr_visitor v(rg); !v.finished(); ++v) {
-        size_type nb_pts = nb_points_of_element(v.cv(), v.f());
-        size_type first_id = (v.f() == short_type(-1))
-                           ? convexes[v.cv()].first_int_pt_id
-                           : convexes[v.cv()].first_int_pt_onface_id[v.f()];
-        size_type first_fid = (v.f() == short_type(-1))
-                            ? convexes[v.cv()].first_int_pt_fid
-                            : convexes[v.cv()].first_int_pt_onface_fid[v.f()];
-        if (first_fid != size_type(-1))
-          gmm::copy(
-            gmm::sub_vector(V1, gmm::sub_interval(first_id*nb_data, nb_pts*nb_data)),
-            gmm::sub_vector(V2, gmm::sub_interval(first_fid*nb_data, nb_pts*nb_data)));
-      }
-    }
-
-    /**get a scalar value of an integration point 
-    from a raw vector data, described by the tensor size.*/
-    template <typename VECT>
-    typename VECT::value_type get_value(const VECT &V1, size_type cv,
-                                        size_type i, bool use_filter = true) const {
-      GMM_ASSERT1(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
-                  "Invalid tensorial size for vector V1");
-      GMM_ASSERT1(nb_tensor_elem_ == 1, "im_data is not of scalar type");
-      size_type ptid = index_of_point(cv,i,use_filter);
-      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
-      return V1[ptid];
-    }
-
-    /**get a vector of an integration point 
-    from a raw vector data, described by the tensor size.*/
-    template <typename VECT1, typename VECT2>
-    void get_vector(const VECT1 &V1, size_type cv, size_type i,
-                    VECT2& V2, bool use_filter = true) const {
-      if (V1.size() == 0 && V2.size() == 0)
-        return;
-      GMM_ASSERT1(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
-                  "Invalid tensorial size for vector V1");
-      GMM_ASSERT1(is_equivalent_with_vector(tensor_size_, V2.size()),
-                  "V2 is incompatible with im_data tensor size");
-      size_type ptid = index_of_point(cv,i,use_filter);
-      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
-      gmm::copy(gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
-                                                      nb_tensor_elem_)),
-                V2);
-    }
-
-    /**get a matrix of an integration point 
-    from a raw vector data, described by the tensor size.*/
-    template <typename VECT, typename MAT>
-    void get_matrix(const VECT &V1, size_type cv, size_type i, 
-                    MAT& M, bool use_filter = true) const {
-      if (V1.size() == 0 && M.size() == 0)
-        return;
-      GMM_ASSERT1(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
-                  "Invalid tensorial size for vector V1");
-      GMM_ASSERT1(is_equivalent_with_matrix(tensor_size_, M.nrows(), M.ncols()),
-                  "M is incompatible with im_data tensor size");
-      size_type ptid = index_of_point(cv,i,use_filter);
-      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
-      gmm::copy(gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
-                                                      nb_tensor_elem_)),
-                M.as_vector());
-    }
-
-    /**get a tensor of an integration point 
-    from a raw vector data, described by the tensor size.*/
-    template <typename VECT, typename TENSOR>
-    void get_tensor(const VECT &V1, size_type cv, size_type i, 
-                    TENSOR& T, bool use_filter = true) const {
-      if (V1.size() == 0 && T.size() == 0)
-        return;
-      GMM_ASSERT1(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
-                  "Invalid tensorial size for vector V1");
-      GMM_ASSERT1(tensor_size_ == T.sizes(),
-                  "T is incompatible with im_data tensor size");
-      size_type ptid = index_of_point(cv,i,use_filter);
-      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
-      gmm::copy(gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
-                                                      nb_tensor_elem_)),
-                T.as_vector());
-    }
-
-    /**set a value of an integration point 
-    from a raw vector data, described by the tensor size.*/
-    template <typename VECT>
-    typename VECT::value_type &set_value(VECT &V1, size_type cv, size_type i,
-                                         bool use_filter = true) const {
-      GMM_ASSERT1(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
-                  "Invalid tensorial size for vector V1");
-      GMM_ASSERT1(nb_tensor_elem_ == 1, "im_data is not of scalar type");
-      size_type ptid = index_of_point(cv,i,use_filter);
-      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
-      return V1[ptid];
-    }
-
-    /**set a vector of an integration point 
-    from a raw vector data, described by the tensor size.*/
-    template <typename VECT1, typename VECT2>
-    void set_vector(VECT1 &V1, size_type cv, size_type i, 
-                    const VECT2& V2, bool use_filter = true) const {
-      if (V1.size() == 0 && V2.size() == 0)
-        return;
-      GMM_ASSERT1(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
-                  "Invalid tensorial size for vector V1");
-      GMM_ASSERT1(is_equivalent_with_vector(tensor_size_, V2.size()),
-                  "V2 is incompatible with im_data tensor size");
-      size_type ptid = index_of_point(cv,i,use_filter);
-      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
-      gmm::copy(V2,
-                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
-                                                      nb_tensor_elem_)));
-    }
-
-    /**set a matrix of an integration point 
-    from a raw vector data, described by the tensor size.*/
-    template <typename VECT, typename MAT>
-    void set_matrix(VECT &V1, size_type cv, size_type i, 
-                    const MAT& M, bool use_filter = true) const {
-      if (V1.size() == 0 && M.size() == 0)
-        return;
-      GMM_ASSERT1(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
-                  "Invalid tensorial size for vector V1");
-      GMM_ASSERT1(is_equivalent_with_matrix(tensor_size_, M.nrows(), M.ncols()),
-                  "M is incompatible with im_data tensor size");
-      size_type ptid = index_of_point(cv,i,use_filter);
-      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
-      gmm::copy(M.as_vector(),
-                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
-                                                      nb_tensor_elem_)));
-    }
-
-    /**set a tensor of an integration point 
-    from a raw vector data, described by the tensor size.*/
-    template <typename VECT, typename TENSOR>
-    void set_tensor(VECT &V1, size_type cv, size_type i,
-                    const TENSOR& T, bool use_filter = true) const {
-      if (V1.size() == 0 && T.size() == 0)
-        return;
-      GMM_ASSERT1(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
-                  "Invalid tensorial size for vector V1");
-      GMM_ASSERT1(tensor_size_ == T.sizes(),
-                  "T is incompatible with im_data tensor size");
-      size_type ptid = index_of_point(cv,i,use_filter);
-      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
-      gmm::copy(T.as_vector(),
-                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
-                                                      nb_tensor_elem_)));
-    }
-
-
-    template <typename VECT1, typename VECT2>
-    void set_vector(VECT1 &V1, size_type ptid, const VECT2& V2) const {
-      GMM_ASSERT1(V1.size() != 0, "V1 of zero size");
-      GMM_ASSERT1(V2.size() != 0, "V2 of zero size");
-      GMM_ASSERT1(is_equivalent_with_vector(tensor_size_, V2.size()),
-                  "V2 is incompatible with im_data tensor size");
-      gmm::copy(V2,
-                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
-                                                      nb_tensor_elem_)));
-    }
-
-    template <typename VECT1, typename TENSOR>
-    void set_tensor(VECT1 &V1, size_type ptid, const TENSOR& T) const {
-      GMM_ASSERT1(V1.size() != 0, "V1 of zero size");
-      GMM_ASSERT1(T.size() != 0, "V2 of zero size");
-      GMM_ASSERT1(tensor_size_ == T.sizes(),
-                  "T is incompatible with im_data tensor size");
-      gmm::copy(T.as_vector(),
-                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
-                                                      nb_tensor_elem_)));
-    }
-
-  private:
-    const mesh_im &im_;
-
-    size_type              region_;
-
-    mutable size_type      nb_int_pts_intern;
-    mutable size_type      nb_int_pts_onfaces;
-    mutable size_type      nb_filtered_int_pts_intern;
-    mutable size_type      nb_filtered_int_pts_onfaces;
-
-    struct convex_data {
-      size_type first_int_pt_id;   // index
-      size_type first_int_pt_fid;  // filtered index
-      size_type nb_int_pts;        // number of internal integration points
-      std::vector<size_type> first_int_pt_onface_id;
-      std::vector<size_type> first_int_pt_onface_fid;
-      std::vector<size_type> nb_int_pts_onface;
-
-      convex_data()
-        : first_int_pt_id(-1), first_int_pt_fid(-1), nb_int_pts(0),
-          first_int_pt_onface_id(0), first_int_pt_onface_fid(0), nb_int_pts_onface(0)
-      {}
-    };
-
-    mutable std::vector<convex_data> convexes;
-
-    mutable gmm::uint64_type v_num_;
-
-    bgeot::multi_index     tensor_size_;
-    size_type              nb_tensor_elem_;
-    lock_factory           locks_;
-  };
-}
-#endif /* GETFEM_IM_DATA_H__  */
+/**
+ at file getfem_im_data.h
+ at brief Provides indexing of integration points for mesh_im.
+ at date Feb 2014
+ at author Liang Jin Lim
+*/
+
+#pragma once
+
+#ifndef GETFEM_IM_DATA_H__
+#define GETFEM_IM_DATA_H__
+
+#include <getfem/getfem_mesh_im.h>
+
+namespace getfem{
+  using bgeot::size_type;
+  using bgeot::scalar_type;
+
+  /**check if a given tensor size is equivalent to a vector*/
+  bool is_equivalent_with_vector(const bgeot::multi_index &sizes, size_type vector_size);
+  /**check if a given tensor size is equivalent to a matrix*/
+  bool is_equivalent_with_matrix(const bgeot::multi_index &sizes, size_type nrows, size_type ncols);
+
+  /** im_data provides indexing to the integration points of a mesh
+  im object. The im_data data contains a reference of mesh_im object
+  . The index can be filtered by region, and each im_data has its 
+  own tensorial size.
+
+  Filtered methods will provide filtered index on the region.
+  This class also provides reading and writing tensor( including
+  matrix, vector and scalar) from a vector data (generally a
+  fixed-size variable from the model.)
+  
+  im_data can be used to provide integration point index on convex or
+  on faces of convex, but not both. To create an im_data that represents
+  integration points on a face, the filter region provided has to contain
+  only faces.
+  */
+  class im_data : public context_dependencies, virtual public dal::static_stored_object {
+  public:
+    /**
+    * Constructor
+    * @param mim Reference mesh_im object
+    * @param tensor_size tensor dimension of each integration points
+    * @param filtered_region index not in the region will be filtered
+    *        out. If filtered_region can contain only convexes or only
+    *        faces or both convexes and faces.
+    */
+    im_data(const mesh_im& mim_, bgeot::multi_index tensor_size,
+            size_type filtered_region_ = size_type(-1));
+
+    /**
+    * Constructor. The tensor size by default is a scalar value.
+    * @param mim Reference mesh_im object
+    * @param filtered_region index not in the region will be filtered
+    *        out. If filtered_region can contain only convexes or only
+    *        faces or both convexes and faces.
+    */
+    im_data(const mesh_im& mim_, size_type filtered_region_ = size_type(-1));
+
+    /**set filtered region id*/
+    void set_region(size_type region);
+
+    /**return filtered region id*/
+    inline size_type filtered_region() const {return region_;}
+
+    /**Returns the index of an integration point with no filtering*/
+    size_type index_of_point(size_type cv, size_type i,
+                             bool use_filter = false) const;
+
+    /**Returns the index of an integration point with filtering*/
+    size_type filtered_index_of_point(size_type cv, size_type i) const;
+
+    /**Returns the index of the first integration point with no filtering*/
+    size_type index_of_first_point(size_type cv, short_type f = short_type(-1),
+                                   bool use_filter = false) const;
+
+    /**Returns the index of the first integration point with filtering*/
+    size_type filtered_index_of_first_point(size_type cv, short_type f = short_type(-1)) const;
+
+    /**Total numbers of index (integration points)*/
+    size_type nb_index(bool use_filter=false) const;
+
+    /**Total numbers of filtered index (integration points)*/
+    size_type nb_filtered_index() const
+    { return nb_index(true); }
+
+    /**Total number of points in element cv*/
+    size_type nb_points_of_element(size_type cv, bool use_filter=false) const;
+
+    /**Number of points in element cv, on face f (or in the interior)*/
+    size_type nb_points_of_element(size_type cv, short_type f, bool use_filter=false) const;
+
+    /**Total number of points in element cv, which lie in filtered_region()*/
+    size_type nb_filtered_points_of_element(size_type cv) const
+    { return nb_points_of_element(cv, true); }
+
+    /**Number of points in element cv, on face f (or in the interior),
+    which lie in filtered_region()*/
+    size_type nb_filtered_points_of_element(size_type cv, short_type f) const
+    { return nb_points_of_element(cv, f, true); }
+
+    /**Number of (active) faces in element cv*/
+    short_type nb_faces_of_element(size_type cv) const;
+
+    /**sum of tensor elements, M(3,3) will have 3*3=9 elements*/
+    size_type nb_tensor_elem() const;
+
+    /**List of convexes*/
+    dal::bit_vector convex_index(bool use_filter=false) const;
+
+    /**List of convex in filtered region*/
+    dal::bit_vector filtered_convex_index() const
+    { return convex_index(true); }
+
+    /**called automatically when there is a change in dependencies*/
+    void update_from_context () const;
+
+    /**linked mesh im*/
+    inline const mesh_im &linked_mesh_im() const { return im_; }
+
+    /**implicit conversion to mesh im*/
+    inline operator const mesh_im &() const { return im_; }
+
+    /**linked mesh*/
+    inline const mesh &linked_mesh () const { return im_.linked_mesh(); }
+
+    getfem::papprox_integration approx_int_method_of_element(size_type cv) const
+    { return im_.int_method_of_element(cv)->approx_method(); }
+
+    inline const bgeot::multi_index& tensor_size () const { return tensor_size_;}
+
+    void set_tensor_size (const bgeot::multi_index& tensor_size);
+
+    inline gmm::uint64_type version_number() const { context_check(); return v_num_; }
+
+    /**Extend a vector from filtered size to full size and copy the data to correct index*/
+    template <typename VECT>
+    void extend_vector(const VECT &V1, VECT &V2) const {
+      if (V1.size() == 0 && V2.size() == 0)
+        return;
+      size_type nb_data = V1.size()/nb_filtered_index();
+      GMM_ASSERT2(V1.size() == nb_data*nb_filtered_index(), "Invalid size of vector V1");
+      GMM_ASSERT2(V2.size() == nb_data*nb_index(), "Invalid size of vector V2");
+      if (nb_filtered_index() == nb_index()) {
+        gmm::copy(V1, V2);
+        return;
+      }
+
+      const getfem::mesh_region &rg = im_.linked_mesh().region(filtered_region());
+      for (getfem::mr_visitor v(rg); !v.finished(); ++v) {
+        size_type nb_pts = nb_points_of_element(v.cv(), v.f());
+        size_type first_id = (v.f() == short_type(-1))
+                           ? convexes[v.cv()].first_int_pt_id
+                           : convexes[v.cv()].first_int_pt_onface_id[v.f()];
+        size_type first_fid = (v.f() == short_type(-1))
+                            ? convexes[v.cv()].first_int_pt_fid
+                            : convexes[v.cv()].first_int_pt_onface_fid[v.f()];
+        if (first_fid != size_type(-1))
+          gmm::copy(
+            gmm::sub_vector(V1, gmm::sub_interval(first_fid*nb_data, nb_pts*nb_data)),
+            gmm::sub_vector(V2, gmm::sub_interval(first_id*nb_data, nb_pts*nb_data)));
+      }
+    }
+
+    /**Filter a vector from full size to filtered size and copy the data to correct index*/    
+    template <typename VECT>
+    void reduce_vector(const VECT &V1, VECT &V2) const {
+      if (V1.size() == 0 && V2.size() == 0)
+        return;
+      size_type nb_data = V1.size()/nb_index();
+      GMM_ASSERT2(V1.size() == nb_data*nb_index(), "Invalid size of vector V1");
+      GMM_ASSERT2(V2.size() == nb_data*nb_filtered_index(), 
+                               "Invalid size of vector V2");
+      if (nb_filtered_index() == nb_index()) {
+        gmm::copy(V1, V2);
+        return;
+      }
+
+      const getfem::mesh_region &rg = im_.linked_mesh().region(filtered_region());
+      for (getfem::mr_visitor v(rg); !v.finished(); ++v) {
+        size_type nb_pts = nb_points_of_element(v.cv(), v.f());
+        size_type first_id = (v.f() == short_type(-1))
+                           ? convexes[v.cv()].first_int_pt_id
+                           : convexes[v.cv()].first_int_pt_onface_id[v.f()];
+        size_type first_fid = (v.f() == short_type(-1))
+                            ? convexes[v.cv()].first_int_pt_fid
+                            : convexes[v.cv()].first_int_pt_onface_fid[v.f()];
+        if (first_fid != size_type(-1))
+          gmm::copy(
+            gmm::sub_vector(V1, gmm::sub_interval(first_id*nb_data, nb_pts*nb_data)),
+            gmm::sub_vector(V2, gmm::sub_interval(first_fid*nb_data, nb_pts*nb_data)));
+      }
+    }
+
+    /**get a scalar value of an integration point 
+    from a raw vector data, described by the tensor size.*/
+    template <typename VECT>
+    typename VECT::value_type get_value(const VECT &V1, size_type cv,
+                                        size_type i, bool use_filter = true) const {
+      GMM_ASSERT2(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
+                  "Invalid tensorial size for vector V1");
+      GMM_ASSERT2(nb_tensor_elem_ == 1, "im_data is not of scalar type");
+      size_type ptid = index_of_point(cv,i,use_filter);
+      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
+      return V1[ptid];
+    }
+
+    /**get a vector of an integration point 
+    from a raw vector data, described by the tensor size.*/
+    template <typename VECT1, typename VECT2>
+    void get_vector(const VECT1 &V1, size_type cv, size_type i,
+                    VECT2& V2, bool use_filter = true) const {
+      if (V1.size() == 0 && V2.size() == 0)
+        return;
+      GMM_ASSERT2(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
+                  "Invalid tensorial size for vector V1");
+      GMM_ASSERT2(is_equivalent_with_vector(tensor_size_, V2.size()),
+                  "V2 is incompatible with im_data tensor size");
+      size_type ptid = index_of_point(cv,i,use_filter);
+      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
+      gmm::copy(gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
+                                                      nb_tensor_elem_)),
+                V2);
+    }
+
+    /**get a matrix of an integration point 
+    from a raw vector data, described by the tensor size.*/
+    template <typename VECT, typename MAT>
+    void get_matrix(const VECT &V1, size_type cv, size_type i, 
+                    MAT& M, bool use_filter = true) const {
+      if (V1.size() == 0 && M.size() == 0)
+        return;
+      GMM_ASSERT2(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
+                  "Invalid tensorial size for vector V1");
+      GMM_ASSERT2(is_equivalent_with_matrix(tensor_size_, M.nrows(), M.ncols()),
+                  "M is incompatible with im_data tensor size");
+      size_type ptid = index_of_point(cv,i,use_filter);
+      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
+      gmm::copy(gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
+                                                      nb_tensor_elem_)),
+                M.as_vector());
+    }
+
+    /**get a tensor of an integration point 
+    from a raw vector data, described by the tensor size.*/
+    template <typename VECT, typename TENSOR>
+    void get_tensor(const VECT &V1, size_type cv, size_type i, 
+                    TENSOR& T, bool use_filter = true) const {
+      if (V1.size() == 0 && T.size() == 0)
+        return;
+      GMM_ASSERT2(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
+                  "Invalid tensorial size for vector V1");
+      GMM_ASSERT2(tensor_size_ == T.sizes(),
+                  "T is incompatible with im_data tensor size");
+      size_type ptid = index_of_point(cv,i,use_filter);
+      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
+      gmm::copy(gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
+                                                      nb_tensor_elem_)),
+                T.as_vector());
+    }
+
+    /**set a value of an integration point 
+    from a raw vector data, described by the tensor size.*/
+    template <typename VECT>
+    typename VECT::value_type &set_value(VECT &V1, size_type cv, size_type i,
+                                         bool use_filter = true) const {
+      GMM_ASSERT2(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
+                  "Invalid tensorial size for vector V1");
+      GMM_ASSERT2(nb_tensor_elem_ == 1, "im_data is not of scalar type");
+      size_type ptid = index_of_point(cv,i,use_filter);
+      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
+      return V1[ptid];
+    }
+
+    /**set a vector of an integration point 
+    from a raw vector data, described by the tensor size.*/
+    template <typename VECT1, typename VECT2>
+    void set_vector(VECT1 &V1, size_type cv, size_type i, 
+                    const VECT2& V2, bool use_filter = true) const {
+      if (V1.size() == 0 && V2.size() == 0)
+        return;
+      GMM_ASSERT2(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
+                  "Invalid tensorial size for vector V1");
+      GMM_ASSERT2(is_equivalent_with_vector(tensor_size_, V2.size()),
+                  "V2 is incompatible with im_data tensor size");
+      size_type ptid = index_of_point(cv,i,use_filter);
+      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
+      gmm::copy(V2,
+                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
+                                                      nb_tensor_elem_)));
+    }
+
+    /**set a matrix of an integration point 
+    from a raw vector data, described by the tensor size.*/
+    template <typename VECT, typename MAT>
+    void set_matrix(VECT &V1, size_type cv, size_type i, 
+                    const MAT& M, bool use_filter = true) const {
+      if (V1.size() == 0 && M.size() == 0)
+        return;
+      GMM_ASSERT2(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
+                  "Invalid tensorial size for vector V1");
+      GMM_ASSERT2(is_equivalent_with_matrix(tensor_size_, M.nrows(), M.ncols()),
+                  "M is incompatible with im_data tensor size");
+      size_type ptid = index_of_point(cv,i,use_filter);
+      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
+      gmm::copy(M.as_vector(),
+                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
+                                                      nb_tensor_elem_)));
+    }
+
+    /**set a tensor of an integration point 
+    from a raw vector data, described by the tensor size.*/
+    template <typename VECT, typename TENSOR>
+    void set_tensor(VECT &V1, size_type cv, size_type i,
+                    const TENSOR& T, bool use_filter = true) const {
+      if (V1.size() == 0 && T.size() == 0)
+        return;
+      GMM_ASSERT2(nb_tensor_elem_*nb_index(use_filter) == V1.size(),
+                  "Invalid tensorial size for vector V1");
+      GMM_ASSERT2(tensor_size_ == T.sizes(),
+                  "T is incompatible with im_data tensor size");
+      size_type ptid = index_of_point(cv,i,use_filter);
+      GMM_ASSERT2(ptid != size_type(-1), "Point index of gauss point not found");
+      gmm::copy(T.as_vector(),
+                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
+                                                      nb_tensor_elem_)));
+    }
+
+
+    template <typename VECT1, typename VECT2>
+    void set_vector(VECT1 &V1, size_type ptid, const VECT2& V2) const {
+      GMM_ASSERT2(V1.size() != 0, "V1 of zero size");
+      GMM_ASSERT2(V2.size() != 0, "V2 of zero size");
+      GMM_ASSERT2(is_equivalent_with_vector(tensor_size_, V2.size()),
+                  "V2 is incompatible with im_data tensor size");
+      gmm::copy(V2,
+                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
+                                                      nb_tensor_elem_)));
+    }
+
+    template <typename VECT1, typename TENSOR>
+    void set_tensor(VECT1 &V1, size_type ptid, const TENSOR& T) const {
+      GMM_ASSERT2(V1.size() != 0, "V1 of zero size");
+      GMM_ASSERT2(T.size() != 0, "V2 of zero size");
+      GMM_ASSERT2(tensor_size_ == T.sizes(),
+                  "T is incompatible with im_data tensor size");
+      gmm::copy(T.as_vector(),
+                gmm::sub_vector(V1, gmm::sub_interval(ptid*nb_tensor_elem_,
+                                                      nb_tensor_elem_)));
+    }
+
+  private:
+    const mesh_im &im_;
+
+    size_type              region_;
+
+    mutable size_type      nb_int_pts_intern;
+    mutable size_type      nb_int_pts_onfaces;
+    mutable size_type      nb_filtered_int_pts_intern;
+    mutable size_type      nb_filtered_int_pts_onfaces;
+
+    struct convex_data {
+      size_type first_int_pt_id;   // index
+      size_type first_int_pt_fid;  // filtered index
+      size_type nb_int_pts;        // number of internal integration points
+      std::vector<size_type> first_int_pt_onface_id;
+      std::vector<size_type> first_int_pt_onface_fid;
+      std::vector<size_type> nb_int_pts_onface;
+
+      convex_data()
+        : first_int_pt_id(-1), first_int_pt_fid(-1), nb_int_pts(0),
+          first_int_pt_onface_id(0), first_int_pt_onface_fid(0), nb_int_pts_onface(0)
+      {}
+    };
+
+    mutable std::vector<convex_data> convexes;
+
+    mutable gmm::uint64_type v_num_;
+
+    bgeot::multi_index     tensor_size_;
+    size_type              nb_tensor_elem_;
+    lock_factory           locks_;
+  };
+}
+#endif /* GETFEM_IM_DATA_H__  */
diff --git a/src/getfem/getfem_im_list.h b/src/getfem/getfem_im_list.h
index e30baa3..8d30cdf 100644
--- a/src/getfem/getfem_im_list.h
+++ b/src/getfem/getfem_im_list.h
@@ -2,7 +2,7 @@
 
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_import.h b/src/getfem/getfem_import.h
index b956ee4..34f8f1b 100644
--- a/src/getfem/getfem_import.h
+++ b/src/getfem/getfem_import.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Julien Pommier
+ Copyright (C) 2000-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -54,6 +54,7 @@ namespace getfem {
       - "gid" for meshes generated by GiD http://gid.cimne.upc.es/
          -- mesh nodes are always 3D
 
+
       - "gmsh" for meshes generated by Gmsh http://www.geuz.org/gmsh/
        IMPORTANT NOTE: if you do not assign a physical surface/volume
        to your 3D mesh, the file will also contain the mesh of the
@@ -79,11 +80,14 @@ namespace getfem {
        in Gmsh, that which does not occur in GetFEM++ since there is
        only one "type of region".
 
-      - "am_fmt" for 2D meshes from emc2
-        [http://pauillac.inria.fr/cdrom/prog/unix/emc2/eng.htm]
 
       - "cdb" for meshes generated by ANSYS (in blocked format).
 
+       Currently, plane and solid elements of types 42,45,73,82,87,89,
+       90,92,95,162,182,183,185,186,187 and 191 are supported.
+       This however does not include any finite element techology linked
+       to these elements but only their geometry.
+
        By default GetFEM++ will define mesh regions corresponding to
        material ids found in the imported cdb file, if there are more
        than one material ids available.
@@ -94,6 +98,11 @@ namespace getfem {
        The recommended ANSYS command for generating a mesh file is:
 
        cdwrite,db,filename,cdb
+
+
+      - "am_fmt" for 2D meshes from emc2
+        [http://pauillac.inria.fr/cdrom/prog/unix/emc2/eng.htm]
+
   */
   void import_mesh(const std::string& filename, const std::string& format,
 		   mesh& m);
diff --git a/src/getfem/getfem_integration.h b/src/getfem/getfem_integration.h
index 78ad19f..b3212c3 100644
--- a/src/getfem/getfem_integration.h
+++ b/src/getfem/getfem_integration.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -76,14 +76,19 @@
                close to a polar integration with respect to vertex IP1.
                if IM1 is an integration method on a tetrahedron, gives an
                integration method on a tetrahedron which is close to a
-               cylindrical integration with respect to vertex IP1 (does not work very well).
+               cylindrical integration with respect to vertex IP1
+               (does not work very well).
                if IM1 is an integration method on a prism. Gives an integration
                method on a tetrahedron which is close to a
                cylindrical integration with respect to vertex IP1.
+
    - "IM_QUASI_POLAR(IM1, IP1, IP2)"   : IM1 should be an integration method
                on a prism. Gives an integration method on a tetrahedron which
                is close to a cylindrical integration with respect to IP1-IP2
                axis.
+
+   - "IM_PYRAMID_COMPOSITE(IM1)"       : Composite integration for a pyramid
+                                         decomposed into two tetrahedrons
 */
 #ifndef GETFEM_INTEGRATION_H__
 #define GETFEM_INTEGRATION_H__
diff --git a/src/getfem/getfem_interpolated_fem.h b/src/getfem/getfem_interpolated_fem.h
index 89f69b5..e7d1dad 100644
--- a/src/getfem/getfem_interpolated_fem.h
+++ b/src/getfem/getfem_interpolated_fem.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_interpolation.h b/src/getfem/getfem_interpolation.h
index ee591fe..5ce875e 100644
--- a/src/getfem/getfem_interpolation.h
+++ b/src/getfem/getfem_interpolation.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2001-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2001-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -582,16 +582,29 @@ namespace getfem {
                   "Target fem not convenient for interpolation");
     }
     /* initialisation of the mesh_trans_inv */
+    bool is_target_torus = dynamic_cast<const torus_mesh *>(&mf_target.linked_mesh());
     if (rg_target.id() == mesh_region::all_convexes().id()) {
       size_type nbpts = mf_target.nb_basic_dof() / qdim_t;
-      for (size_type i = 0; i < nbpts; ++i)
-        mti.add_point(mf_target.point_of_basic_dof(i * qdim_t));
+      for (size_type i = 0; i < nbpts; ++i){
+        if (is_target_torus){
+          auto p = mf_target.point_of_basic_dof(i * qdim_t);
+          p.resize(msh.dim());
+          mti.add_point(p);
+        }
+        else mti.add_point(mf_target.point_of_basic_dof(i * qdim_t));
+      }
       interpolation(mf_source, mti, U, V, M, version, extrapolation);
     }
     else {
       for (dal::bv_visitor_c dof(mf_target.basic_dof_on_region(rg_target)); !dof.finished(); ++dof)
-        if (dof % qdim_t == 0)
-          mti.add_point_with_id(mf_target.point_of_basic_dof(dof), dof/qdim_t);
+        if (dof % qdim_t == 0){
+          if (is_target_torus){
+            auto p = mf_target.point_of_basic_dof(dof);
+            p.resize(msh.dim());
+            mti.add_point_with_id(p, dof/qdim_t);
+          }
+          else mti.add_point_with_id(mf_target.point_of_basic_dof(dof), dof/qdim_t);
+        }
       interpolation(mf_source, mti, U, V, M, version, extrapolation, 0, rg_source);
     }
 
@@ -725,17 +738,23 @@ namespace getfem {
     // typedef typename gmm::linalg_traits<const VECT>::value_type T;
 
     dim_type qdim = mf_source.get_qdim();
-    GMM_ASSERT1(qdim == im_target.nb_tensor_elem(),
+    size_type nb_dof = mf_source.nb_dof();
+    size_type nb_basic_dof = mf_source.nb_basic_dof();
+    size_type nodal_data_size = gmm::vect_size(nodal_data);
+    dim_type data_qdim = nodal_data_size / nb_dof;
+
+    GMM_ASSERT1(data_qdim * mf_source.nb_dof() == nodal_data_size,
+                "Incompatible size of mesh fem " << mf_source.nb_dof() * data_qdim <<
+                " with the data " << nodal_data_size);
+
+    GMM_ASSERT1(qdim * data_qdim == im_target.nb_tensor_elem(),
                 "Incompatible size of qdim for mesh_fem " << qdim
                 << " and im_data " << im_target.nb_tensor_elem());
     GMM_ASSERT1(&mf_source.linked_mesh() == &im_target.linked_mesh(),
                 "mf_source and im_data do not share the same mesh.");
 
-    size_type nb_dof = mf_source.nb_dof();
-    size_type nb_basic_dof = mf_source.nb_basic_dof();
-
-    GMM_ASSERT1(nb_dof == gmm::vect_size(nodal_data),
-                "Provided nodal data size is " << gmm::vect_size(nodal_data)
+    GMM_ASSERT1(nb_dof * data_qdim == nodal_data_size,
+                "Provided nodal data size is " << nodal_data_size
                 << " but expecting vector size of " << nb_dof);
 
     size_type size_im_data = im_target.nb_index(use_im_data_filter)
@@ -744,7 +763,7 @@ namespace getfem {
                 "Provided im data size is " << gmm::vect_size(int_pt_data)
                 << " but expecting vector size of " << size_im_data);
 
-    VECT extended_nodal_data_((nb_dof != nb_basic_dof) ? nb_basic_dof : 0);
+    VECT extended_nodal_data_((nb_dof != nb_basic_dof) ? nb_basic_dof * data_qdim : 0);
     if (nb_dof != nb_basic_dof)
       mf_source.extend_vector(nodal_data, extended_nodal_data_);
     const VECT &extended_nodal_data = (nb_dof == nb_basic_dof) ? nodal_data : extended_nodal_data_;
@@ -783,7 +802,7 @@ namespace getfem {
         fem_interpolation_context ctx(pgt, pfp, size_type(-1), G, cv);
         for (size_type i = 0; i < nb_int_pts; ++i, ++int_pt_id) {
           ctx.set_ii(i);
-          ctx.pf()->interpolation(ctx, coeff, tensor_int_point.as_vector(), qdim);
+          ctx.pf()->interpolation(ctx, coeff, tensor_int_point.as_vector(), qdim * data_qdim);
           im_target.set_tensor(int_pt_data, int_pt_id, tensor_int_point);
         }
       }
@@ -798,7 +817,7 @@ namespace getfem {
           size_type i0 = pim->ind_first_point_on_face(f);
           for (size_type i = 0; i < nb_int_pts; ++i, ++int_pt_id) {
             ctx.set_ii(i+i0);
-            ctx.pf()->interpolation(ctx, coeff, tensor_int_point.as_vector(), qdim);
+            ctx.pf()->interpolation(ctx, coeff, tensor_int_point.as_vector(), qdim * data_qdim);
             im_target.set_tensor(int_pt_data, int_pt_id, tensor_int_point);
           }
         }
diff --git a/src/getfem/getfem_level_set.h b/src/getfem/getfem_level_set.h
index 2927fa7..0ea6e17 100644
--- a/src/getfem/getfem_level_set.h
+++ b/src/getfem/getfem_level_set.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard, Julien Pommier
+ Copyright (C) 1999-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_level_set_contact.h b/src/getfem/getfem_level_set_contact.h
index 71fc31b..386629b 100644
--- a/src/getfem/getfem_level_set_contact.h
+++ b/src/getfem/getfem_level_set_contact.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2012-2016 Andriy Andreykiv
+ Copyright (C) 2012-2017 Andriy Andreykiv
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_linearized_plates.h b/src/getfem/getfem_linearized_plates.h
index 3ee8c83..d8c90fc 100644
--- a/src/getfem/getfem_linearized_plates.h
+++ b/src/getfem/getfem_linearized_plates.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard, Jeremie Lasry
+ Copyright (C) 2004-2017 Yves Renard, Jeremie Lasry
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mat_elem.h b/src/getfem/getfem_mat_elem.h
index 5941cf5..13f08ea 100644
--- a/src/getfem/getfem_mat_elem.h
+++ b/src/getfem/getfem_mat_elem.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mat_elem_type.h b/src/getfem/getfem_mat_elem_type.h
index e98837c..958beec 100644
--- a/src/getfem/getfem_mat_elem_type.h
+++ b/src/getfem/getfem_mat_elem_type.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mesh.h b/src/getfem/getfem_mesh.h
index 489e8ee..cf67b83 100644
--- a/src/getfem/getfem_mesh.h
+++ b/src/getfem/getfem_mesh.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -171,18 +171,13 @@ namespace getfem {
     inline std::string get_name() const {return name_;}
     void update_from_context() const {}
     /// Mesh dimension.
-    dim_type dim() const { return pts.dim(); }
+    using basic_mesh::dim;
     /// Return the array of PT.
-    const PT_TAB &points() const { return pts; }
-    /// Return the array of PT.
-    PT_TAB &points() { return pts; }
+    using basic_mesh::points;
+    PT_TAB &points() { return pts; } // non-const version
 
     /// Return a (pseudo)container of the points of a given convex
-    ref_mesh_pt_ct points_of_convex(size_type ic) const {
-      const ind_cv_ct &rct = ind_points_of_convex(ic);
-      return ref_mesh_pt_ct(pts.begin(), rct.begin(), rct.end());
-    }
-
+    using basic_mesh::points_of_convex;
     /// Return a (pseudo)container of points of face of a given convex
     ref_mesh_face_pt_ct points_of_face_of_convex(size_type ic,
                                                  short_type f) const {
@@ -194,21 +189,7 @@ namespace getfem {
     ref_convex convex(size_type ic) const
     { return ref_convex(structure_of_convex(ic), points_of_convex(ic)); }
 
-    /** Add the point pt to the mesh and return the index of the
-        point.
-
-        If the point is too close to an existing point and remove_duplicated_nodes = true,
-        the function does not create a new point, and returns the index of the
-        already existing point.
-        @param pt the point coordinates.
-    */
-    size_type add_point(const base_node &pt,
-                        const scalar_type tol=scalar_type(0),
-                        bool remove_duplicated_nodes = true) {
-      return pts.add_node(pt, tol, remove_duplicated_nodes);
-    }
-    //                        scalar_type characteristic_size = scalar_type(1));
-
+    using basic_mesh::add_point;
     /// Give the number of geometrical nodes in the mesh.
     size_type nb_points() const { return pts.card(); }
     /// Return the points index
@@ -227,14 +208,8 @@ namespace getfem {
     */
     size_type search_point(const base_node &pt, const scalar_type radius=0) const
     { return pts.search_node(pt,radius); }
-    /** Return the bgeot::geometric_trans attached to a convex.
-        @param ic the convex number.
-    */
-    bgeot::pgeometric_trans trans_of_convex(size_type ic) const {
-      GMM_ASSERT1(trans_exists[ic],
-                  "No geometric transformation or nonexisting element");
-      return gtab[ic];
-    }
+
+    using basic_mesh::trans_of_convex;
 
     /// return the version number of the convex ic.
     gmm::uint64_type convex_version_number(size_type ic) const
@@ -304,6 +279,9 @@ namespace getfem {
                                         const base_node &p2,
                                         const base_node &p3,
                                         const base_node &p4);
+    /** Add a pyramid to the mesh, given the point id of its vertices. */
+    size_type add_pyramid(size_type a,
+                          size_type b, size_type c, size_type d, size_type e);
     /** Add a parallelepiped to the mesh.
         @param di dimension of the parallelepiped
         @param ipts iterator on the list of point id.
@@ -468,7 +446,7 @@ namespace getfem {
     void sup_convex_from_regions(size_type cv);
     /** Pack the mesh : renumber convexes and nodes such that there
         is no holes in their numbering. Do NOT do the Cuthill-McKee. */
-    void optimize_structure();
+    void optimize_structure(bool with_renumbering = true);
     /// Return the list of convex IDs for a Cuthill-McKee ordering
     const std::vector<size_type> &cuthill_mckee_ordering() const;
     /// Erase the mesh.
@@ -601,8 +579,6 @@ namespace getfem {
     (dim_type di, const ITER &ps)
   { return add_convex_by_points(bgeot::prism_geotrans(di, 1), ps); }
 
-  typedef mesh *pmesh;
-
   /** rough estimate of the convex area.
       @param pgt the geometric transformation.
       @param pts the convex nodes.
@@ -629,9 +605,9 @@ namespace getfem {
   struct APIDECL convex_face  {
     size_type cv;
     short_type f;
-    inline bool operator < (const convex_face &e) const
-    {
-      if (cv < e.cv) return true; if (cv > e.cv) return false;
+    inline bool operator < (const convex_face &e) const {
+      if (cv < e.cv) return true;
+      if (cv > e.cv) return false;
       if (f < e.f) return true; else if (f > e.f) return false;
       return false;
     }
@@ -680,10 +656,21 @@ namespace getfem {
   /** Select in the region mr the faces of the mesh m lying entirely in the
       box delimated by pt1 and pt2.
    */
-  mesh_region APIDECL select_faces_in_box(const mesh &m, const mesh_region &mr,
-                                          const base_node &pt1,
-                                          const base_node &pt2);
-
+  mesh_region APIDECL
+  select_faces_in_box(const mesh &m, const mesh_region &mr,
+                      const base_node &pt1,
+                      const base_node &pt2);
+
+  mesh_region APIDECL
+  select_convexes_in_box(const mesh &m, const mesh_region &mr,
+                         const base_node &pt1,
+                         const base_node &pt2);
+
+  inline mesh_region APIDECL
+  select_convexes_in_box(const mesh &m,
+                         const base_node &pt1,
+                         const base_node &pt2)
+  { return select_convexes_in_box(m, m.region(-1), pt1, pt2); }
 
   ///@}
 }  /* end of namespace getfem.                                             */
diff --git a/src/getfem/getfem_mesh_fem.h b/src/getfem/getfem_mesh_fem.h
index b502964..2ec585a 100644
--- a/src/getfem/getfem_mesh_fem.h
+++ b/src/getfem/getfem_mesh_fem.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -88,7 +88,7 @@ namespace getfem {
     bool operator < (const iterator &i) const
     { return (it < i.it) && (ii < i.ii); }
 
-    tab_scal_to_vect_iterator(void) {}
+    tab_scal_to_vect_iterator() {}
     tab_scal_to_vect_iterator(const ITER &iter, dim_type n, dim_type i)
       : it(iter), N(n), ii(i) { }
 
@@ -120,20 +120,20 @@ namespace getfem {
 
   public :
 
-    bool empty(void) const { return it == ite; }
-    size_type size(void) const { return (ite - it) * N; }
+    bool empty() const { return it == ite; }
+    size_type size() const { return (ite - it) * N; }
 
-    const_iterator begin(void) const { return iterator(it, N, 0); }
-    const_iterator end(void) const { return iterator(ite, N, 0); }
-    const_reverse_iterator rbegin(void) const
+    const_iterator begin() const { return iterator(it, N, 0); }
+    const_iterator end() const { return iterator(ite, N, 0); }
+    const_reverse_iterator rbegin() const
     { return const_reverse_iterator(end()); }
-    const_reverse_iterator rend(void) const
+    const_reverse_iterator rend() const
     { return const_reverse_iterator(begin()); }
 
-    value_type front(void) const { return *begin(); }
-    value_type back(void) const { return *(--(end())); }
+    value_type front() const { return *begin(); }
+    value_type back() const { return *(--(end())); }
 
-    tab_scal_to_vect(void) : N(0) {}
+    tab_scal_to_vect() : N(0) {}
     tab_scal_to_vect(const CONT &cc, dim_type n)
       : it(cc.begin()), ite(cc.end()), N(n) {}
 
@@ -153,13 +153,14 @@ namespace getfem {
     void copy_from(const mesh_fem &mf); /* Remember to change copy_from if
                                            adding components to mesh_fem */
 
-    dal::dynamic_array<pfem> f_elems;
+    std::vector<pfem> f_elems;
     dal::bit_vector fe_convex;
     const mesh *linked_mesh_;
     REDUCTION_MATRIX R_;
     EXTENSION_MATRIX E_;
     mutable bgeot::mesh_structure dof_structure;
     mutable bool dof_enumeration_made;
+    mutable bool is_uniform_, is_uniformly_vectorized_;
     mutable size_type nb_total_dof;
     pfem auto_add_elt_pf; /* fem for automatic addition                   */
                        /* of element option. (0 = no automatic addition)  */
@@ -180,24 +181,24 @@ namespace getfem {
     typedef tab_scal_to_vect<mesh::ind_cv_ct> ind_dof_ct;
     typedef tab_scal_to_vect<mesh::ind_pt_face_ct> ind_dof_face_ct;
 
-    void update_from_context(void) const;
+    void update_from_context() const;
 
-    gmm::uint64_type version_number(void) const
+    gmm::uint64_type version_number() const
     { context_check(); return v_num; }
 
     /** Get the set of convexes where a finite element has been assigned.
      */
-    inline const dal::bit_vector &convex_index(void) const
+    inline const dal::bit_vector &convex_index() const
     { context_check(); return fe_convex; }
 
     /// Return true if a reduction matrix is applied to the dofs.
-    bool is_reduced(void) const { return use_reduction; }
+    bool is_reduced() const { return use_reduction; }
 
     /// Return the reduction matrix applied to the dofs.
-    const REDUCTION_MATRIX &reduction_matrix(void) const { return R_; }
+    const REDUCTION_MATRIX &reduction_matrix() const { return R_; }
 
     /// Return the extension matrix corresponding to reduction applied (RE=I).
-    const EXTENSION_MATRIX &extension_matrix(void) const { return E_; }
+    const EXTENSION_MATRIX &extension_matrix() const { return E_; }
 
     /** Allows to set the reduction and the extension matrices.
      * Should satify (RR*EE=I). */
@@ -274,7 +275,10 @@ namespace getfem {
 
 
     /// Return a reference to the underlying mesh.
-    const mesh &linked_mesh(void) const { return *linked_mesh_; }
+    const mesh &linked_mesh() const { return *linked_mesh_; }
+
+    virtual bool is_uniform() const;
+    virtual bool is_uniformly_vectorized() const;
 
     /** Set the degree of the fem for automatic addition
      *  of element option. K=-1 disables the automatic addition.
@@ -420,7 +424,7 @@ namespace getfem {
      *  vectorization due to qdim nor the optional reduction.
      */
     virtual pfem fem_of_element(size_type cv) const
-    { return  f_elems[cv]; }
+    { return ((cv < f_elems.size()) ? f_elems[cv] : 0); }
     /** Give an array of the dof numbers a of convex.
      *  @param cv the convex number.
      *  @return a pseudo-container of the dof number.
@@ -432,6 +436,9 @@ namespace getfem {
     }
     ind_dof_ct ind_dof_of_element(size_type cv) const IS_DEPRECATED
     { return ind_basic_dof_of_element(cv); }
+    virtual const bgeot::mesh_structure::ind_cv_ct &
+    ind_scalar_basic_dof_of_element(size_type cv) const
+    { return dof_structure.ind_points_of_convex(cv); }
     /** Give an array of the dof numbers lying of a convex face (all
               degrees of freedom whose associated base function is non-zero
         on the convex face).
@@ -454,7 +461,7 @@ namespace getfem {
         @param f the face number.
     */
     virtual size_type nb_basic_dof_of_face_of_element(size_type cv,
-                                              short_type f) const {
+						      short_type f) const {
       context_check(); if (!dof_enumeration_made) enumerate_dof();
       pfem pf = f_elems[cv];
       return dof_structure.structure_of_convex(cv)->nb_points_of_face(f)
@@ -520,20 +527,20 @@ namespace getfem {
     virtual void get_global_dof_index(std::vector<size_type> &ind) const;
     /** Renumber the degrees of freedom. You should not have
      * to call this function, as it is done automatically */
-    virtual void enumerate_dof(void) const;
+    virtual void enumerate_dof() const;
 
 #if GETFEM_PARA_LEVEL > 1
-    void enumerate_dof_para(void)const;
+    void enumerate_dof_para()const;
 #endif
 
     /** Return the total number of basic degrees of freedom (before the
      * optional reduction). */
-    virtual size_type nb_basic_dof(void) const {
+    virtual size_type nb_basic_dof() const {
       context_check(); if (!dof_enumeration_made) enumerate_dof();
       return nb_total_dof;
     }
     /// Return the total number of degrees of freedom.
-    virtual size_type nb_dof(void) const {
+    virtual size_type nb_dof() const {
       context_check(); if (!dof_enumeration_made) enumerate_dof();
       return use_reduction ? gmm::mat_nrows(R_) : nb_total_dof;
     }
@@ -555,8 +562,8 @@ namespace getfem {
 
     void set_dof_partition(size_type cv, unsigned partition_num) {
       if (dof_partition.empty() && partition_num == 0) return;
-      if (dof_partition.size() < linked_mesh().convex_index().last_true()+1)
-        dof_partition.resize(linked_mesh().convex_index().last_true()+1);
+      if (dof_partition.size() < linked_mesh().nb_allocated_convex())
+        dof_partition.resize(linked_mesh().nb_allocated_convex());
       if (dof_partition.at(cv) != partition_num) {
         dof_partition[cv] = partition_num;
         dof_enumeration_made = false;
@@ -570,7 +577,7 @@ namespace getfem {
     size_type memsize() const {
       return dof_structure.memsize() +
         sizeof(mesh_fem) - sizeof(bgeot::mesh_structure) +
-        f_elems.memsize() + fe_convex.memsize();
+        f_elems.size() * sizeof(pfem) + fe_convex.memsize();
     }
     void init_with_mesh(const mesh &me, dim_type Q = 1);
     /** Build a new mesh_fem. A mesh object must be supplied.
@@ -578,12 +585,12 @@ namespace getfem {
         @param Q the Q dimension (see mesh_fem::get_qdim).
     */
     explicit mesh_fem(const mesh &me, dim_type Q = 1);
-    mesh_fem(void);
+    mesh_fem();
     mesh_fem(const mesh_fem &mf);
     mesh_fem &operator=(const mesh_fem &mf);
 
     virtual ~mesh_fem();
-    virtual void clear(void);
+    virtual void clear();
     /** Read the mesh_fem from a stream.
         @param ist the stream.
      */
@@ -625,26 +632,36 @@ namespace getfem {
   /** Given a mesh_fem @param mf and a vector @param vec of size equal to
    *  mf.nb_basic_dof(), the output vector @param coeff will contain the
    *  values of @param vec corresponding to the basic dofs of element
-   *  @param cv . The size of @param coeff is adjusted if necessary.
+   *  @param cv. The size of @param coeff is adjusted if necessary.
    */
   template <typename VEC1, typename VEC2>
   void slice_vector_on_basic_dof_of_element(const mesh_fem &mf,
                                             const VEC1 &vec,
-                                            size_type cv, VEC2 &coeff) {
-    size_type nbdof = mf.nb_basic_dof();
-    size_type qmult = gmm::vect_size(vec) / nbdof;
-    GMM_ASSERT1(gmm::vect_size(vec) == qmult * nbdof, "Bad dof vector size");
-    size_type cvnbdof = mf.nb_basic_dof_of_element(cv);
-    gmm::resize(coeff, cvnbdof*qmult);
-    mesh_fem::ind_dof_ct::const_iterator
-      itdof = mf.ind_basic_dof_of_element(cv).begin();
-    if (qmult == 1) {
-      for (size_type k = 0; k < cvnbdof; ++k, ++itdof)
-          coeff[k] = vec[*itdof];
+                                            size_type cv, VEC2 &coeff,
+					    size_type qmult1 = size_type(-1),
+					    size_type qmult2 = size_type(-1)) {
+    if (qmult1 == size_type(-1)) {
+      size_type nbdof = mf.nb_basic_dof();
+      qmult1 = gmm::vect_size(vec) / nbdof;
+      GMM_ASSERT1(gmm::vect_size(vec) == qmult1 * nbdof, "Bad dof vector size");
+    }
+    if (qmult2 == size_type(-1)) {
+      qmult2 = mf.get_qdim();
+      if (qmult2 > 1) qmult2 /= mf.fem_of_element(cv)->target_dim();
+    }
+    size_type qmultot = qmult1*qmult2;
+    auto &ct = mf.ind_scalar_basic_dof_of_element(cv);
+    gmm::resize(coeff, ct.size()*qmultot);
+    
+    auto it = ct.begin();
+    auto itc = coeff.begin();
+    if (qmultot == 1) {
+      for (; it != ct.end(); ++it) *itc++ = vec[*it];
     } else {
-      for (size_type k = 0; k < cvnbdof; ++k, ++itdof)
-        for (size_type l = 0; l < qmult; ++l)
-          coeff[l+k*qmult] = vec[l+(*itdof)*qmult];
+      for (; it != ct.end(); ++it) {
+	auto itv = vec.begin()+(*it)*qmult1;
+	for (size_type m = 0; m < qmultot; ++m) *itc++ = *itv++;
+      }
     }
   }
 
diff --git a/src/getfem/getfem_mesh_fem_global_function.h b/src/getfem/getfem_mesh_fem_global_function.h
index 4157f04..6faa185 100644
--- a/src/getfem/getfem_mesh_fem_global_function.h
+++ b/src/getfem/getfem_mesh_fem_global_function.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
  Copyright (C) 2016      Konstantinos Poulios
 
  This file is a part of GetFEM++
diff --git a/src/getfem/getfem_mesh_fem_level_set.h b/src/getfem/getfem_mesh_fem_level_set.h
index a609fab..81cb4b8 100644
--- a/src/getfem/getfem_mesh_fem_level_set.h
+++ b/src/getfem/getfem_mesh_fem_level_set.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mesh_fem_product.h b/src/getfem/getfem_mesh_fem_product.h
index f318589..f7122c8 100644
--- a/src/getfem/getfem_mesh_fem_product.h
+++ b/src/getfem/getfem_mesh_fem_product.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mesh_fem_sum.h b/src/getfem/getfem_mesh_fem_sum.h
index 3f2e885..8a6dba5 100644
--- a/src/getfem/getfem_mesh_fem_sum.h
+++ b/src/getfem/getfem_mesh_fem_sum.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mesh_im.h b/src/getfem/getfem_mesh_im.h
index e7294d4..9491a27 100644
--- a/src/getfem/getfem_mesh_im.h
+++ b/src/getfem/getfem_mesh_im.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2005-2016 Yves Renard
+ Copyright (C) 2005-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mesh_im_level_set.h b/src/getfem/getfem_mesh_im_level_set.h
index 2ca49e7..5ae02ef 100644
--- a/src/getfem/getfem_mesh_im_level_set.h
+++ b/src/getfem/getfem_mesh_im_level_set.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2005-2016 Yves Renard
+ Copyright (C) 2005-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mesh_level_set.h b/src/getfem/getfem_mesh_level_set.h
index 6e3e27e..ae7fd70 100644
--- a/src/getfem/getfem_mesh_level_set.h
+++ b/src/getfem/getfem_mesh_level_set.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2005-2016 Julien Pommier
+ Copyright (C) 2005-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mesh_region.h b/src/getfem/getfem_mesh_region.h
index b368baf..aa34e40 100644
--- a/src/getfem/getfem_mesh_region.h
+++ b/src/getfem/getfem_mesh_region.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2005-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2005-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -93,7 +93,7 @@ namespace getfem {
     // #endif
 
     size_type id_;            /* used temporarily when the 
-                              mesh_region(size_type) constructor is used */
+				 mesh_region(size_type) constructor is used */
 
     size_type type_; //optional type of the region
     omp_distribute<bool> partitioning_allowed; /** specifies that in
@@ -166,7 +166,9 @@ namespace getfem {
     /** Test if the region is a boundary of a list of faces of elements of
         region `rg`. Return 0 if not, -1 if only partially, 1 if the region
         contains only some faces which are all faces of elements of `rg`. */
-    int region_is_faces_of(const mesh_region &rg);
+    int region_is_faces_of(const getfem::mesh& m1,
+			   const mesh_region &rg2,
+			   const getfem::mesh& m2) const;
 
     size_type id() const { return id_; }
 
@@ -213,6 +215,7 @@ namespace getfem {
     void clear();
     void swap_convex(size_type cv1, size_type cv2);
     bool is_in(size_type cv, short_type f = short_type(-1)) const;
+    bool is_in(size_type cv, short_type f, const mesh &m) const;
 
     /**region size, or the size of the region partition on the current
     thread if the region is partitioned*/
@@ -246,42 +249,36 @@ namespace getfem {
     class visitor {
 
       typedef mesh_region::map_t::const_iterator const_iterator;
-      const_iterator it,ite;
+      bool whole_mesh;
+      dal::bit_const_iterator itb, iteb;
+      const_iterator it, ite;
       face_bitset c;
       size_type cv_;
       short_type f_;
       bool finished_;
+#if GETFEM_PARA_LEVEL > 1
+      mesh_region mpi_rg;
+#endif
       void init(const mesh_region &s);
+      void init(const dal::bit_vector &s);
 
     public: 
       visitor(const mesh_region &s);
-      visitor(const mesh_region &s, const mesh &m);
+      visitor(const mesh_region &s, const mesh &m,
+	      bool intersect_with_mpi = false);
       size_type cv() const { return cv_; }
       size_type is_face() const { return f_ != 0; }
       short_type f() const { return short_type(f_-1); }
 
-      bool next() 
-      {
-        while (c.none()) 
-        {
-          if (it == ite) { finished_=true; return false; }
-          cv_ = it->first;
-          c   = it->second;  
-          f_ = short_type(-1);
-          ++it; 
-          if (c.none()) continue;
-        }
-        next_face();
-        return true;
-      }
-
+      bool next();
       bool operator++() { return next(); }
 
-      bool finished() const { return finished_; }//it == ite && c.none(); }
+      bool finished() const { return finished_; }
 
       bool next_face() 
       {
-        if (c.none()) return false;
+	if (whole_mesh) return false;
+	if (c.none()) return false;
         do { ++f_; } while (!c.test(f_));
         c.set(f_,0);
         return true;
diff --git a/src/getfem/getfem_mesh_slice.h b/src/getfem/getfem_mesh_slice.h
index 5009985..cc0ac64 100644
--- a/src/getfem/getfem_mesh_slice.h
+++ b/src/getfem/getfem_mesh_slice.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Julien Pommier
+ Copyright (C) 2003-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -99,6 +99,9 @@ namespace getfem {
     /** return the original convex number of the 'ic'th convex
         referenced in the slice */
     size_type convex_num(size_type ic) const { return cvlst[ic].cv_num; }
+    /** return the position ic of the referenced convex in the slice convexes
+        list cvlist, corresponding to the original convex number cv*/
+    size_type convex_pos(size_type cv) const { return cv2pos[cv]; }
     /** change the slice dimension (append zeros or truncate node coordinates..) */
     void set_dim(size_type newdim);
     /** return the slice dimension */
@@ -120,8 +123,15 @@ namespace getfem {
     /** Return the list of simplexes for the 'ic'th convex of the slice. */
     const mesh_slicer::cs_simplexes_ct& simplexes(size_type ic) const { return cvlst[ic].simplexes; }
     size_type memsize() const;
-    void clear() { poriginal_mesh = 0; cvlst.clear(); points_cnt = 0; 
-      dim_ = size_type(-1); cv2pos.clear(); simplex_cnt.clear(); clear_merged_nodes(); }
+    void clear() {
+      poriginal_mesh = 0;
+      cvlst.clear();
+      points_cnt = 0; 
+      dim_ = size_type(-1);
+      gmm::fill(cv2pos, size_type(-1));
+      simplex_cnt.clear();
+      clear_merged_nodes();
+    }
     /** @brief merge with another mesh slice. */
     void merge(const stored_mesh_slice& sl);
 
diff --git a/src/getfem/getfem_mesh_slicers.h b/src/getfem/getfem_mesh_slicers.h
index ab24538..770dc9f 100644
--- a/src/getfem/getfem_mesh_slicers.h
+++ b/src/getfem/getfem_mesh_slicers.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_mesher.h b/src/getfem/getfem_mesher.h
index 3b66289..870cbad 100644
--- a/src/getfem/getfem_mesher.h
+++ b/src/getfem/getfem_mesher.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier, Yves Renard
+ Copyright (C) 2004-2017 Julien Pommier, Yves Renard
 
  This file is a part of GetFEM++
 
@@ -439,15 +439,24 @@ namespace getfem {
      const pmesher_signed_distance &t = pmesher_signed_distance()) {
       dists.push_back(a); dists.push_back(b);
       with_min = true;
-      if (c) dists.push_back(c); if (d) dists.push_back(d);
-      if (e) dists.push_back(e); if (f) dists.push_back(f);
-      if (g) dists.push_back(g); if (h) dists.push_back(h);
-      if (i) dists.push_back(i); if (j) dists.push_back(j);
-      if (k) dists.push_back(k); if (l) dists.push_back(l);
-      if (m) dists.push_back(m); if (n) dists.push_back(n);
-      if (o) dists.push_back(o); if (p) dists.push_back(p);
-      if (q) dists.push_back(q); if (r) dists.push_back(r);
-      if (s) dists.push_back(s); if (t) dists.push_back(t);
+      if (c) dists.push_back(c);
+      if (d) dists.push_back(d);
+      if (e) dists.push_back(e);
+      if (f) dists.push_back(f);
+      if (g) dists.push_back(g);
+      if (h) dists.push_back(h);
+      if (i) dists.push_back(i);
+      if (j) dists.push_back(j);
+      if (k) dists.push_back(k);
+      if (l) dists.push_back(l);
+      if (m) dists.push_back(m);
+      if (n) dists.push_back(n);
+      if (o) dists.push_back(o);
+      if (p) dists.push_back(p);
+      if (q) dists.push_back(q);
+      if (r) dists.push_back(r);
+      if (s) dists.push_back(s);
+      if (t) dists.push_back(t);
       vd.resize(dists.size());
     }
     
@@ -624,15 +633,24 @@ namespace getfem {
      const pmesher_signed_distance &s = pmesher_signed_distance(),
      const pmesher_signed_distance &t = pmesher_signed_distance()) {
       dists.push_back(a); dists.push_back(b);
-      if (c) dists.push_back(c); if (d) dists.push_back(d);
-      if (e) dists.push_back(e); if (f) dists.push_back(f);
-      if (g) dists.push_back(g); if (h) dists.push_back(h);
-      if (i) dists.push_back(i); if (j) dists.push_back(j);
-      if (k) dists.push_back(k); if (l) dists.push_back(l);
-      if (m) dists.push_back(m); if (n) dists.push_back(n);
-      if (o) dists.push_back(o); if (p) dists.push_back(p);
-      if (q) dists.push_back(q); if (r) dists.push_back(r);
-      if (s) dists.push_back(s); if (t) dists.push_back(t);
+      if (c) dists.push_back(c);
+      if (d) dists.push_back(d);
+      if (e) dists.push_back(e);
+      if (f) dists.push_back(f);
+      if (g) dists.push_back(g);
+      if (h) dists.push_back(h);
+      if (i) dists.push_back(i);
+      if (j) dists.push_back(j);
+      if (k) dists.push_back(k);
+      if (l) dists.push_back(l);
+      if (m) dists.push_back(m);
+      if (n) dists.push_back(n);
+      if (o) dists.push_back(o);
+      if (p) dists.push_back(p);
+      if (q) dists.push_back(q);
+      if (r) dists.push_back(r);
+      if (s) dists.push_back(s);
+      if (t) dists.push_back(t);
       vd.resize(dists.size());
     }
     bool bounding_box(base_node &bmin, base_node &bmax) const {
diff --git a/src/getfem/getfem_model_solvers.h b/src/getfem/getfem_model_solvers.h
index 9a2f91a..6198072 100644
--- a/src/getfem/getfem_model_solvers.h
+++ b/src/getfem/getfem_model_solvers.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -154,6 +154,17 @@ namespace getfem {
     }
   };
 
+  template <typename MAT, typename VECT>
+  struct linear_solver_dense_lu : public abstract_linear_solver<MAT, VECT> {
+    void operator ()(const MAT &M, VECT &x, const VECT &b,
+                     gmm::iteration &iter) const {
+      typedef typename gmm::linalg_traits<MAT>::value_type T;
+      gmm::dense_matrix<T> MM(gmm::mat_nrows(M),gmm::mat_ncols(M));
+      gmm::copy(M, MM);
+      gmm::lu_solve(MM, x, b);
+      iter.enforce_converged(true);
+    }
+  };
 
 #ifdef GMM_USES_MUMPS
   template <typename MAT, typename VECT>
@@ -611,6 +622,8 @@ namespace getfem {
     std::shared_ptr<abstract_linear_solver<MATRIX, VECTOR>> p;
     if (bgeot::casecmp(name, "superlu") == 0)
       return std::make_shared<linear_solver_superlu<MATRIX, VECTOR>>();
+    else if (bgeot::casecmp(name, "dense_lu") == 0)
+      return std::make_shared<linear_solver_dense_lu<MATRIX, VECTOR>>();
     else if (bgeot::casecmp(name, "mumps") == 0) {
 #ifdef GMM_USES_MUMPS
 # if GETFEM_PARA_LEVEL <= 1
diff --git a/src/getfem/getfem_models.h b/src/getfem/getfem_models.h
index a42732b..a3f52a5 100644
--- a/src/getfem/getfem_models.h
+++ b/src/getfem/getfem_models.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard
+ Copyright (C) 2009-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -39,6 +39,7 @@
 #ifndef GETFEM_MODELS_H__
 #define GETFEM_MODELS_H__
 
+#include "getfem_generic_assembly.h"
 #include "getfem_assembling.h"
 #include "getfem_partial_mesh_fem.h"
 #include "getfem_im_data.h"
@@ -55,21 +56,6 @@ namespace getfem {
   class virtual_time_scheme;
   typedef std::shared_ptr<const virtual_time_scheme> ptime_scheme;
 
-
-  class Neumann_elem_term;
-  typedef std::shared_ptr<const Neumann_elem_term> pNeumann_elem_term;
-
-  class virtual_interpolate_transformation;
-  typedef std::shared_ptr<const virtual_interpolate_transformation>
-  pinterpolate_transformation;
-
-  class virtual_elementary_transformation;
-  typedef std::shared_ptr<const virtual_elementary_transformation>
-  pelementary_transformation;
-  
-
-  class ga_workspace;
-
   // Event management : The model has to react when something has changed in
   //    the context and ask for corresponding (linear) bricks to recompute
   //    some terms.
@@ -98,21 +84,6 @@ namespace getfem {
   //  Model object.
   //
   //=========================================================================
-
-
-  typedef gmm::rsvector<scalar_type> model_real_sparse_vector;
-  typedef gmm::rsvector<complex_type> model_complex_sparse_vector;
-  typedef std::vector<scalar_type> model_real_plain_vector;
-  typedef std::vector<complex_type> model_complex_plain_vector;
-
-  typedef gmm::col_matrix<model_real_sparse_vector> model_real_sparse_matrix;
-  typedef gmm::col_matrix<model_complex_sparse_vector>
-  model_complex_sparse_matrix;
-
-  typedef gmm::row_matrix<model_real_sparse_vector>
-  model_real_row_sparse_matrix;
-  typedef gmm::row_matrix<model_complex_sparse_vector>
-  model_complex_row_sparse_matrix;
   
   // For backward compatibility with version 3.0
   typedef model_real_plain_vector modeling_standard_plain_vector;
@@ -122,15 +93,18 @@ namespace getfem {
   typedef model_complex_sparse_vector modeling_standard_complex_sparse_vector;
   typedef model_complex_sparse_matrix modeling_standard_complex_sparse_matrix;
 
-  inline std::string sup_previous_and_dot_to_varname(std::string v) {
-    if (!(v.compare(0, 8, "Previous")) && (v[8] == '_' || v[9] == '_')) {
-      v = v.substr((v[8] == '_') ? 9 : 10);
-    }
-    if (!(v.compare(0, 3, "Dot")) && (v[3] == '_' || v[4] == '_')) {
-      v = v.substr((v[3] == '_') ? 4 : 5);
-    }
-    return v;
-  }
+
+  /** A prefix to refer to the previous version of a variable*/
+  const auto PREFIX_OLD = std::string{"Old_"};
+  const auto PREFIX_OLD_LENGTH = 4;
+
+  /** Does the variable have Old_ prefix*/
+  bool is_old(const std::string &name);
+
+  /** Strip the variable name from prefix Old_ if it has one*/
+  std::string no_old_prefix_name(const std::string &name);
+
+  std::string sup_previous_and_dot_to_varname(std::string v);
 
   /** ``Model'' variables store the variables, the data and the
       description of a model. This includes the global tangent matrix, the
@@ -195,7 +169,8 @@ namespace getfem {
       bgeot::multi_index qdims;  // For data having a qdim != of the fem
                                  // (dim per dof for dof data)
                                  // and for constant variables.
-      gmm::uint64_type v_num, v_num_data;
+      gmm::uint64_type v_num;
+      std::vector<gmm::uint64_type> v_num_data;
 
       gmm::sub_interval I; // For a variable : indices on the whole system.
       // For an affine dependent variable, should be the same than the
@@ -230,7 +205,7 @@ namespace getfem {
           n_iter(std::max(size_type(1), n_it)), n_temp_iter(0),
           default_iter(0), ptsc(0), mf(mmf), m_region(m_reg), mim(mim_),
           filter_var(filter_v), qdims(qdims_), v_num(0),
-          v_num_data(act_counter()), I(0,0),
+          v_num_data(n_iter, act_counter()), I(0,0),
           alpha(1), pim_data(pimd) {
         
         if (filter != VDESCRFILTER_NO && mf != 0)
@@ -299,8 +274,7 @@ namespace getfem {
                          BUILD_ALL = 3,
                          BUILD_ON_DATA_CHANGE = 4,
                          BUILD_WITH_COMPLETE_RHS = 8,
-                         BUILD_COMPLETE_RHS = 9,
-    };
+                         BUILD_COMPLETE_RHS = 9, };
 
   protected:
 
@@ -352,12 +326,6 @@ namespace getfem {
     mutable VAR_SET variables;             // Variables list of the model
     std::vector<brick_description> bricks; // Bricks list of the model
     dal::bit_vector valid_bricks, active_bricks;
-    typedef std::pair<std::string, size_type> Neumann_pair;
-    typedef std::map<Neumann_pair, pNeumann_elem_term> Neumann_SET;
-    mutable Neumann_SET Neumann_term_list; // Neumann terms list (mainly for
-                                           // Nitsche's method)
-    mutable std::map<std::string, std::vector<std::string> >
-      Neumann_terms_auxilliary_variables;
     std::map<std::string, pinterpolate_transformation> transformations;
     std::map<std::string, pelementary_transformation> elem_transformations;
 
@@ -386,6 +354,18 @@ namespace getfem {
                size_type region_) : expr(expr_), mim(mim_), region(region_) {}
     };
 
+    // Structure for assignment in assembly
+    struct assignement_desc {
+      std::string varname;
+      std::string expr;
+      size_type region;
+      bool before;
+      size_type order;
+    };
+
+    std::list<assignement_desc> assignments;
+
+    
     mutable std::list<gen_expr> generic_expressions;
 
     // Groups of variables for interpolation on different meshes
@@ -432,7 +412,7 @@ namespace getfem {
     scalar_type &matrix_coeff_of_brick(size_type ib) const
     { return bricks[ib].matrix_coeff; }
     bool is_var_newer_than_brick(const std::string &varname,
-                                 size_type ib) const;
+                                 size_type ib, size_type niter = size_type(-1)) const;
     bool is_var_mf_newer_than_brick(const std::string &varname,
                                     size_type ib) const;
     bool is_mim_newer_than_brick(const mesh_im &mim,
@@ -458,41 +438,12 @@ namespace getfem {
       return (variable_groups.find(group_name))->second;
     }
 
-    void add_Neumann_term(pNeumann_elem_term p,
-                          const std::string &varname,
-                          size_type brick_num) const
-    { Neumann_term_list[Neumann_pair(varname, brick_num)] = p; }
-
-    size_type check_Neumann_terms_consistency(const std::string &varname)const;
-
-    bool check_Neumann_terms_linearity(const std::string &varname) const;
-
-    void auxilliary_variables_of_Neumann_terms
-    (const std::string &varname, std::vector<std::string> &aux_var) const;
-
-    void add_auxilliary_variables_of_Neumann_terms
-    (const std::string &varname, const std::vector<std::string> &aux_vars) const;
-
-    void add_auxilliary_variables_of_Neumann_terms
-    (const std::string &varname, const std::string &aux_var) const;
-
-    /* Compute the approximation of the Neumann condition for a variable
-        with the declared terms.
-        The output tensor has to have the right size. No verification.
-    */
-    void compute_Neumann_terms(int version, const std::string &varname,
-                               const mesh_fem &mfvar,
-                               const model_real_plain_vector &var,
-                               fem_interpolation_context &ctx,
-                               base_small_vector &n,
-                               bgeot::base_tensor &output) const;
-
-    void compute_auxilliary_Neumann_terms
-    (int version, const std::string &varname,
-     const mesh_fem &mfvar, const model_real_plain_vector &var,
-     const std::string &aux_varname,
-     fem_interpolation_context &ctx, base_small_vector &n,
-     bgeot::base_tensor &output) const;
+    void clear_assembly_assignments(void) { assignments.clear(); }
+    void add_assembly_assignments(const std::string &dataname,
+				  const std::string &expr,
+				  size_type rg = size_type(-1),
+				  size_type order = 1,
+				  bool before = false);
 
     /* function to be called by Dirichlet bricks */
     void add_real_dof_constraint(const std::string &varname, size_type dof,
@@ -557,8 +508,7 @@ namespace getfem {
     void enable_variable(const std::string &name);
 
     /** Says if a name corresponds to a declared variable.  */
-    bool variable_exists(const std::string &name) const
-    { return variables.count(name) > 0; }
+    bool variable_exists(const std::string &name) const;
 
     bool is_disabled_variable(const std::string &name) const;
 
@@ -581,7 +531,8 @@ namespace getfem {
     const im_data *pim_data_of_variable(const std::string &name) const;
 
     const gmm::uint64_type &
-    version_number_of_data_variable(const std::string &varname) const;
+    version_number_of_data_variable(const std::string &varname,
+                                    size_type niter = size_type(-1)) const;
 
     /** Boolean which says if the model deals with real or complex unknowns
         and data. */
@@ -613,26 +564,42 @@ namespace getfem {
     /** Gives the access to the vector value of a variable. For the real
         version. */
     const model_real_plain_vector &
-    real_variable(const std::string &name,
-                  size_type niter = size_type(-1)) const;
+    real_variable(const std::string &name, size_type niter) const;
+
+    /**The same as above, but either accessing the latest variable version,
+    or the previous, if using "Old_" prefix*/
+    const model_real_plain_vector &
+    real_variable(const std::string &name) const;
 
     /** Gives the access to the vector value of a variable. For the complex
         version. */
     const model_complex_plain_vector &
-    complex_variable(const std::string &name,
-                     size_type niter = size_type(-1)) const;
+    complex_variable(const std::string &name, size_type niter) const;
+
+    /**The same as above, but either accessing the latest variable version,
+    or the previous, if using "Old_" prefix*/
+    const model_complex_plain_vector &
+    complex_variable(const std::string &name) const;
 
     /** Gives the write access to the vector value of a variable. Make a
         change flag of the variable set. For the real version. */
     model_real_plain_vector &
-    set_real_variable(const std::string &name,
-                      size_type niter = size_type(-1)) const;
+    set_real_variable(const std::string &name, size_type niter) const;
+
+    /**The same as above, but for either latest variable, or
+    for the previous, if prefixed with "Old_".*/
+    model_real_plain_vector &
+    set_real_variable(const std::string &name) const;
 
     /** Gives the write access to the vector value of a variable. Make a
         change flag of the variable set. For the complex version. */
     model_complex_plain_vector &
-    set_complex_variable(const std::string &name,
-                         size_type niter = size_type(-1)) const;
+    set_complex_variable(const std::string &name, size_type niter) const;
+
+    /**The same as above, but either accessing the latest variable version,
+    or the previous, if using "Old_" prefix*/
+    model_complex_plain_vector &
+    set_complex_variable(const std::string &name) const;
 
     model_real_plain_vector &
     set_real_constant_part(const std::string &name) const;
@@ -671,7 +638,7 @@ namespace getfem {
             && !(v.second.is_disabled)) {
           gmm::copy(gmm::sub_vector(V, v.second.I),
                     v.second.real_value[0]);
-          v.second.v_num_data = act_counter();
+          v.second.v_num_data[0] = act_counter();
         }
       update_affine_dependent_variables();
       this->post_to_variables_step();
@@ -684,7 +651,7 @@ namespace getfem {
             && !(v.second.is_disabled)) {
           gmm::copy(gmm::sub_vector(V, v.second.I),
                     v.second.complex_value[0]);
-          v.second.v_num_data = act_counter();
+          v.second.v_num_data[0] = act_counter();
         }
       update_affine_dependent_variables();
       this->post_to_variables_step();
@@ -776,15 +743,15 @@ namespace getfem {
     }
 
 
+    /** Add data, defined at integration points.*/
+    void add_im_data(const std::string &name, const im_data &im_data, size_type niter = 1);
+
     /** Add a variable being the dofs of a finite element method to the model.
         niter is the number of version of the variable stored, for time
         integration schemes. */
     void add_fem_variable(const std::string &name, const mesh_fem &mf,
                           size_type niter = 1);
 
-    /** Add a data that is described by integration points.*/
-    void add_im_data(const std::string &name, const im_data &im_data, size_type niter = 1);
-
     /** Add a variable linked to a fem with the dof filtered with respect
         to a mesh region. Only the dof returned by the dof_on_region
         method of `mf` will be kept. niter is the number of version
@@ -1358,7 +1325,6 @@ namespace getfem {
     bool isinit;      // internal flag.
     bool compute_each_time; // The brick is linear but needs to be computed
     // each time it is evaluated.
-    bool hasNeumannterm; // The brick declares at list a Neumann term.
     bool isUpdateBrick;  // The brick does not contribute any terms to the
     // system matrix or right-hand side, but only updates state variables.
     std::string name; // Name of the brick.
@@ -1370,12 +1336,11 @@ namespace getfem {
     virtual_brick() { isinit = false; }
     virtual ~virtual_brick() { }
     void set_flags(const std::string &bname, bool islin, bool issym,
-                   bool iscoer, bool ire, bool isco, bool each_time = false,
-                   bool hasNeumannt = true) {
+                   bool iscoer, bool ire, bool isco, bool each_time = false) {
       name = bname;
       islinear = islin; issymmetric = issym; iscoercive = iscoer;
       isreal = ire; iscomplex = isco; isinit = true;
-      compute_each_time = each_time; hasNeumannterm = hasNeumannt;
+      compute_each_time = each_time;
     }
 
 #   define BRICK_NOT_INIT GMM_ASSERT1(isinit, "Set brick flags !")
@@ -1384,7 +1349,6 @@ namespace getfem {
     bool is_coercive()  const { BRICK_NOT_INIT; return iscoercive;  }
     bool is_real()      const { BRICK_NOT_INIT; return isreal;      }
     bool is_complex()   const { BRICK_NOT_INIT; return iscomplex;   }
-    bool has_Neumann_term() const {BRICK_NOT_INIT; return hasNeumannterm; }
     bool is_to_be_computed_each_time() const
     { BRICK_NOT_INIT; return compute_each_time; }
     const std::string &brick_name() const { BRICK_NOT_INIT; return name; }
@@ -1534,101 +1498,6 @@ namespace getfem {
 
   //=========================================================================
   //
-  //  Virtual interpolate_transformation object.
-  //
-  //=========================================================================
-
-  struct var_trans_pair {
-    std::string varname, transname;
-    bool operator <(const var_trans_pair &vt) const {
-      return (varname < vt.varname) ||
-             (!(varname > vt.varname) && transname < vt.transname);
-    }
-    var_trans_pair() : varname(), transname() {}
-    var_trans_pair(const std::string &v, const std::string &t)
-      : varname(v), transname(t) {}
-  };
-
-  class APIDECL virtual_interpolate_transformation {
-
-  public:
-    virtual void extract_variables
-    (const ga_workspace &workspace, std::set<var_trans_pair> &vars,
-     bool ignore_data, const mesh &m,
-     const std::string &interpolate_name) const = 0;
-    virtual void init(const ga_workspace &workspace) const = 0;
-    virtual int transform
-    (const ga_workspace &workspace, const mesh &m,
-     fem_interpolation_context &ctx_x, const base_small_vector &Normal,
-     const mesh **m_t, size_type &cv, short_type &face_num,
-     base_node &P_ref, base_small_vector &N_y,
-     std::map<var_trans_pair, base_tensor> &derivatives,
-     bool compute_derivatives) const = 0;
-    virtual void finalize() const = 0;
-
-    virtual ~virtual_interpolate_transformation() {}
-  };
-
-  //=========================================================================
-  //
-  //  Virtual elementary_transformation object.
-  //
-  //=========================================================================
-
-  class APIDECL virtual_elementary_transformation {
-
-  public:
-    
-    virtual void give_transformation(const mesh_fem &mf, size_type cv,
-                                     base_matrix &M) const = 0;
-    virtual ~virtual_elementary_transformation() {}
-  };
-
-  //=========================================================================
-  //
-  //  Neumann term object.
-  //
-  //=========================================================================
-
-  /* For a PDE in a weak form, the Neumann condition correspond to
-     prescribe a certain derivative of the unkown (the normal derivative
-     for the Poisson problem for instance). The Neumann term objects allows
-     to compute the finite element approximation of this certain derivative.
-     This allows, first ot have an estimate of this term (for instance, it can
-     give an approximation of the stress at the boundary in a problem of
-     linear elasticity) but also it allows to prescribe some boundary
-     conditions with Nitsche's method (For dirichlet or contact boundary
-     conditions for instance).
-  */
-
-  struct APIDECL Neumann_elem_term  {
-
-    std::vector<std::string> auxilliary_variables;
-
-    // The function should return the Neumann term when version = 1,
-    // its derivative when version = 2 and its second derivative
-    // when version = 3.
-    // CAUTION : The output tensor has the right size and the reult has to
-    //           be ADDED. previous additions of other term have not to be
-    //           erased.
-
-    virtual void compute_Neumann_term
-    (int version, const mesh_fem &/*mfvar*/,
-     const model_real_plain_vector &/*var*/,
-     fem_interpolation_context& /*ctx*/,
-     base_small_vector &/*n*/, base_tensor &/*output*/,
-     size_type /*auxilliary_ind*/ = 0) const = 0;
-
-    virtual ~Neumann_elem_term() {}
-
-  };
-
-
-
-
-
-  //=========================================================================
-  //
   //  Functions adding standard bricks to the model.
   //
   //=========================================================================
@@ -2248,6 +2117,16 @@ namespace getfem {
     return ind;
   }
 
+  template <typename MAT>
+  size_type add_constraint_with_multipliers
+  (model &md, const std::string &varname, const std::string &multname,
+   const MAT &B, const std::string &Lname) {
+    size_type ind = add_constraint_with_multipliers(md, varname, multname);
+    set_private_data_rhs(md, ind, Lname);
+    set_private_data_matrix(md, ind, B);
+    return ind;
+  }
+
   size_type APIDECL add_explicit_matrix(model &md, const std::string &varname1,
                                         const std::string &varname2,
                                         bool issymmetric, bool iscoercive);
diff --git a/src/getfem/getfem_nonlinear_elasticity.h b/src/getfem/getfem_nonlinear_elasticity.h
index e00c457..0c078a7 100644
--- a/src/getfem/getfem_nonlinear_elasticity.h
+++ b/src/getfem/getfem_nonlinear_elasticity.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2000-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_omp.h b/src/getfem/getfem_omp.h
index e173366..3147a5e 100644
--- a/src/getfem/getfem_omp.h
+++ b/src/getfem/getfem_omp.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2012-2016 Andriy Andreykiv
+ Copyright (C) 2012-2017 Andriy Andreykiv
 
  This file is a part of GetFEM++
 
@@ -43,11 +43,6 @@ This is the kernel of getfem.
 #include <vector>
 #include <algorithm>
 
-#ifdef GETFEM_HAVE_OPENMP
-#include <omp.h>
-#include <boost/thread.hpp>
-#endif
-
 #ifdef _WIN32
 #include <mbctype.h>
 #endif
@@ -57,6 +52,8 @@ This is the kernel of getfem.
 #include "gmm/gmm_std.h"
 #include "bgeot_config.h"
 #ifdef GETFEM_HAVE_OPENMP
+#include <omp.h>
+#include <boost/thread.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/make_shared.hpp>
 #endif
@@ -158,9 +155,7 @@ namespace getfem
       }
     };
   public:
-    omp_distribute() : thread_values(num_threads()) {}
-    omp_distribute(const T& value) :
-      thread_values(num_threads(),value) {}
+
     template <class... Args>
     omp_distribute(Args&&... value){
       for (size_type i = 0; i < num_threads(); ++i) thread_values.emplace_back(value...);
@@ -372,7 +367,11 @@ namespace getfem
     template <typename Function, typename... Parameters>
     void run(Function f, Parameters... params)
     {
+#ifdef GETFEM_HAVE_OPENMP
       try { f(params...); } catch (...) { captureException(); }
+#else
+      f(params...);
+#endif
     }
 
     /**vector of pointers to caught exceptions*/
diff --git a/src/getfem/getfem_partial_mesh_fem.h b/src/getfem/getfem_partial_mesh_fem.h
index 13433ff..b6bd00d 100644
--- a/src/getfem/getfem_partial_mesh_fem.h
+++ b/src/getfem/getfem_partial_mesh_fem.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -74,6 +74,10 @@ namespace getfem {
     virtual const bgeot::multi_index &get_qdims() const
     { return mf.get_qdims(); }
 
+    virtual bool is_uniform() const { return mf.is_uniform(); }
+    virtual bool is_uniformly_vectorized() const
+    { return mf.is_uniformly_vectorized(); }
+
     virtual void set_qdim(dim_type) {
       GMM_ASSERT1(false, "The Qdim of a partial_mesh_fem is the same as "
                   "the original fem");
@@ -97,6 +101,10 @@ namespace getfem {
     ind_dof_ct ind_basic_dof_of_element(size_type cv) const
     { return  mf.ind_basic_dof_of_element(cv); }
 
+    const bgeot::mesh_structure::ind_cv_ct &
+    ind_scalar_basic_dof_of_element(size_type cv) const
+    { return mf.ind_scalar_basic_dof_of_element(cv); }
+
     ind_dof_face_ct
     ind_basic_dof_of_face_of_element(size_type cv, short_type f) const
     { return  mf.ind_basic_dof_of_face_of_element(cv, f); }
diff --git a/src/getfem/getfem_plasticity.h b/src/getfem/getfem_plasticity.h
index 70a0050..941e02c 100644
--- a/src/getfem/getfem_plasticity.h
+++ b/src/getfem/getfem_plasticity.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Konstantinos Poulios, Amandine Cottaz, Yves Renard
+ Copyright (C) 2002-2017 Konstantinos Poulios, Amandine Cottaz, Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_projected_fem.h b/src/getfem/getfem_projected_fem.h
index 3bcafd9..dc06452 100644
--- a/src/getfem/getfem_projected_fem.h
+++ b/src/getfem/getfem_projected_fem.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2012-2016 Yves Renard, Konstantinos Poulios
+ Copyright (C) 2012-2017 Yves Renard, Konstantinos Poulios
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_regular_meshes.h b/src/getfem/getfem_regular_meshes.h
index 70b276f..7771be6 100644
--- a/src/getfem/getfem_regular_meshes.h
+++ b/src/getfem/getfem_regular_meshes.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -100,6 +100,22 @@ namespace getfem
     parallelepiped_regular_mesh_(me, N, org, &(vect[0]), &(ref[0]), linear_gt);
   } 
 
+  void parallelepiped_regular_pyramid_mesh_(mesh &me, const base_node &org,
+   const base_small_vector *ivect, const size_type *iref);
+
+  template<class ITER1, class ITER2>
+    void parallelepiped_regular_pyramid_mesh(mesh &me,
+                                     const base_node &org, ITER1 ivect, ITER2 iref)
+  { 
+    int N=3;
+    std::vector<base_small_vector> vect(N);
+    std::copy(ivect, ivect+N, vect.begin());
+    std::vector<size_type> ref(N);
+    std::copy(iref, iref+N, ref.begin());
+    parallelepiped_regular_pyramid_mesh_(me, org, &(vect[0]), &(ref[0]));
+  } 
+
+
   /**
      Build a regular mesh of the unit square/cube/, etc.
      @param m the output mesh.
diff --git a/src/getfem/getfem_superlu.h b/src/getfem/getfem_superlu.h
index 7b8748b..472f2eb 100644
--- a/src/getfem/getfem_superlu.h
+++ b/src/getfem/getfem_superlu.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem/getfem_torus.h b/src/getfem/getfem_torus.h
index 2908af8..dcfe562 100644
--- a/src/getfem/getfem_torus.h
+++ b/src/getfem/getfem_torus.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2014-2016 Liang Jin Lim
+ Copyright (C) 2014-2017 Liang Jin Lim
 
  This file is a part of GetFEM++
 
@@ -28,118 +28,118 @@
  might be covered by the GNU Lesser General Public License.
 
 ===========================================================================*/
-/**
- at file getfem_torus.h
- at brief Provides mesh and mesh fem of torus.
- at date May 2014
- at author Liang Jin Lim
-*/
-
-#pragma once
-
-#ifndef GETFEM_TORUS_H__
-#define GETFEM_TORUS_H__
-
-#include "getfem/getfem_mesh_fem.h"
-
-
-namespace bgeot{
-
-/**An adaptor that adapts a two dimensional geometric_trans to include radial dimension.*/
-struct torus_geom_trans : public geometric_trans{
-
-  virtual void poly_vector_val(const base_node &, bgeot::base_vector &) const;
-  virtual void poly_vector_val(const base_node &, const bgeot::convex_ind_ct &,
-    bgeot::base_vector &) const;
-  virtual void poly_vector_grad(const base_node &, bgeot::base_matrix &) const;
-  inline virtual void poly_vector_grad(const base_node &,
-    const bgeot::convex_ind_ct &, bgeot::base_matrix &) const;
-  inline virtual void compute_K_matrix
-    (const bgeot::base_matrix &, const bgeot::base_matrix &, bgeot::base_matrix &) const;
-
-  virtual void poly_vector_hess(const base_node &, bgeot::base_matrix &) const;
-
-  torus_geom_trans(bgeot::pgeometric_trans poriginal_trans);
-
-  pgeometric_trans get_original_transformation() const;
-
-private:
-  pgeometric_trans poriginal_trans_;
-};
-
-pconvex_structure torus_structure_descriptor(pconvex_structure ori_structure);
-
-bool is_torus_structure(pconvex_structure cvs);
-
-pgeometric_trans torus_geom_trans_descriptor(pgeometric_trans poriginal_trans);
-
-bool is_torus_geom_trans(pgeometric_trans pgt);
-
-}
-
-namespace getfem
-{
-  /**Torus fem, the real grad base value is modified to compute radial grad of F/R.
-     It stores a reference to the original fem object. By default, torus_fem is vectorial.
-     There is an option to change it to a scalar form through set_to_scalar(bool is_scalar).
-     torus_mesh_fem will automatically check qdim of itself and set the form accordingly.
-  */
-  class torus_fem : public virtual_fem{
-
-  public :
-    virtual size_type index_of_global_dof(size_type cv, size_type i) const;
-    void base_value(const base_node &, base_tensor &) const;
-    void grad_base_value(const base_node &, base_tensor &) const;
-    void hess_base_value(const base_node &, base_tensor &) const;
-    void real_base_value(const fem_interpolation_context& c,
-      base_tensor &t, bool = true) const;
-    void real_grad_base_value(const fem_interpolation_context& c,
-      base_tensor &t, bool = true) const;
-    void real_hess_base_value(const fem_interpolation_context&,
-      base_tensor &, bool = true) const;
-
-    pfem get_original_pfem() const;
-
-    torus_fem(pfem pf) : virtual_fem(*pf), poriginal_fem_(pf), is_scalar_(false){
-      init();
-    }
-
-    void set_to_scalar(bool is_scalar);
-
-  protected :
-    void init();
-
-  private :
-    pfem poriginal_fem_;
-    bool is_scalar_;
-  };
-  
-  /**Copy an original 2D mesh to become a torus mesh with radial dimension.*/
-  class torus_mesh : public mesh
-  {
-  private:
-    bool is_adapted_;
-    
-  public:
-    torus_mesh(std::string name = std::string());
-    virtual scalar_type convex_radius_estimate(size_type ic) const;
-
-    void adapt();
-    void adapt(const getfem::mesh &original_mesh);
-  };
-
-  /**Mesh fem object that adapts */
-  class torus_mesh_fem : public mesh_fem{
-  public:
-
-    torus_mesh_fem(const torus_mesh &mesh, bgeot::dim_type dim) : mesh_fem(mesh, dim){}    
-    void enumerate_dof(void) const;
-
-  private:
-    void adapt_to_torus_();
-    void del_torus_fem_();
-  };
-
-}
-
-#endif /* GETFEM_TORUS_H__  */
+/**
+ at file getfem_torus.h
+ at brief Provides mesh and mesh fem of torus.
+ at date May 2014
+ at author Liang Jin Lim
+*/
+
+#pragma once
+
+#ifndef GETFEM_TORUS_H__
+#define GETFEM_TORUS_H__
+
+#include "getfem/getfem_mesh_fem.h"
+
+
+namespace bgeot{
+
+/**An adaptor that adapts a two dimensional geometric_trans to include radial dimension.*/
+struct torus_geom_trans : public geometric_trans{
+
+  virtual void poly_vector_val(const base_node &, bgeot::base_vector &) const;
+  virtual void poly_vector_val(const base_node &, const bgeot::convex_ind_ct &,
+    bgeot::base_vector &) const;
+  virtual void poly_vector_grad(const base_node &, bgeot::base_matrix &) const;
+  inline virtual void poly_vector_grad(const base_node &,
+    const bgeot::convex_ind_ct &, bgeot::base_matrix &) const;
+  inline virtual void compute_K_matrix
+    (const bgeot::base_matrix &, const bgeot::base_matrix &, bgeot::base_matrix &) const;
+
+  virtual void poly_vector_hess(const base_node &, bgeot::base_matrix &) const;
+
+  torus_geom_trans(bgeot::pgeometric_trans poriginal_trans);
+
+  pgeometric_trans get_original_transformation() const;
+
+private:
+  pgeometric_trans poriginal_trans_;
+};
+
+pconvex_structure torus_structure_descriptor(pconvex_structure ori_structure);
+
+bool is_torus_structure(pconvex_structure cvs);
+
+pgeometric_trans torus_geom_trans_descriptor(pgeometric_trans poriginal_trans);
+
+bool is_torus_geom_trans(pgeometric_trans pgt);
+
+}
+
+namespace getfem
+{
+  /**Torus fem, the real grad base value is modified to compute radial grad of F/R.
+     It stores a reference to the original fem object. By default, torus_fem is vectorial.
+     There is an option to change it to a scalar form through set_to_scalar(bool is_scalar).
+     torus_mesh_fem will automatically check qdim of itself and set the form accordingly.
+  */
+  class torus_fem : public virtual_fem{
+
+  public :
+    virtual size_type index_of_global_dof(size_type cv, size_type i) const;
+    void base_value(const base_node &, base_tensor &) const;
+    void grad_base_value(const base_node &, base_tensor &) const;
+    void hess_base_value(const base_node &, base_tensor &) const;
+    void real_base_value(const fem_interpolation_context& c,
+      base_tensor &t, bool = true) const;
+    void real_grad_base_value(const fem_interpolation_context& c,
+      base_tensor &t, bool = true) const;
+    void real_hess_base_value(const fem_interpolation_context&,
+      base_tensor &, bool = true) const;
+
+    pfem get_original_pfem() const;
+
+    torus_fem(pfem pf) : virtual_fem(*pf), poriginal_fem_(pf), is_scalar_(false){
+      init();
+    }
+
+    void set_to_scalar(bool is_scalar);
+
+  protected :
+    void init();
+
+  private :
+    pfem poriginal_fem_;
+    bool is_scalar_;
+  };
+  
+  /**Copy an original 2D mesh to become a torus mesh with radial dimension.*/
+  class torus_mesh : public mesh
+  {
+  private:
+    bool is_adapted_;
+    
+  public:
+    torus_mesh(std::string name = std::string());
+    virtual scalar_type convex_radius_estimate(size_type ic) const;
+
+    void adapt();
+    void adapt(const getfem::mesh &original_mesh);
+  };
+
+  /**Mesh fem object that adapts */
+  class torus_mesh_fem : public mesh_fem{
+  public:
+
+    torus_mesh_fem(const torus_mesh &mesh, bgeot::dim_type dim) : mesh_fem(mesh, dim){}    
+    void enumerate_dof(void) const;
+
+  private:
+    void adapt_to_torus_();
+    void del_torus_fem_();
+  };
+
+}
+
+#endif /* GETFEM_TORUS_H__  */
diff --git a/src/getfem_assembling_tensors.cc b/src/getfem_assembling_tensors.cc
index dfef675..4dd48e2 100644
--- a/src/getfem_assembling_tensors.cc
+++ b/src/getfem_assembling_tensors.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2003-2016 Julien Pommier
+ Copyright (C) 2003-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -162,16 +162,16 @@ namespace getfem {
               "of size " << rn << " with '"
               << s << "'");
           }
-          //cerr << "ts = " << child(n).ranges() << ", red="
-          //     << red[n].second << "\n";
-          bgeot::tensor_reduction::diag_shape(ts, red[n].second);
-          // cerr << "REDUCTION '" << red[n].second
-          //        << "' -> sending required to child#" << int(n)
-          //	<< " " << child(n).name() << ":" << endl;
-          // cerr << ts << endl;
-          child(n).merge_required_shape(ts);
-          // cerr << "------>required shape is now: "
-          //      << child(n).required_shape() << endl;
+	//cerr << "ts = " << child(n).ranges() << ", red="
+	//     << red[n].second << "\n";
+	bgeot::tensor_reduction::diag_shape(ts, red[n].second);
+	// cerr << "REDUCTION '" << red[n].second
+	//        << "' -> sending required to child#" << int(n)
+	//	<< " " << child(n).name() << ":" << endl;
+	// cerr << ts << endl;
+	child(n).merge_required_shape(ts);
+	// cerr << "------>required shape is now: "
+	//      << child(n).required_shape() << endl;
       }
     }
 
@@ -280,9 +280,8 @@ namespace getfem {
       if ((shape_updated_ = child(0).is_shape_updated())) {
         if (reorder.size() != child(0).ranges().size())
           ASM_THROW_TENSOR_ERROR("can't reorder tensor '" << name()
-          << "' of dimensions " 
-          << child(0).ranges() << 
-          " with this permutation: " << reorder);
+				 << "' of dimensions " << child(0).ranges() << 
+				 " with this permutation: " << vref(reorder));
         r_.resize(reorder.size());
         std::fill(r_.begin(), r_.end(), dim_type(-1));
 
@@ -1462,9 +1461,9 @@ namespace getfem {
       }
       if (check_permut.first_false() != reorder.size()) {
         cerr << check_permut << endl;
-        cerr << reorder << endl;
+        cerr << vref(reorder) << endl;
         ASM_THROW_PARSE_ERROR("you did not give a real permutation:"
-          << reorder);
+			      << vref(reorder));
       }
       t = tnode(record(std::make_unique<ATN_permuted_tensor>(*t.tensor(), reorder)));
     }
diff --git a/src/getfem_boost/workaround.hpp b/src/getfem_boost/workaround.hpp
old mode 100755
new mode 100644
diff --git a/src/getfem_contact_and_friction_common.cc b/src/getfem_contact_and_friction_common.cc
index bfe3e4c..d65366d 100644
--- a/src/getfem_contact_and_friction_common.cc
+++ b/src/getfem_contact_and_friction_common.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2013-2016 Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2013-2017 Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
@@ -43,10 +43,16 @@ namespace getfem {
       } else {
         ctx.pf()->interpolation_grad(ctx, coeff, grad, dim_type(ctx.N()));
         gmm::add(gmm::identity_matrix(), grad);
-        scalar_type J = gmm::lu_inverse(grad);
-        if (J <= scalar_type(0)) GMM_WARNING1("Inverted element !" << J);
+        scalar_type J = bgeot::lu_inverse(&(*(grad.begin())), ctx.N());
+        if (J <= scalar_type(0)) {GMM_WARNING1("Inverted element !" << J);
+            gmm::mult(gmm::transposed(grad), n0, n);
+            gmm::scale(n, gmm::sgn(J));
+            //cout<< "n0 =" <<  n0 << "n =" <<n<< endl;
+            //cout<< "x0=" <<  ctx.xref() << "x =" <<ctx.xreal()<< endl;
+            }
+       else {
         gmm::mult(gmm::transposed(grad), n0, n);
-        gmm::scale(n, gmm::sgn(J)); // Test
+        gmm::scale(n, gmm::sgn(J));} // Test
       }
   }
 
@@ -378,8 +384,7 @@ namespace getfem {
 
           if (!ref_conf)
             slice_vector_on_basic_dof_of_element(mfu, U, cv, coeff);
-          bgeot::vectors_to_base_matrix
-            (G, mfu.linked_mesh().points_of_convex(cv));
+          mfu.linked_mesh().points_of_convex(cv, G);
 
           pfem_precomp pfp(0);
           size_type nbptf(0);
@@ -577,8 +582,7 @@ namespace getfem {
           pfem_precomp pfp = fppool(pf_s, pgt->pgeometric_nodes());
           if (!ref_conf)
             slice_vector_on_basic_dof_of_element(mfu, U, cv, coeff);
-          bgeot::vectors_to_base_matrix
-            (G, mfu.linked_mesh().points_of_convex(cv));
+          mfu.linked_mesh().points_of_convex(cv, G);
           fem_interpolation_context ctx(pgt,pfp,size_type(-1), G, cv);
 
           size_type nb_pt_on_face = 0;
@@ -1045,7 +1049,7 @@ namespace getfem {
           slice_vector_on_basic_dof_of_element(mfu, disp_of_boundary(ib),
                                                cv, coeff);
 
-        bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
+        m.points_of_convex(cv, G);
 
         const base_node &x0 = pf_s->ref_convex(cv)->points_of_face(iff)[0];
         fem_interpolation_context ctx(pgt, pf_s, x0, G, cv, iff);
@@ -1100,7 +1104,7 @@ namespace getfem {
 
             for (size_type subiter(0);;) {
               pps(a, hessa);
-              det = gmm::abs(gmm::lu_inverse(hessa, false));
+	      det = gmm::abs(bgeot::lu_inverse(&(*(hessa.begin())),N-1, false));
               if (det > 1E-15) break;
               for (size_type i = 0; i < N-1; ++i)
                 a[i] += gmm::random() * 1E-7;
@@ -1160,7 +1164,7 @@ namespace getfem {
 
             for (size_type subiter(0);;) {
               pps(a, hessa);
-              det = gmm::abs(gmm::lu_inverse(hessa, false));
+	      det = gmm::abs(bgeot::lu_inverse(&(*(hessa.begin())),N-1, false));
               if (det > 1E-15) break;
               for (size_type i = 0; i < N-1; ++i)
                 a[i] += gmm::random() * 1E-7;
@@ -1283,7 +1287,7 @@ namespace getfem {
   
   class  raytracing_interpolate_transformation
     : public virtual_interpolate_transformation {
-
+  protected:
     // Structure describing a contact boundary
     struct contact_boundary {
       size_type region;            // Boundary number
@@ -1421,8 +1425,7 @@ namespace getfem {
             pfem pf_s = mfu.fem_of_element(cv);
             pfem_precomp pfp = fppool(pf_s, pgt->pgeometric_nodes());
             slice_vector_on_basic_dof_of_element(mfu, U, cv, coeff);
-            bgeot::vectors_to_base_matrix
-              (G, mfu.linked_mesh().points_of_convex(cv));
+            mfu.linked_mesh().points_of_convex(cv, G);
             fem_interpolation_context ctx(pgt, pfp, size_type(-1), G, cv);
             
             bgeot::pconvex_structure cvs = pgt->structure();
@@ -1639,7 +1642,7 @@ namespace getfem {
       // Computation of the deformed point and unit normal vectors
       //
       slice_vector_on_basic_dof_of_element(mfu_x, *(cb_x.U), cv_x, coeff_x);
-      bgeot::vectors_to_base_matrix(G_x, m_x.points_of_convex(cv_x));
+      m_x.points_of_convex(cv_x, G_x);
       ctx_x.set_pf(pfu_x);
       pfu_x->interpolation(ctx_x, coeff_x, pt_x, dim_type(N));
       pt_x += ctx_x.xreal();
@@ -1746,7 +1749,7 @@ namespace getfem {
         // Raytrace search for y by Newton's algorithm
         //
 
-        bgeot::vectors_to_base_matrix(G_y, m_y.points_of_convex(cv_y));
+        m_y.points_of_convex(cv_y, G_y);
         const base_node &Y0
           = pfu_y->ref_convex(cv_y)->points_of_face(face_y)[0];
         fem_interpolation_context ctx_y(pgt_y, pfu_y, Y0, G_y, cv_y, face_y);
@@ -1794,7 +1797,7 @@ namespace getfem {
           
           for (size_type subiter(0); subiter <= 4; ++subiter) {
             pps(a, hessa);
-            det = gmm::abs(gmm::lu_inverse(hessa, false));
+            det = gmm::abs(bgeot::lu_inverse(&(*(hessa.begin())), N-1, false));
             if (det > 1E-15) break;
             for (size_type i = 0; i < N-1; ++i)
               a[i] += gmm::random() * 1E-7;
@@ -1823,14 +1826,13 @@ namespace getfem {
           
           if (niter > 1 && dist_ref > 15) break;
           if (niter > 5 && dist_ref > 8) break;
-          if ((niter > 1 && dist_ref > 7) || nbfail == 3) exited = true;
+          if (/*(niter > 1 && dist_ref > 7) ||*/ nbfail == 3) exited = true;
         }
         bool converged = (gmm::vect_norm2(res) < 2E-6);
         bool is_in = (pfu_y->ref_convex(cv_y)->is_in(ctx_y.xref()) < 1E-6);
-        GMM_ASSERT1(!(exited && converged && is_in),
-                    "A non conformal case !! " << gmm::vect_norm2(res)
-                    << " : " << nbfail << " : " << niter);
-        
+       // GMM_ASSERT1(!(exited && converged && is_in),
+       //             "A non conformal case !! " << gmm::vect_norm2(res)
+       //             << " : " << nbfail << " : " << niter);
         if (is_in) {
           ctx_y.pf()->interpolation(ctx_y, coeff_y, pt_y, dim_type(N));
           pt_y += ctx_y.xreal();
@@ -1919,7 +1921,7 @@ namespace getfem {
             pfu_y->interpolation_grad(ctx_y, stored_coeff_y, F_y, dim_type(N));
             gmm::add(gmm::identity_matrix(), F_y);
             gmm::copy(F_y, F_y_inv);
-            gmm::lu_inverse(F_y_inv);
+            bgeot::lu_inverse(&(*(F_y_inv.begin())), N);
           } else {
             gmm::copy(gmm::identity_matrix(), F_y);
             gmm::copy(gmm::identity_matrix(), F_y_inv);
@@ -1930,7 +1932,7 @@ namespace getfem {
           pfu_x->interpolation_grad(ctx_x, coeff_x, F_x, dim_type(N));
           gmm::add(gmm::identity_matrix(), F_x);
           gmm::copy(F_x, F_x_inv);
-          gmm::lu_inverse(F_x_inv);
+          bgeot::lu_inverse(&(*(F_x_inv.begin())), N);
         
 
           base_tensor base_ux;
@@ -2007,7 +2009,434 @@ namespace getfem {
     raytracing_interpolate_transformation(scalar_type d)
       : release_distance(d) {}
   };
+//=========================================================================
+  //
+  //  Projection interpolate transformation for generic assembly
+  //
+  //=========================================================================
+
+ class  projection_interpolate_transformation
+    : public raytracing_interpolate_transformation {
+
+    scalar_type release_distance;  // Limit distance beyond which the contact
+                                   // will not be considered.
+  public:
+    int transform(const ga_workspace &workspace, const mesh &m_x,
+                  fem_interpolation_context &ctx_x,
+                  const base_small_vector &/*Normal*/,
+                  const mesh **m_t,
+                  size_type &cv, short_type &face_num, base_node &P_ref,
+                  base_small_vector &N_y,
+                  std::map<var_trans_pair, base_tensor> &derivatives,
+                  bool compute_derivatives) const {
+      size_type cv_x = ctx_x.convex_num();
+      short_type face_x = ctx_x.face_num();
+      GMM_ASSERT1(face_x != short_type(-1), "The contact transformation can "
+                  "only be applied to a boundary");
+
+      //
+      // Find the right (slave) contact boundary
+      //
+      mesh_boundary_cor::const_iterator it =  boundary_for_mesh.find(&m_x);
+      GMM_ASSERT1(it != boundary_for_mesh.end(),
+                  "Mesh with no declared contact boundary");
+      size_type ib_x = size_type(-1);
+      for (const auto &boundary_ind : it->second) {
+        const contact_boundary &cb = contact_boundaries[boundary_ind];
+        if (m_x.region(cb.region).is_in(cv_x, face_x))
+          { ib_x = boundary_ind; break; }
+      }
+      GMM_ASSERT1(ib_x != size_type(-1),
+                  "No contact region found for this point");
+      const contact_boundary &cb_x = contact_boundaries[ib_x];
+      const mesh_fem &mfu_x = *(cb_x.mfu); 
+      pfem pfu_x = mfu_x.fem_of_element(cv_x);
+      size_type N = mfu_x.linked_mesh().dim();
+      GMM_ASSERT1(mfu_x.get_qdim() == N,
+                  "Displacment field with wrong dimension");
+      
+      model_real_plain_vector coeff_x, coeff_y, stored_coeff_y;
+      base_small_vector a(N-1), b(N-1), pt_x(N), pt_y(N), n_x(N);
+      base_small_vector stored_pt_y(N), stored_n_y(N), stored_pt_y_ref(N);
+      base_small_vector n0_x, n_y(N), n0_y, res(N-1), res2(N-1), dir(N-1);
+      base_matrix G_x, G_y, grad(N,N), hessa(N-1, N-1);
+      std::vector<base_small_vector> ti(N-1);
+      scalar_type stored_signed_distance(0);
+      std::string stored_dispname;
+      scalar_type d0 = 1E300, d1, d2(0);
+      const mesh *stored_m_y(0);
+      size_type stored_cv_y(-1);
+      short_type stored_face_y(-1);
+      fem_interpolation_context stored_ctx_y;
+      size_type nbwarn(0);
+
+
+      //
+      // Computation of the deformed point and unit normal vectors
+      //
+      slice_vector_on_basic_dof_of_element(mfu_x, *(cb_x.U), cv_x, coeff_x);
+      bgeot::vectors_to_base_matrix(G_x, m_x.points_of_convex(cv_x));
+      ctx_x.set_pf(pfu_x);
+      pfu_x->interpolation(ctx_x, coeff_x, pt_x, dim_type(N));
+      pt_x += ctx_x.xreal();
+      compute_normal(ctx_x, face_x, false, coeff_x, n0_x, n_x, grad);
+      n_x /= gmm::vect_norm2(n_x);
+
+      //
+      //  Determine the nearest rigid obstacle, taking into account
+      //  the release distance.
+      //
+
+      bool first_pair_found = false;
+      size_type irigid_obstacle(-1);
+      for (size_type i = 0; i < obstacles.size(); ++i) {
+        const obstacle &obs = obstacles[i];
+        gmm::copy(pt_x, obs.point());
+        const base_tensor &t = obs.eval();
+        
+        GMM_ASSERT1(t.size() == 1, "Obstacle level set function as to be "
+                    "a scalar valued one");
+        d1 = t[0];
+        // cout << "d1 = " << d1 << endl;
+        if (gmm::abs(d1) < release_distance && d1 < d0) {
+          const base_tensor &t_der = obs.eval_derivative();
+          GMM_ASSERT1(t_der.size() == n_x.size(), "Bad derivative size");
+          if (gmm::vect_sp(t_der.as_vector(), n_x) < scalar_type(0)) 
+            { d0 = d1; irigid_obstacle = i; gmm::copy(t_der.as_vector(),n_y); }
+        }
+      }
+
+      if (irigid_obstacle != size_type(-1)) {
+        // cout << "Testing obstacle " << irigid_obstacle << endl;
+        const obstacle &obs = obstacles[irigid_obstacle];
+        gmm::copy(pt_x, obs.point());
+        gmm::copy(pt_x, pt_y);
+        size_type nit = 0, nb_fail = 0;
+        scalar_type alpha(0), beta(0);
+        d1 = d0;
+        
+        while (gmm::abs(d1) > 1E-13 && ++nit < 50 && nb_fail < 3) {
+          if (nit != 1) gmm::copy(obs.eval_derivative().as_vector(), n_y);
+
+          for (scalar_type lambda(1); lambda >= 1E-3; lambda/=scalar_type(2)) {
+          gmm::add(gmm::scaled(n_y, -d1/gmm::vect_norm2_sqr(n_y)), pt_y, pt_x);
 
+            if (gmm::abs(d2) < gmm::abs(d1)) break;
+          }
+          if (gmm::abs(beta - d1 / gmm::vect_sp(n_y, n_x)) > scalar_type(500))
+            nb_fail++;
+          beta = alpha; d1 = d2;
+        }
+        gmm::copy(obs.point(), pt_y);
+
+        if (gmm::abs(d1) > 1E-8) {
+           GMM_WARNING1("Raytrace on rigid obstacle failed");
+        } // CRITERION 4 for rigid bodies : Apply the release distance
+        else if (gmm::vect_dist2(pt_y, pt_x) <= release_distance) {
+          n_y /= gmm::vect_norm2(n_y);
+          d0 = gmm::vect_dist2(pt_y, pt_x) * gmm::sgn(d0);
+          stored_pt_y = stored_pt_y_ref = pt_y; stored_n_y = n_y, 
+          stored_signed_distance = d0;
+          first_pair_found = true;
+        } else
+          irigid_obstacle = size_type(-1);
+      }
+
+      //
+      // Determine the potential contact pairs with deformable bodies
+      //
+      bgeot::rtree::pbox_set bset;
+      base_node bmin(pt_x), bmax(pt_x);
+      for (size_type i = 0; i < N; ++i)
+        { bmin[i] -= release_distance; bmax[i] += release_distance; }
+
+      face_boxes.find_line_intersecting_boxes(pt_x, n_x, bmin, bmax, bset);
+            //
+      // Iteration on potential contact pairs and application
+      // of selection criteria
+      //
+      for (const auto &pbox : bset) {
+        face_box_info &fbox_y = face_boxes_info[pbox->id];
+        size_type ib_y = fbox_y.ind_boundary;
+        const contact_boundary &cb_y =  contact_boundaries[ib_y];
+        const mesh_fem &mfu_y = *(cb_y.mfu);
+        const mesh &m_y = mfu_y.linked_mesh();
+        bool ref_conf=false;
+        size_type cv_y = fbox_y.ind_element;
+        pfem pfu_y = mfu_y.fem_of_element(cv_y);
+        short_type face_y = fbox_y.ind_face;
+        bgeot::pgeometric_trans pgt_y= m_y.trans_of_convex(cv_y);
+
+        // CRITERION 1 : The unit normal vectors are compatible
+        //               and the two points are not in the same element.
+        if (gmm::vect_sp(fbox_y.mean_normal, n_x) >= scalar_type(0) ||
+            (cv_x == cv_y && &m_x == &m_y))
+          continue;
+
+        //
+        // Classical projection for y by quasi Newton algorithm
+        //
+        bgeot::vectors_to_base_matrix(G_y, m_y.points_of_convex(cv_y));
+        const base_node &Y0
+          = pfu_y->ref_convex(cv_y)->points_of_face(face_y)[0];
+        fem_interpolation_context ctx_y(pgt_y, pfu_y, Y0, G_y, cv_y, face_y);
+        
+        const base_small_vector &NY0
+          = pfu_y->ref_convex(cv_y)->normals()[face_y];
+
+         gmm::clear(a);
+
+        for (size_type k = 0; k < N-1; ++k) { // A basis for the face
+          gmm::resize(ti[k], N);
+          scalar_type norm(0);
+          while(norm < 1E-5) {
+            gmm::fill_random(ti[k]);
+            ti[k] -= gmm::vect_sp(ti[k], NY0) * NY0;
+            for (size_type l = 0; l < k; ++l)
+              ti[k] -= gmm::vect_sp(ti[k], ti[l]) * ti[l];
+            norm = gmm::vect_norm2(ti[k]);
+          }
+          ti[k] /= norm;
+        }        
+        slice_vector_on_basic_dof_of_element(mfu_y, *(cb_y.U), cv_y, coeff_y);
+        proj_pt_surf_cost_function_object pps(Y0, pt_x, ctx_y, coeff_y, ti,
+                                                1E-10, ref_conf);
+         base_small_vector grada(N-1);
+          scalar_type det(0);
+          scalar_type residual = gmm::vect_norm2(res);
+          scalar_type dist = pps(a, grada);
+          pps(a, res);
+          for (size_type niter = 0;
+               gmm::vect_norm2(grada) > 1E-7 && niter <= 50; ++niter) {
+
+            for (size_type subiter(0);;) {
+              pps(a, hessa);
+              det = gmm::abs(gmm::lu_inverse(hessa, false));
+              if (det > 1E-15) break;
+              for (size_type i = 0; i < N-1; ++i)
+                a[i] += gmm::random() * 1E-7;
+              if (++subiter > 4) break;
+            }
+            if (det <= 1E-15) break;
+            // Computation of the descent direction
+            gmm::mult(hessa, gmm::scaled(grada, scalar_type(-1)), dir);
+
+            // Line search
+            for (scalar_type lambda(1);
+                 lambda >= 1E-3; lambda /= scalar_type(2)) {
+              gmm::add(a, gmm::scaled(dir, lambda), b);
+              if (pps(b) < dist) break;
+              gmm::add(a, gmm::scaled(dir, -lambda), b);
+              if (pps(b) < dist) break;
+            }
+             //cout<< "b =" << b <<endl;
+            gmm::copy(b, a);
+            dist = pps(a, grada);
+          }
+
+          bool converged = (gmm::vect_norm2(grada) < 2E-6);
+          if (!converged) { // Try with BFGS
+            gmm::iteration iter(1E-10, 0 /* noisy*/, 100 /*maxiter*/);
+            gmm::clear(a);
+            gmm::bfgs(pps, pps, a, 10, iter, 0, 0.5);
+            residual = gmm::abs(iter.get_res());
+            converged = (residual < 2E-5);
+          }
+
+        bool is_in = (pfu_y->ref_convex(cv_y)->is_in(ctx_y.xref()) < 1E-6);
+         
+          //cout<< "y_ref =" << ctx_y.xref() <<endl;
+          //cout<< "x_ref =" << ctx_x.xref() <<endl;
+         // cout<< "y =" << ctx_y.xreal() <<endl;
+         // cout<< "x =" << ctx_x.xreal() <<endl;
+        // cout<< "is_in =" << is_in <<endl;
+
+        if (is_in || (!converged )) {
+          if (!ref_conf) {
+            ctx_y.pf()->interpolation(ctx_y, coeff_y, pt_y, dim_type(N));
+            pt_y += ctx_y.xreal();
+          } else {
+            pt_y = ctx_y.xreal();
+          }
+        }
+        // CRITERION 2 : The contact pair is eliminated when
+        //               projection/raytrace do not converge.
+        if (!converged) {
+          if ( nbwarn < 4) {
+            GMM_WARNING3("Projection algorithm did not converge "
+                         "for point " << pt_x << " residual " << residual
+                         << " projection computed " << pt_y);
+            ++nbwarn;
+          }
+          continue;
+        }
+
+        // CRITERION 3 : The projected point is inside the element
+        //               The test should be completed: If the point is outside
+        //               the element, a rapid reprojection on the face
+        //               (on the reference element, with a linear algorithm)
+        //               can be applied and a test with a neigbhour element
+        //               to decide if the point is in fact ok ...
+        //               (to be done only if there is no projection on other
+        //               element which coincides and with a test on the
+        //               distance ... ?) To be specified (in this case,
+        //               change xref).
+        if (!is_in) continue;
+
+        // CRITERION 4 : Apply the release distance
+
+        scalar_type signed_dist = gmm::vect_dist2(pt_y, pt_x);
+        //cout<< "signd_dist="<< signed_dist << "relaese_dist="<< release_distance <<endl;
+        if (signed_dist > release_distance) continue;
+
+        // compute the unit normal vector at y and the signed distance.
+        base_small_vector ny0(N);
+        compute_normal(ctx_y, face_y, ref_conf, coeff_y, ny0, n_y, grad);
+        // ny /= gmm::vect_norm2(ny); // Useful only if the unit normal is kept
+        signed_dist *= gmm::sgn(gmm::vect_sp(pt_x - pt_y, n_y));
+
+        // CRITERION 5 : comparison with rigid obstacles
+        // CRITERION 7 : smallest signed distance on contact pairs
+        if (first_pair_found && stored_signed_distance < signed_dist)
+            continue;
+
+        // CRITERION 1 : again on found unit normal vector
+        if (gmm::vect_sp(n_y, n_x) >= scalar_type(0)) continue;
+
+        // CRITERION 6 : for self-contact only : apply a test on
+        //               unit normals in reference configuration.
+        if (&m_x == &m_y) {
+
+          base_small_vector diff = ctx_x.xreal() - ctx_y.xreal();
+          scalar_type ref_dist = gmm::vect_norm2(diff);
+
+          if ( (ref_dist < scalar_type(4) * release_distance)
+               && (gmm::vect_sp(diff, ny0) < - 0.01 * ref_dist) )
+            continue;
+        }
+
+        stored_pt_y = pt_y; stored_pt_y_ref = ctx_y.xref();
+        stored_m_y = &m_y; stored_cv_y = cv_y; stored_face_y = face_y;
+        stored_n_y = n_y;
+        stored_ctx_y = ctx_y;
+        stored_coeff_y = coeff_y;
+        stored_signed_distance = signed_dist;
+        stored_dispname = cb_y.dispname;
+        first_pair_found = true;
+        irigid_obstacle = size_type(-1);
+
+          // Projection could be ameliorated by finding a starting point near
+          // x (with respect to the integration method, for instance).
+
+          // A specific (Quasi) Newton algorithm for computing the projection
+      }   
+
+      int ret_type = 0;
+      *m_t = 0; cv = size_type(-1); face_num = short_type(-1);
+      if (irigid_obstacle != size_type(-1)) {
+        P_ref = stored_pt_y; N_y = stored_n_y;
+        ret_type = 2;
+      } else if (first_pair_found) {
+        *m_t = stored_m_y; cv = stored_cv_y; face_num = stored_face_y;
+        P_ref = stored_pt_y_ref;
+        ret_type = 1;
+      }
+      // Note on derivatives of the transformation : for efficiency and
+      // simplicity reasons, the derivative should be computed with
+      // the value of corresponding test functions. This means that
+      // for a transformation F(u) the conputed derivative is F'(u).Test_u
+      // including the Test_u.
+
+      if (compute_derivatives) {
+        if (ret_type >= 1) {
+          fem_interpolation_context &ctx_y = stored_ctx_y;
+          size_type cv_y = 0;
+          if (ret_type == 1) cv_y = ctx_y.convex_num();
+        
+          
+          base_matrix I_nyny(N,N); // I - ny at ny
+          gmm::copy(gmm::identity_matrix(), I_nyny);
+          gmm::rank_one_update(I_nyny, stored_n_y,
+                               gmm::scaled(stored_n_y,scalar_type(-1)));
+        
+          // Computation of F_y
+          base_matrix F_y(N,N), F_y_inv(N,N), M1(N, N), M2(N, N);
+          pfem pfu_y = 0;
+          if (ret_type == 1) {
+            pfu_y = ctx_y.pf();
+            pfu_y->interpolation_grad(ctx_y, stored_coeff_y, F_y, dim_type(N));
+            gmm::add(gmm::identity_matrix(), F_y);
+            gmm::copy(F_y, F_y_inv);
+            gmm::lu_inverse(F_y_inv);
+          } else {
+            gmm::copy(gmm::identity_matrix(), F_y);
+            gmm::copy(gmm::identity_matrix(), F_y_inv);
+          }
+
+
+          base_tensor base_ux;
+          base_matrix vbase_ux;
+          ctx_x.base_value(base_ux);
+          size_type qdim_ux = pfu_x->target_dim();
+          size_type ndof_ux = pfu_x->nb_dof(cv_x) * N / qdim_ux;
+          vectorize_base_tensor(base_ux, vbase_ux, ndof_ux, qdim_ux, N);
+          
+          base_tensor base_uy;
+          base_matrix vbase_uy;
+          size_type ndof_uy = 0;
+          if (ret_type == 1) {
+            ctx_y.base_value(base_uy);
+            size_type qdim_uy = pfu_y->target_dim();
+            ndof_uy = pfu_y->nb_dof(cv_y) * N / qdim_uy;
+            vectorize_base_tensor(base_uy, vbase_uy, ndof_uy, qdim_uy, N);
+          }
+          
+          base_tensor grad_base_ux, vgrad_base_ux;
+          ctx_x.grad_base_value(grad_base_ux);
+          vectorize_grad_base_tensor(grad_base_ux, vgrad_base_ux, ndof_ux,
+                                     qdim_ux, N);
+
+          // Derivative : F_y^{-1}*I_nyny*(Test_u(X)-Test_u(Y))
+          //         and I_nyny*(I - ny at ny) = I_nyny
+          
+          // F_y^{-1}*I_nyny*Test_u(X)
+          gmm::mult(F_y_inv, I_nyny, M1);
+          base_matrix der_x(ndof_ux, N);
+          gmm::mult(vbase_ux, gmm::transposed(M1), der_x);
+          
+          // -F_y^{-1}*I_nyny*Test_u(Y)
+          base_matrix der_y(ndof_uy, N);
+          if (ret_type == 1) {
+            gmm::mult(vbase_uy, gmm::transposed(M1), der_y);
+            gmm::scale(der_y, scalar_type(-1));
+          }
+
+          const std::string &dispname_x
+            = workspace.variable_in_group(cb_x.dispname, m_x);
+
+          for (auto&& d : derivatives) {
+            if (dispname_x.compare(d.first.varname) == 0 &&
+                d.first.transname.size() == 0) {
+              d.second.adjust_sizes(ndof_ux, N);
+              gmm::copy(der_x.as_vector(), d.second.as_vector());
+            } else if (ret_type == 1 &&
+                       stored_dispname.compare(d.first.varname) == 0 &&
+                       d.first.transname.size() != 0) {
+              d.second.adjust_sizes(ndof_uy, N);
+              gmm::copy(der_y.as_vector(), d.second.as_vector());
+            } else
+              d.second.adjust_sizes(0, 0);
+          }
+        } else {
+          for (auto&& d : derivatives)
+            d.second.adjust_sizes(0, 0);
+        }
+      }
+      return ret_type;
+    }
+    projection_interpolate_transformation(const scalar_type &d)
+      :raytracing_interpolate_transformation(d), release_distance(d) {}
+  };
   void add_raytracing_transformation
   (model &md, const std::string &transname, scalar_type d) {
     pinterpolate_transformation
@@ -2082,6 +2511,80 @@ namespace getfem {
     p->add_rigid_obstacle(workspace, expr, N);
   }
 
+ void add_projection_transformation
+  (model &md, const std::string &transname, scalar_type d) {
+    pinterpolate_transformation
+      p = std::make_shared<projection_interpolate_transformation>(d);
+    md.add_interpolate_transformation(transname, p);
+  }
+
+  void add_projection_transformation
+  (ga_workspace &workspace, const std::string &transname, scalar_type d) {
+    pinterpolate_transformation
+      p = std::make_shared<projection_interpolate_transformation>(d);
+    workspace.add_interpolate_transformation(transname, p);
+  }
+
+  void add_master_contact_boundary_to_projection_transformation
+  (model &md, const std::string &transname, const mesh &m,
+   const std::string &dispname, size_type region) {
+    projection_interpolate_transformation *p
+      = dynamic_cast<projection_interpolate_transformation *>
+      (const_cast<virtual_interpolate_transformation *>
+       (&(*(md.interpolate_transformation(transname)))));
+    p->add_contact_boundary(md, m, dispname, region, false);
+  }
+
+  void add_slave_contact_boundary_to_projection_transformation
+  (model &md, const std::string &transname, const mesh &m,
+   const std::string &dispname, size_type region) {
+    projection_interpolate_transformation *p
+      = dynamic_cast<projection_interpolate_transformation *>
+      (const_cast<virtual_interpolate_transformation *>
+       (&(*(md.interpolate_transformation(transname)))));
+    p->add_contact_boundary(md, m, dispname, region, true);
+  }
+
+  void add_master_contact_boundary_to_projection_transformation
+  (ga_workspace &workspace, const std::string &transname, const mesh &m,
+   const std::string &dispname, size_type region) {
+    projection_interpolate_transformation *p
+      = dynamic_cast<projection_interpolate_transformation *>
+      (const_cast<virtual_interpolate_transformation *>
+       (&(*(workspace.interpolate_transformation(transname)))));
+    p->add_contact_boundary(workspace, m, dispname, region, false);
+  }
+
+  void add_slave_contact_boundary_to_projection_transformation
+  (ga_workspace &workspace, const std::string &transname, const mesh &m,
+   const std::string &dispname, size_type region) {
+    projection_interpolate_transformation *p
+      = dynamic_cast<projection_interpolate_transformation *>
+      (const_cast<virtual_interpolate_transformation *>
+       (&(*(workspace.interpolate_transformation(transname)))));
+    p->add_contact_boundary(workspace, m, dispname, region, true);
+  }
+
+  void add_rigid_obstacle_to_projection_transformation
+  (model &md, const std::string &transname,
+   const std::string &expr, size_type N) {
+    projection_interpolate_transformation *p
+      = dynamic_cast<projection_interpolate_transformation *>
+      (const_cast<virtual_interpolate_transformation *>
+       (&(*(md.interpolate_transformation(transname)))));
+    p->add_rigid_obstacle(md, expr, N);
+  }
+
+  void add_rigid_obstacle_to_projection_transformation
+  (ga_workspace &workspace, const std::string &transname,
+   const std::string &expr, size_type N) {
+    projection_interpolate_transformation *p
+      = dynamic_cast<projection_interpolate_transformation *>
+      (const_cast<virtual_interpolate_transformation *>
+       (&(*(workspace.interpolate_transformation(transname)))));
+    p->add_rigid_obstacle(workspace, expr, N);
+  }
+
 
 
   //=========================================================================
@@ -2114,7 +2617,7 @@ namespace getfem {
       base_matrix F(N, N);
       gmm::copy(args[0]->as_vector(), F.as_vector());
       gmm::add(gmm::identity_matrix(), F);
-      gmm::lu_inverse(F);
+      bgeot::lu_inverse(&(*(F.begin())), N);
       gmm::mult(gmm::transposed(F), args[1]->as_vector(), result.as_vector());
       gmm::scale(result.as_vector(),
                  scalar_type(1)/gmm::vect_norm2(result.as_vector()));
@@ -2135,7 +2638,7 @@ namespace getfem {
       base_small_vector ndef(N), aux(N);
       gmm::copy(args[0]->as_vector(), F.as_vector());
       gmm::add(gmm::identity_matrix(), F);
-      gmm::lu_inverse(F);
+      bgeot::lu_inverse(&(*(F.begin())), N);
       gmm::mult(gmm::transposed(F), args[1]->as_vector(), ndef);
       scalar_type norm_ndef = gmm::vect_norm2(ndef);
       gmm::scale(ndef, scalar_type(1)/norm_ndef);
@@ -2321,6 +2824,7 @@ namespace getfem {
           gmm::add(gmm::scaled(n, g/nn), dg);
         for (size_type i = 0; i < N; ++i, ++it)
           *it = dg[i];
+        it = result.end();
         break;
       case 6:
         base_small_vector dtau_df(s_f);
diff --git a/src/getfem_contact_and_friction_integral.cc b/src/getfem_contact_and_friction_integral.cc
index 11b8b4b..bd480de 100644
--- a/src/getfem_contact_and_friction_integral.cc
+++ b/src/getfem_contact_and_friction_integral.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2011-2016 Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2011-2017 Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
@@ -126,7 +126,8 @@ namespace getfem {
     // one-dimensional tensors [N]
 
     case RHS_U_V1:
-      for (i=0; i<N; ++i) t[i] = ln * no[i]; break;
+      for (i=0; i<N; ++i) t[i] = ln * no[i];
+      break;
     case RHS_U_V2:
       e = -gmm::neg(ln-r*(un - g));
       for (i=0; i<N; ++i) t[i] = e * no[i];
@@ -157,7 +158,8 @@ namespace getfem {
       for (i=0; i<N; ++i) t[i] = auxN[i];
       break;
     case RHS_U_FRICT_V1:
-      for (i=0; i<N; ++i) t[i] = lnt[i]; break;
+      for (i=0; i<N; ++i) t[i] = lnt[i];
+      break;
     case RHS_U_FRICT_V4:
       e = gmm::neg(ln);
       // if (e > 0. && ctx.xreal()[1] > 1.)
@@ -2226,7 +2228,7 @@ namespace getfem {
         }
       }
 
-      GMM_ASSERT1(matl.size() == contact_only ? 3 : 4,
+      GMM_ASSERT1(matl.size() == (contact_only ? 3 : 4),
                   "Wrong number of terms for penalized contact "
                   "between nonmatching meshes brick");
 
@@ -2664,6 +2666,7 @@ namespace getfem {
   //
   //=========================================================================
 
+#if (0) // Deprecated brick : uses the old Neumann terms
 
   struct Nitsche_fictitious_domain_contact_brick : public virtual_brick {
 
@@ -3210,8 +3213,7 @@ namespace getfem {
   }
 
 
-
-
+#endif
 
 
 }  /* end of namespace getfem.                                             */
diff --git a/src/getfem_contact_and_friction_large_sliding.cc b/src/getfem_contact_and_friction_large_sliding.cc
index b23f702..b1bb1e9 100644
--- a/src/getfem_contact_and_friction_large_sliding.cc
+++ b/src/getfem_contact_and_friction_large_sliding.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2013-2016 Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2013-2017 Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
@@ -508,7 +508,7 @@ namespace getfem {
     const base_matrix &grad_phix_inv(void) {
       if (!grad_phix_inv_init) {
         gmm::copy(grad_phix(), grad_phix_inv_);
-        /* scalar_type J = */ gmm::lu_inverse(grad_phix_inv_);
+        /* scalar_type J = */ gmm::lu_inverse(grad_phix_inv_); 
         // if (J <= scalar_type(0)) GMM_WARNING1("Inverted element !" << J);
         grad_phix_inv_init = true;
       }
@@ -1441,7 +1441,7 @@ namespace getfem {
             n0 = bgeot::compute_normal(ctx, v.f());
             pf_s->interpolation_grad(ctx, coeff, grad, dim_type(N));
             gmm::add(gmm::identity_matrix(), grad);
-            scalar_type J = gmm::lu_inverse(grad);
+            scalar_type J = bgeot::lu_inverse(&(*(grad.begin())), N);
             if (J <= scalar_type(0)) GMM_WARNING1("Inverted element ! " << J);
             gmm::mult(gmm::transposed(grad), n0, n);
             n /= gmm::vect_norm2(n);
@@ -1514,7 +1514,7 @@ namespace getfem {
 
     ctxu.pf()->interpolation_grad(ctxu, coeff, gradinv, dim_type(N));
     gmm::add(gmm::identity_matrix(), gradinv);
-    scalar_type J = gmm::lu_inverse(gradinv); // remplacer par une resolution...
+    scalar_type J = bgeot::lu_inverse(&(*(grad_inv.begin())), N); // remplacer par une resolution...
     if (J <= scalar_type(0)) {
       GMM_WARNING1("Inverted element !");
 
@@ -2632,12 +2632,345 @@ namespace getfem {
 
 
 
+ struct Nitsche_large_sliding_contact_brick_raytracing
+    : public virtual_brick {
+
+    struct contact_boundary {
+      size_type region;
+      std::string varname_u;
+      std::string sigma_u;
+      std::string varname_w;
+      bool is_master;
+      bool is_slave;
+      bool is_unbiased;
+      const mesh_im *mim;
+      
+      std::string expr;
+    };
+
+    std::vector<contact_boundary> boundaries;
+    std::string transformation_name;
+    std::string u_group;
+    std::string w_group;
+    std::string friction_coeff;
+    std::string alpha;
+    std::string Nitsche_param;
+    model::varnamelist vl, dl;
+    model::mimlist ml;
+
+    bool  sym_version, frame_indifferent, unbiased;
+
+    void add_contact_boundary(model &md, const mesh_im &mim, size_type region,
+                              bool is_master, bool is_slave, bool is_unbiased,
+                              const std::string &u,
+                              const std::string &sigma_u,
+                              const std::string &w = "") {
+      std::string test_u = "Test_" + sup_previous_and_dot_to_varname(u);
+      std::string test_u_group = "Test_" + sup_previous_and_dot_to_varname(u_group);
+      GMM_ASSERT1(is_slave || is_master, "The contact boundary should be "
+                  "either master, slave or both");
+      if (is_unbiased) {
+                        GMM_ASSERT1((is_slave && is_master), "The contact boundary should be "
+                          "both master and slave for the unbiased version");
+                        is_slave=true; is_master=true;
+                       }
+      const mesh_fem *mf = md.pmesh_fem_of_variable(u);
+      GMM_ASSERT1(mf, "The displacement variable should be a f.e.m. one");
+      GMM_ASSERT1(&(mf->linked_mesh()) == &(mim.linked_mesh()),
+                  "The displacement variable and the integration method "
+                  "should share the same mesh");
 
+      if (w.size()) {
+        const mesh_fem *mf2 =  md.pmesh_fem_of_variable(w);
+        GMM_ASSERT1(!mf2 || &(mf2->linked_mesh()) == &(mf->linked_mesh()),
+                    "The data for the sliding velocity should be defined on "
+                    " the same mesh as the displacement variable");
+      }
 
+      for (size_type i = 0; i < boundaries.size(); ++i) {
+        const contact_boundary &cb = boundaries[i];
+        if (&(md.mesh_fem_of_variable(cb.varname_u).linked_mesh())
+            == &(mf->linked_mesh()) && cb.region == region)
+          GMM_ASSERT1(false, "This contact boundary has already been added");
+      }
+      if (is_master)
+        add_master_contact_boundary_to_raytracing_transformation
+          (md, transformation_name, mf->linked_mesh(), u_group, region);
+      else
+         add_slave_contact_boundary_to_raytracing_transformation
+          (md, transformation_name, mf->linked_mesh(), u_group, region);
+      
+      boundaries.push_back(contact_boundary());
+      contact_boundary &cb = boundaries.back();
+      cb.region = region;
+      cb.varname_u = u;
+      if (is_slave) cb.sigma_u = sigma_u;
+      cb.varname_w = w;
+      cb.is_master = is_master;
+      cb.is_slave = is_slave;
+      cb.is_unbiased= is_unbiased;
+      cb.mim = &mim;
+      if (is_slave) {
+        std::string n, n0, Vs, g, Y, gamma;
+
+        gamma ="("+Nitsche_param+"/element_size)";
+        n = "Transformed_unit_vector(Grad_"+u+", Normal)";
+        n0 = "Transformed_unit_vector(Grad_"+w+", Normal)";
+
+        // For deformable bodies:
+        // Coulomb_friction_coupled_projection(sigma(u),
+        //    Transformed_unit_vector(Grad_u, Normal),
+        //    (u-Interpolate(ug,trans)-(w-Interpolate(wg,trans)))*alpha,
+        //    (Interpolate(X,trans)+Interpolate(ug,trans)-X-u).
+        //      Transformed_unit_vector(Grad_u, Normal), f, r)
+        Y = "Interpolate(X,"+transformation_name+")";
+        g = "("+Y+"+Interpolate("+u_group+","+transformation_name+")-X-"+u+")."+n;
+        Vs = "("+u+"-Interpolate("+u_group+","+transformation_name+")";
+        if (w.size()) {
+          Vs += "-"+w+"+Interpolate("+w_group+","+transformation_name+")";
+          if (frame_indifferent)
+            Vs += "+("+g+")*("+n+"-"+n0+")";
+        }
+        Vs += ")*"+alpha;
+
+        std::string coupled_projection_def =
+          "Coulomb_friction_coupled_projection("
+          + sigma_u +","+n+","+Vs+","+g+","+friction_coeff+","
+          + gamma +")";
+
+        // For regid obstacle:
+        // Coulomb_friction_coupled_projection(sigma(u),
+        //   Transformed_unit_vector(Grad_u, Normal), (u-w)*alpha,
+        //   (Interpolate(X,trans)-X-u).Transformed_unit_vector(Grad_u,
+        //                                                      Normal), f, r)
+        g = "(Interpolate(X,"+transformation_name+")-X-"+u+")."+n;
+        if (frame_indifferent && w.size())
+          Vs = "("+u+"-"+w+"+"+g+"*("+n+"-"+n0+"))*"+alpha;
+        else
+          Vs = "("+u+(w.size() ? ("-"+w):"")+")*"+alpha;
+
+        std::string coupled_projection_rig =
+          "Coulomb_friction_coupled_projection("
+          + sigma_u +","+n+","+Vs+","+g+","+ friction_coeff+","
+          + gamma +")";
+
+        cb.expr =
+          // 0.5* for non-biaised version
+          (is_unbiased ? "-0.5*" : "-")
+          // -coupled_projection_def.Test_u 
+          + ("Interpolate_filter("+transformation_name+","
+                            +coupled_projection_def+"."+test_u+",1) ") 
+          +(is_unbiased ? "":"-Interpolate_filter("+transformation_name+","
+                            +coupled_projection_rig+"."+test_u+",2) ")
+          // Interpolate_filter(trans,
+          //                   lambda.Interpolate(Test_ug, contact_trans), 1)
+          // or
+          // Interpolate_filter(trans,
+          //     coupled_projection_def.Interpolate(Test_ug, contact_trans), 1)
+          + (is_unbiased ? "+ 0.5*" : "+ ")
+          +"Interpolate_filter("+transformation_name+","
+                            +coupled_projection_def +".Interpolate("+test_u_group+"," + transformation_name+"), 1)"
+          +(is_unbiased ? "":"+ Interpolate_filter("+transformation_name+","
+                            +coupled_projection_rig +".Interpolate("+test_u_group+"," + transformation_name+"), 2)");                  
+        }
+      }
+
+    virtual void asm_real_tangent_terms(const model &md, size_type ,
+                                        const model::varnamelist &,
+                                        const model::varnamelist &,
+                                        const model::mimlist &,
+                                        model::real_matlist &,
+                                        model::real_veclist &,
+                                        model::real_veclist &,
+                                        size_type,
+                                        build_version) const {
+      // GMM_ASSERT1(mims.size() == 1,
+      //            "Generic linear assembly brick needs one and only one "
+      //            "mesh_im"); // to be verified ...
+
+      for (const contact_boundary &cb : boundaries) {
+        if (cb.is_slave)
+          md.add_generic_expression(cb.expr, *(cb.mim), cb.region);
+      }
+    }
+
+
+    Nitsche_large_sliding_contact_brick_raytracing
+    ( bool unbia,
+      const std::string &Nitsche_parameter,
+     const std::string &f_coeff,const std::string &ug,
+     const std::string &wg, const std::string &tr,
+     const std::string &alpha_ = "1", bool sym_v = false,
+     bool frame_indiff = false) {
+      transformation_name = tr;
+      u_group = ug; w_group = wg;
+      friction_coeff = f_coeff;
+      alpha = alpha_;
+      Nitsche_param = Nitsche_parameter;
+      sym_version = sym_v;
+      frame_indifferent = frame_indiff;
+      unbiased = unbia;
+
+      set_flags("Integral large sliding contact bick raytracing",
+                false /* is linear*/,
+                false /* is symmetric */, false /* is coercive */,
+                true /* is real */, false /* is complex */);
+    }
+
+  };
+
+  
+  const std::string &transformation_name_of_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick) {
+    pbrick pbr = md.brick_pointer(indbrick);
+    Nitsche_large_sliding_contact_brick_raytracing *p
+      = dynamic_cast<Nitsche_large_sliding_contact_brick_raytracing *>
+      (const_cast<virtual_brick *>(pbr.get()));
+    GMM_ASSERT1(p, "Wrong type of brick");
+    return p->transformation_name;
+  }
+
+  const std::string &displacement_group_name_of_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick) {
+    pbrick pbr = md.brick_pointer(indbrick);
+    Nitsche_large_sliding_contact_brick_raytracing *p
+      = dynamic_cast<Nitsche_large_sliding_contact_brick_raytracing *>
+      (const_cast<virtual_brick *>(pbr.get()));
+    GMM_ASSERT1(p, "Wrong type of brick");
+    return p->u_group;
+  }
+
+  const std::string &sliding_data_group_name_of_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick) {
+    pbrick pbr = md.brick_pointer(indbrick);
+    Nitsche_large_sliding_contact_brick_raytracing *p
+      = dynamic_cast<Nitsche_large_sliding_contact_brick_raytracing *>
+      (const_cast<virtual_brick *>(pbr.get()));
+    GMM_ASSERT1(p, "Wrong type of brick");
+    return p->w_group;
+  }
+
+  void add_rigid_obstacle_to_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick, const std::string &expr, size_type N) {
+    pbrick pbr = md.brick_pointer(indbrick);
+    Nitsche_large_sliding_contact_brick_raytracing *p
+      = dynamic_cast<Nitsche_large_sliding_contact_brick_raytracing *>
+      (const_cast<virtual_brick *>(pbr.get()));
+    GMM_ASSERT1(p, "Wrong type of brick");
+    add_rigid_obstacle_to_raytracing_transformation
+      (md, p->transformation_name, expr, N);
+  }
+
+  void add_contact_boundary_to_Nitsche_large_sliding_contact_brick
+  (model &md, size_type indbrick, const mesh_im &mim, size_type region,
+   bool is_master, bool is_slave, bool is_unbiased, const std::string &u,
+   const std::string &sigma_u, const std::string &w) {
+
+    pbrick pbr = md.brick_pointer(indbrick);
+    Nitsche_large_sliding_contact_brick_raytracing *p
+      = dynamic_cast<Nitsche_large_sliding_contact_brick_raytracing *>
+      (const_cast<virtual_brick *>(pbr.get()));
+    GMM_ASSERT1(p, "Wrong type of brick");
+
+    bool found_u = false, found_sigma = false;
+    for (const auto & v : p->vl) {
+      if (v.compare(u) == 0) found_u = true;
+      if (v.compare(sigma_u) == 0) found_sigma = true;
+    }
+    if (!found_u) p->vl.push_back(u);
+    GMM_ASSERT1(!is_slave || sigma_u.size(),
+                "You should define an expression of sigma(u) on each slave boundary");
+   // if (is_slave && !found_sigma) p->vl.push_back(sigma_u);
+    if (!found_u)
+      md.change_variables_of_brick(indbrick, p->vl);
+
+    std::vector<std::string> ug = md.variable_group(p->u_group);
+    found_u = false;
+    for (const auto &uu : ug)
+      if (uu.compare(u) == 0) { found_u = true; break; }
+    if (!found_u) {
+      ug.push_back(u);
+      md.define_variable_group(p->u_group, ug);
+    }
+
+    if (w.size()) {
+      bool found_w = false;
+      for (const auto &ww : p->dl)
+        if (ww.compare(w) == 0) { found_w = true; break; }
+      if (!found_w) { 
+        p->dl.push_back(w);
+        md.change_data_of_brick(indbrick, p->dl);
+      }
+      std::vector<std::string> wg = md.variable_group(p->w_group);
+      found_w = false;
+      for (const auto &ww : wg)
+        if (ww.compare(w) == 0) { found_w = true; break; }
+      if (!found_w) {
+        wg.push_back(w);
+        md.define_variable_group(p->w_group, wg);
+      }
+    }
+
+    bool found_mim = false;
+    for (const auto &pmim : p->ml)
+      if (pmim == &mim) { found_mim = true; break; }
+    if (!found_mim) {
+      p->ml.push_back(&mim);
+      md.change_mims_of_brick(indbrick, p->ml);
+    }
+
+    p->add_contact_boundary(md, mim, region, is_master, is_slave,is_unbiased,
+                            u, sigma_u, w);
+  } 
+
+  size_type add_Nitsche_large_sliding_contact_brick_raytracing
+  (model &md, bool is_unbiased, const std::string &Nitsche_param,
+   scalar_type release_distance, const std::string &f_coeff, 
+   const std::string &alpha, bool sym_v, bool frame_indifferent) {
+
+    char ugroupname[50], wgroupname[50], transname[50];
+    for (int i = 0; i < 10000; ++i) {
+      sprintf(ugroupname, "disp__group_raytracing_%d", i);
+      if (!(md.variable_group_exists(ugroupname))
+          && !(md.variable_exists(ugroupname)))
+        break;
+    }
+    md.define_variable_group(ugroupname, std::vector<std::string>());
+
+    for (int i = 0; i < 10000; ++i) {
+      sprintf(wgroupname, "w__group_raytracing_%d", i);
+      if (!(md.variable_group_exists(wgroupname))
+          && !(md.variable_exists(wgroupname)))
+        break;
+    }
+    md.define_variable_group(wgroupname, std::vector<std::string>());
+
+    for (int i = 0; i < 10000; ++i) {
+      sprintf(transname, "trans__raytracing_%d", i);
+      if (!(md.interpolate_transformation_exists(transname)))
+        break;
+    }
+    add_raytracing_transformation(md, transname, release_distance);
+
+    model::varnamelist vl, dl;
+    if (md.variable_exists(Nitsche_param)) dl.push_back(Nitsche_param);
+    if (md.variable_exists(f_coeff)) dl.push_back(f_coeff);
+    if (md.variable_exists(alpha)) dl.push_back(alpha);
+    
+    auto p = std::make_shared<Nitsche_large_sliding_contact_brick_raytracing>
+      (is_unbiased, Nitsche_param , f_coeff, ugroupname, wgroupname, transname, alpha,
+       sym_v, frame_indifferent);
+    pbrick pbr(p);
+    p->dl = dl;
+    
+    return md.add_brick(pbr, p->vl, p->dl, model::termlist(), model::mimlist(),
+                        size_type(-1));
+  }
 
+}
 
 
 
 
 
-}  /* end of namespace getfem.                                             */
+  /* end of namespace getfem.                                             */
diff --git a/src/getfem_contact_and_friction_nodal.cc b/src/getfem_contact_and_friction_nodal.cc
index 5d3f199..164d111 100644
--- a/src/getfem_contact_and_friction_nodal.cc
+++ b/src/getfem_contact_and_friction_nodal.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard, Konstantinos Poulios.
+ Copyright (C) 2004-2017 Yves Renard, Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
@@ -318,7 +318,7 @@ namespace getfem {
         gmm::mult(grad_fc, gmm::transposed(base_ref_fc), grad_fc1);
         gmm::mult(G, grad_fc1, K);
         gmm::mult(gmm::transposed(K), K, CS);
-        gmm::lu_inverse(CS);
+        bgeot::lu_inverse(&(*(CS.begin())), P-1);
         gmm::mult(K, CS, B);
         gmm::mult(B, base_ref_fc, BB);
 
@@ -352,7 +352,7 @@ namespace getfem {
           pgt->poly_vector_grad(xp, grad_cv);
 
           base_matrix GG(N, nb_pts_cv);
-          vectors_to_base_matrix(GG, m.points_of_convex(cv));
+          m.points_of_convex(cv, GG);
 
           gmm::mult(GG, grad_cv, KK);
         }
@@ -416,7 +416,9 @@ namespace getfem {
         const mesh &mesh_m = cn_m->mf->linked_mesh();
         base_node slave_node = cn_s->mf->point_of_basic_dof(cn_s->dof);
         base_node master_node = cn_m->mf->point_of_basic_dof(cn_m->dof);
-        base_node un_sel(3), proj_node_sel(3), proj_node_ref_sel(3);
+        GMM_ASSERT1(slave_node.size() == qdim && master_node.size() == qdim,
+                    "Internal error");
+        base_node un_sel(qdim), proj_node_sel(qdim), proj_node_ref_sel(qdim);
         scalar_type is_in_min = 1e5;  //FIXME
         size_type cv_sel = 0;
         short_type fc_sel = 0;
@@ -424,7 +426,7 @@ namespace getfem {
         std::vector<short_type>::iterator fc;
         for (cv = cn_m->cvs.begin(), fc = cn_m->fcs.begin();
              cv != cn_m->cvs.end() && fc != cn_m->fcs.end(); cv++, fc++) {
-          base_node un(3), proj_node(3), proj_node_ref(3);
+          base_node un(qdim), proj_node(qdim), proj_node_ref(qdim);
           scalar_type is_in = projection_on_convex_face
             (mesh_m, *cv, *fc, master_node, slave_node, un, proj_node, proj_node_ref);
           if (is_in < is_in_min) {
@@ -439,8 +441,8 @@ namespace getfem {
         if (is_in_min < 0.05) {  //FIXME
           gap[row] = gmm::vect_sp(slave_node-proj_node_sel, un_sel);
 
-          base_node ut[3];
-          if (BT1) orthonormal_basis_to_unit_vec(d, un_sel, ut);
+	  std::vector<base_node> ut(d);
+          if (BT1) orthonormal_basis_to_unit_vec(d, un_sel, &(ut[0]));
 
           CONTACT_B_MATRIX *BN = 0;
           CONTACT_B_MATRIX *BT = 0;
@@ -473,7 +475,7 @@ namespace getfem {
           if (BN) {
             base_matrix G;
             base_matrix M(qdim, mf_disp->nb_basic_dof_of_element(cv_sel));
-            bgeot::vectors_to_base_matrix(G, mesh_m.points_of_convex(cv_sel));
+            mesh_m.points_of_convex(cv_sel, G);
             pfem pf = mf_disp->fem_of_element(cv_sel);
             bgeot::pgeometric_trans pgt = mesh_m.trans_of_convex(cv_sel);
             fem_interpolation_context
diff --git a/src/getfem_context.cc b/src/getfem_context.cc
index 19b77c6..346bb5a 100644
--- a/src/getfem_context.cc
+++ b/src/getfem_context.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -62,7 +62,7 @@ namespace getfem {
     dependencies.resize(s);
   }
 
-  void context_dependencies::invalid_context(void) const {
+  void context_dependencies::invalid_context() const {
     if (state != CONTEXT_INVALID) 
     {
       iterator_list it = dependent.begin(), ite = dependent.end();
@@ -84,7 +84,7 @@ namespace getfem {
     cd.dependent.push_back(this);
   }
   
-  bool context_dependencies::context_check(void) const 
+  bool context_dependencies::go_check() const 
   {
     if (state == CONTEXT_CHANGED) 
     {
@@ -103,7 +103,7 @@ namespace getfem {
     return false;
   }
   
-  void context_dependencies::touch(void) const 
+  void context_dependencies::touch() const 
   {
     if (!touched) 
     {
diff --git a/src/getfem_continuation.cc b/src/getfem_continuation.cc
index a91519e..0361db9 100644
--- a/src/getfem_continuation.cc
+++ b/src/getfem_continuation.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2011-2016 Tomas Ligursky, Yves Renard, Konstantinos Poulios
+ Copyright (C) 2011-2017 Tomas Ligursky, Yves Renard, Konstantinos Poulios
 
  This file is a part of GetFEM++
 
@@ -20,7 +20,7 @@
 ===========================================================================*/
 
 /** @file getfem_continuation.cc
-    @author Tomas Ligursky <tomas.ligursky at gmail.com>
+    @author Tomas Ligursky <tomas.ligursky at ugn.cas.cz>
     @author Yves Renard <Yves.Renard at insa-lyon.fr>
     @author Konstantinos Poulios <logari81 at googlemail.com>
     @date January 12, 2014.
diff --git a/src/getfem_error_estimate.cc b/src/getfem_error_estimate.cc
index 1293d6b..cda7135 100644
--- a/src/getfem_error_estimate.cc
+++ b/src/getfem_error_estimate.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2013-2016 Yves Renard
+ Copyright (C) 2013-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -78,7 +78,7 @@ namespace getfem {
       get_approx_im_or_fail(mim.int_method_of_element(cv));
       getfem::pfem pf1 = mf_u.fem_of_element(cv);
       scalar_type radius = m.convex_radius_estimate(cv);
-      bgeot::vectors_to_base_matrix(G1, m.points_of_convex(cv));
+      m.points_of_convex(cv, G1);
       coeff1.resize(mf_u.nb_basic_dof_of_element(cv));
       gmm::copy(gmm::sub_vector(U, gmm::sub_index(mf_u.ind_basic_dof_of_element(cv))), coeff1);
       getfem::fem_interpolation_context ctx1(pgt1, pf1, base_node(N), G1, cv);
@@ -110,7 +110,7 @@ namespace getfem {
 	
         bgeot::pgeometric_trans pgt2 = m.trans_of_convex(cvn);
         getfem::pfem pf2 = mf_u.fem_of_element(cvn);
-        bgeot::vectors_to_base_matrix(G2, m.points_of_convex(cvn));
+        m.points_of_convex(cvn, G2);
         coeff2.resize(mf_u.nb_basic_dof_of_element(cvn));
         gmm::copy(gmm::sub_vector(U, gmm::sub_index(mf_u.ind_basic_dof_of_element(cvn))), coeff2);
         getfem::fem_interpolation_context ctx2(pgt2, pf2, base_node(N), G2, cvn);
@@ -169,7 +169,7 @@ namespace getfem {
 	getfem::pfem pf1 = mf_u.fem_of_element(v.cv());
 	scalar_type radius = m.convex_radius_estimate(v.cv());
       
-	bgeot::vectors_to_base_matrix(G1, m.points_of_convex(v.cv()));
+	m.points_of_convex(v.cv(), G1);
       
 	coeff1.resize(mf_u.nb_basic_dof_of_element(v.cv()));
 	gmm::copy(gmm::sub_vector(U, gmm::sub_index(mf_u.ind_basic_dof_of_element(v.cv()))), coeff1);
@@ -218,7 +218,7 @@ namespace getfem {
         get_approx_im_or_fail(mim.int_method_of_element(v.cv()));
 	getfem::pfem pf1 = mf_u.fem_of_element(v.cv());
       
-	bgeot::vectors_to_base_matrix(G1, m.points_of_convex(v.cv()));
+	m.points_of_convex(v.cv(), G1);
       
 	coeff1.resize(mf_u.nb_basic_dof_of_element(v.cv()));
 	gmm::copy(gmm::sub_vector(U, gmm::sub_index(mf_u.ind_basic_dof_of_element(v.cv()))), coeff1);
diff --git a/src/getfem_export.cc b/src/getfem_export.cc
index 438ddf7..18bfc73 100644
--- a/src/getfem_export.cc
+++ b/src/getfem_export.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2001-2016 Yves Renard
+ Copyright (C) 2001-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -46,11 +46,13 @@ namespace getfem
       bgeot::sc(dm[vtk_export::VTK_QUADRATIC_QUAD]) = 0, 2, 7, 5, 1, 4, 6, 3;
       bgeot::sc(dm[vtk_export::VTK_TETRA]) = 0, 1, 2, 3;
       bgeot::sc(dm[vtk_export::VTK_QUADRATIC_TETRA]) = 0, 2, 5, 9, 1, 4, 3, 6, 7, 8;
+      bgeot::sc(dm[vtk_export::VTK_PYRAMID]) = 0, 1, 3, 2, 4;
       bgeot::sc(dm[vtk_export::VTK_WEDGE]) = 0, 1, 2, 3, 4, 5;
       //bgeot::sc(dm[vtk_export::VTK_QUADRATIC_WEDGE]) = 0, 6, 1, 7, 2, 8, 3, 4, 5;
       bgeot::sc(dm[vtk_export::VTK_VOXEL]) = 0, 1, 2, 3, 4, 5, 6, 7;
       bgeot::sc(dm[vtk_export::VTK_HEXAHEDRON]) = 0, 1, 3, 2, 4, 5, 7, 6;
       bgeot::sc(dm[vtk_export::VTK_QUADRATIC_HEXAHEDRON]) = 0, 2, 7, 5, 12, 14, 19, 17, 1, 4, 6, 3, 13, 16, 18, 15, 8, 9, 11, 10;
+      bgeot::sc(dm[vtk_export::VTK_QUADRATIC_PYRAMID]) = 0, 2, 8, 6, 13, 1, 5, 7, 3, 9, 10, 12, 11; // to be verified
       bgeot::sc(dm[vtk_export::VTK_BIQUADRATIC_QUAD]) = 0, 2, 8, 6, 1, 5, 7, 3, 4;
       bgeot::sc(dm[vtk_export::VTK_TRIQUADRATIC_HEXAHEDRON]) = 0, 2, 8, 6, 18, 20, 26, 24, 1, 5, 7, 3, 19, 23, 25, 21, 9, 11, 17, 15, 12, 14, 10, 16, 4, 22;
     }
@@ -163,10 +165,12 @@ namespace getfem
       else {
         pfem classical_pf1 = discontinuous ? classical_discontinuous_fem(pgt, 1)
                                            : classical_fem(pgt, 1);
-        short_type degree = short_type(((pf != classical_pf1 &&
-                                         pf->estimated_degree() > 1) ||
-                                        pgt->structure() !=
-                                        pgt->basic_structure()) ? 2 : 1);
+
+	short_type degree = 1;
+	if ((pf != classical_pf1 && pf->estimated_degree() > 1) ||
+		pgt->structure() != pgt->basic_structure())
+	  degree = 2;
+	  
         pmf->set_finite_element(cv, discontinuous ?
                                 classical_discontinuous_fem(pgt, degree) :
                                 classical_fem(pgt, degree));
@@ -181,25 +185,32 @@ namespace getfem
       int t = -1;
       size_type nbd = pmf->fem_of_element(cv)->nb_dof(cv);
       switch (pmf->fem_of_element(cv)->dim()) {
-        case 0: t = VTK_VERTEX; break;
-        case 1:
-          if (nbd == 2) t = VTK_LINE;
-          else if (nbd == 3) t = VTK_QUADRATIC_EDGE; break;
-        case 2:
-          if (nbd == 3) t = VTK_TRIANGLE;
-          else if (nbd == 4) t = check_voxel(m.points_of_convex(cv)) ? VTK_PIXEL : VTK_QUAD;
-          else if (nbd == 6) t = VTK_QUADRATIC_TRIANGLE;
-          else if (nbd == 8) t = VTK_QUADRATIC_QUAD;
-          else if (nbd == 9) t = VTK_BIQUADRATIC_QUAD; break;
-        case 3:
-          if (nbd == 4) t = VTK_TETRA;
-          else if (nbd == 10) t = VTK_QUADRATIC_TETRA;
-          else if (nbd == 8) t = check_voxel(m.points_of_convex(cv)) ? VTK_VOXEL : VTK_HEXAHEDRON;
-          else if (nbd == 20) t = VTK_QUADRATIC_HEXAHEDRON;
-          else if (nbd == 27) t = VTK_TRIQUADRATIC_HEXAHEDRON;
-          else if (nbd == 6) t = VTK_WEDGE; break;
+      case 0: t = VTK_VERTEX; break;
+      case 1:
+	if (nbd == 2) t = VTK_LINE;
+	else if (nbd == 3) t = VTK_QUADRATIC_EDGE;
+	break;
+      case 2:
+	if (nbd == 3) t = VTK_TRIANGLE;
+	else if (nbd == 4)
+	  t = check_voxel(m.points_of_convex(cv)) ? VTK_PIXEL : VTK_QUAD;
+	else if (nbd == 6) t = VTK_QUADRATIC_TRIANGLE;
+	else if (nbd == 8) t = VTK_QUADRATIC_QUAD;
+	else if (nbd == 9) t = VTK_BIQUADRATIC_QUAD;
+	break;
+      case 3:
+	if (nbd == 4) t = VTK_TETRA;
+	else if (nbd == 10) t = VTK_QUADRATIC_TETRA;
+	else if (nbd == 8)
+	  t = check_voxel(m.points_of_convex(cv)) ? VTK_VOXEL:VTK_HEXAHEDRON;
+	else if (nbd == 20) t = VTK_QUADRATIC_HEXAHEDRON;
+	else if (nbd == 27) t = VTK_TRIQUADRATIC_HEXAHEDRON;
+	else if (nbd == 6) t = VTK_WEDGE;
+	else if (nbd == 5) t = VTK_PYRAMID;
+	else if (nbd == 14) t = VTK_QUADRATIC_PYRAMID;
+	break;
       }
-      GMM_ASSERT1(t != -1, "semi internal error.. could not map " <<
+      GMM_ASSERT1(t != -1, "semi internal error. Could not map " <<
                   name_of_fem(pmf->fem_of_element(cv))
                 << " to a VTK cell type");
       pmf_cell_type[cv] = t;
@@ -535,7 +546,8 @@ namespace getfem
   { strncpy(header, s.c_str(), 256); header[255] = 0; }
 
   void dx_export::check_header() {
-    if (header_written) return; header_written = true;
+    if (header_written) return;
+    header_written = true;
     os << "# data file for IBM OpenDX, generated by GetFem++ v "
        << GETFEM_VERSION << "\n";
     os << "# " << header << "\n";
@@ -789,7 +801,7 @@ namespace getfem
   static const std::vector<unsigned>& getfem_to_pos_dof_mapping(int t) {
     gf2pos_dof_mapping &dm = dal::singleton<gf2pos_dof_mapping>::instance();
     if (dm.size() == 0) {
-      dm.resize(7);
+      dm.resize(8);
       bgeot::sc(dm[pos_export::POS_PT]) = 0;
       bgeot::sc(dm[pos_export::POS_LN]) = 0, 1;
       bgeot::sc(dm[pos_export::POS_TR]) = 0, 1, 2;
@@ -797,6 +809,7 @@ namespace getfem
       bgeot::sc(dm[pos_export::POS_SI]) = 0, 1, 2, 3;
       bgeot::sc(dm[pos_export::POS_HE]) = 0, 1, 3, 2, 4, 5, 7, 6;
       bgeot::sc(dm[pos_export::POS_PR]) = 0, 1, 2, 3, 4, 5;
+      bgeot::sc(dm[pos_export::POS_PY]) = 0, 1, 3, 2, 4;
     }
     return dm[t];
   }
@@ -859,7 +872,8 @@ namespace getfem
         // could be a better test for discontinuity ...
         if (!dof_linkable(pf->dof_types()[i])) { discontinuous = true; break; }
       }
-      pfem classical_pf1 = discontinuous ? classical_discontinuous_fem(pgt, 1) : classical_fem(pgt, 1);
+      pfem classical_pf1 = discontinuous ?
+	classical_discontinuous_fem(pgt, 1) : classical_fem(pgt, 1);
       pmf->set_finite_element(cv, classical_pf1);
     }
     psl = NULL;
@@ -873,11 +887,13 @@ namespace getfem
         case 3: t = POS_TR; break;
         case 4:
           if ( 2 == pmf->fem_of_element(cv)->dim() ) t = POS_QU;
-          else if (3 == pmf->fem_of_element(cv)->dim()) t = POS_SI; break;
+          else if (3 == pmf->fem_of_element(cv)->dim()) t = POS_SI;
+	  break;
         case 6: t = POS_PR; break;
         case 8: t = POS_HE; break;
+        case 5: t = POS_PY; break;
       }
-      GMM_ASSERT1(t != -1, "semi internal error.. could not map "
+      GMM_ASSERT1(t != -1, "semi internal error. Could not map "
                            << name_of_fem(pmf->fem_of_element(cv))
                            << " to a POS primitive type");
       pos_cell_type.push_back(unsigned(t));
diff --git a/src/getfem_fem.cc b/src/getfem_fem.cc
index f3d9da0..43b6440 100644
--- a/src/getfem_fem.cc
+++ b/src/getfem_fem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -77,67 +77,175 @@ namespace getfem {
   // In that case, the storage available in ctx.pfp()->c, ctx.pfp()->pc
   // and ctx.pfp()->hpc is not used.
 
-  void fem_interpolation_context::base_value(base_tensor& t,
-                                             bool withM) const {
-    if (pf()->is_on_real_element())
-      pf()->real_base_value(*this, t);
+
+  // Specific multiplication for fem_interpolation_context use.
+  static inline void spec_mat_tmult_(const base_tensor &g, const base_matrix &B,
+				     base_tensor &t) {
+    size_type P = B.nrows(), N = B.ncols();
+    size_type M = t.adjust_sizes_changing_last(g, P);
+    bgeot::mat_tmult(&(*(g.begin())), &(*(B.begin())), &(*(t.begin())),M,N,P);
+  }
+  
+  void fem_interpolation_context::pfp_base_value(base_tensor& t,
+                                                 const pfem_precomp &pfp__) {
+    const pfem &pf__ = pfp__->get_pfem();
+    GMM_ASSERT1(ii_ != size_type(-1), "Internal error");
+
+    if (pf__->is_standard())
+      t = pfp__->val(ii());
     else {
-      base_tensor u;
-      if (have_pfp() && ii() != size_type(-1)) {
-        switch(pf()->vectorial_type()) {
+      if (pf__->is_on_real_element())
+        pf__->real_base_value(*this, t);
+      else {
+        switch(pf__->vectorial_type()) {
+        case virtual_fem::VECTORIAL_NOTRANSFORM_TYPE:
+          t = pfp__->val(ii()); break;
         case virtual_fem::VECTORIAL_PRIMAL_TYPE:
-          t.mat_transp_reduction(pfp_->val(ii()), K(), 1); break;
+          t.mat_transp_reduction(pfp__->val(ii()), K(), 1); break;
         case virtual_fem::VECTORIAL_DUAL_TYPE:
-          t.mat_transp_reduction(pfp_->val(ii()), B(), 1); break;
-        default: t = pfp_->val(ii());
+          t.mat_transp_reduction(pfp__->val(ii()), B(), 1); break;
+        }
+        if (!(pf__->is_equivalent())) {
+          set_pfp(pfp__);
+          { base_tensor u = t; t.mat_transp_reduction(u, M(), 0); }
         }
       }
+    }
+  }
+
+
+  void fem_interpolation_context::base_value(base_tensor& t,
+                                             bool withM) const {
+    if (pfp_ && ii_ != size_type(-1) && pf_->is_standard())
+      t = pfp_->val(ii());
+    else {
+      if (pf_->is_on_real_element())
+        pf_->real_base_value(*this, t);
       else {
-        switch(pf()->vectorial_type()) {
-        case virtual_fem::VECTORIAL_PRIMAL_TYPE:
-          pf()->base_value(xref(), u); t.mat_transp_reduction(u,K(),1); break;
-        case virtual_fem::VECTORIAL_DUAL_TYPE:
-          pf()->base_value(xref(), u); t.mat_transp_reduction(u,B(),1); break;
-        default: pf()->base_value(xref(), t);
+        if (pfp_ && ii_ != size_type(-1)) {
+          switch(pf_->vectorial_type()) {
+          case virtual_fem::VECTORIAL_NOTRANSFORM_TYPE:
+            t = pfp_->val(ii()); break;
+          case virtual_fem::VECTORIAL_PRIMAL_TYPE:
+            t.mat_transp_reduction(pfp_->val(ii()), K(), 1); break;
+          case virtual_fem::VECTORIAL_DUAL_TYPE:
+            t.mat_transp_reduction(pfp_->val(ii()), B(), 1); break;
+          }
+        }
+        else {
+          switch(pf_->vectorial_type()) {
+          case virtual_fem::VECTORIAL_NOTRANSFORM_TYPE:
+            pf_->base_value(xref(), t); break;
+          case virtual_fem::VECTORIAL_PRIMAL_TYPE:
+            {
+              base_tensor u; pf_->base_value(xref(), u);
+              t.mat_transp_reduction(u,K(),1);
+            } break;
+          case virtual_fem::VECTORIAL_DUAL_TYPE:
+            {
+              base_tensor u; pf_->base_value(xref(), u);
+              t.mat_transp_reduction(u,B(),1);
+            } break;
+          }
         }
+        if (withM && !(pf_->is_equivalent()))
+          { base_tensor u = t; t.mat_transp_reduction(u, M(), 0); }
       }
-      if (!(pf()->is_equivalent()) && withM)
-        { u = t; t.mat_transp_reduction(u, M(), 0); }
     }
   }
 
-  void fem_interpolation_context::grad_base_value(base_tensor& t,
-                                                  bool withM) const {
-    if (pf()->is_on_real_element())
-      pf()->real_grad_base_value(*this, t);
-    else {
-      base_tensor u;
-      if (have_pfp() && ii() != size_type(-1)) {
-        switch(pf()->vectorial_type()) {
+  void fem_interpolation_context::pfp_grad_base_value
+  (base_tensor& t, const pfem_precomp &pfp__) {
+    const pfem &pf__ = pfp__->get_pfem();
+    GMM_ASSERT1(ii_ != size_type(-1), "Internal error");
+
+    if (pf__->is_standard()) {
+      // t.mat_transp_reduction(pfp__->grad(ii()), B(), 2);
+      spec_mat_tmult_(pfp__->grad(ii()), B(), t);
+    } else {
+      if (pf__->is_on_real_element())
+        pf__->real_grad_base_value(*this, t);
+      else {
+        switch(pf__->vectorial_type()) {
         case virtual_fem::VECTORIAL_PRIMAL_TYPE:
-          u.mat_transp_reduction(pfp_->grad(ii()), B(), 2);
-          t.mat_transp_reduction(u, K(), 1); break;
+          {
+            base_tensor u;
+            // u.mat_transp_reduction(pfp__->grad(ii()), B(), 2);
+	    spec_mat_tmult_(pfp__->grad(ii()), B(), u);
+            t.mat_transp_reduction(u, K(), 1);
+          }
+          break;
         case virtual_fem::VECTORIAL_DUAL_TYPE:
-          u.mat_transp_reduction(pfp_->grad(ii()), B(), 2);
-          t.mat_transp_reduction(u, B(), 1); break;
-        default: t.mat_transp_reduction(pfp_->grad(ii()), B(), 2);
+          {
+            base_tensor u;
+            // u.mat_transp_reduction(pfp__->grad(ii()), B(), 2);
+	    spec_mat_tmult_(pfp__->grad(ii()), B(), u);
+            t.mat_transp_reduction(u, B(), 1);
+          }
+          break;
+        default:
+	  // t.mat_transp_reduction(pfp__->grad(ii()), B(), 2);
+	  spec_mat_tmult_(pfp__->grad(ii()), B(), t);
         }
+        if (!(pf__->is_equivalent())) {
+          set_pfp(pfp__);
+          base_tensor u = t; t.mat_transp_reduction(u, M(), 0);
+        }
+      }
+    }
+  }
+
 
-      } else {
-        pf()->grad_base_value(xref(), u);
-        if (u.size()) { /* only if the FEM can provide grad_base_value */
-          t.mat_transp_reduction(u, B(), 2);
+  void fem_interpolation_context::grad_base_value(base_tensor& t,
+                                                  bool withM) const {
+    if (pfp_ && ii_ != size_type(-1) && pf_->is_standard()) {
+      // t.mat_transp_reduction(pfp_->grad(ii()), B(), 2);
+      spec_mat_tmult_(pfp_->grad(ii()), B(), t);
+    } else {
+      if (pf()->is_on_real_element())
+        pf()->real_grad_base_value(*this, t);
+      else {
+        if (have_pfp() && ii() != size_type(-1)) {
           switch(pf()->vectorial_type()) {
           case virtual_fem::VECTORIAL_PRIMAL_TYPE:
-            u = t; t.mat_transp_reduction(u, K(), 1); break;
+            {
+              base_tensor u;
+              // u.mat_transp_reduction(pfp_->grad(ii()), B(), 2);
+	      spec_mat_tmult_(pfp_->grad(ii()), B(), u);
+              t.mat_transp_reduction(u, K(), 1);
+            }
+            break;
           case virtual_fem::VECTORIAL_DUAL_TYPE:
-            u = t; t.mat_transp_reduction(u, B(), 1); break;
-          default: break;
+            {
+              base_tensor u;
+              // u.mat_transp_reduction(pfp_->grad(ii()), B(), 2);
+	      spec_mat_tmult_(pfp_->grad(ii()), B(), u);
+              t.mat_transp_reduction(u, B(), 1);
+            }
+            break;
+          default:
+	    // t.mat_transp_reduction(pfp_->grad(ii()), B(), 2);
+	    spec_mat_tmult_(pfp_->grad(ii()), B(), t);
+          }
+          
+        } else {
+          base_tensor u;
+          pf()->grad_base_value(xref(), u);
+          if (u.size()) { /* only if the FEM can provide grad_base_value */
+	    // t.mat_transp_reduction(u, B(), 2);
+            spec_mat_tmult_(u, B(), t);
+            switch(pf()->vectorial_type()) {
+            case virtual_fem::VECTORIAL_PRIMAL_TYPE:
+              u = t; t.mat_transp_reduction(u, K(), 1); break;
+            case virtual_fem::VECTORIAL_DUAL_TYPE:
+              u = t; t.mat_transp_reduction(u, B(), 1);  break;
+            default: break;
+            }
           }
         }
+        if (withM && !(pf()->is_equivalent()))
+          { base_tensor u = t; t.mat_transp_reduction(u, M(), 0); }
       }
-      if (!(pf()->is_equivalent()) && withM)
-        { u = t; t.mat_transp_reduction(u, M(), 0); }
     }
   }
 
@@ -148,7 +256,9 @@ namespace getfem {
     else {
       base_tensor tt;
       if (have_pfp() && ii() != size_type(-1))
-        tt = pfp()->hess(ii()); else pf()->hess_base_value(xref(), tt);
+        tt = pfp()->hess(ii());
+      else
+        pf()->hess_base_value(xref(), tt);
 
       switch(pf()->vectorial_type()) {
       case virtual_fem::VECTORIAL_PRIMAL_TYPE:
@@ -159,10 +269,7 @@ namespace getfem {
       }
 
       if (tt.size()) { /* only if the FEM can provide hess_base_value */
-        bgeot::multi_index mim(3);
-        mim[2] = gmm::sqr(tt.sizes()[2]); mim[1] = tt.sizes()[1];
-        mim[0] = tt.sizes()[0];
-        tt.adjust_sizes(mim);
+        tt.adjust_sizes(tt.sizes()[0], tt.sizes()[1], gmm::sqr(tt.sizes()[2]));
         t.mat_transp_reduction(tt, B3(), 2);
         if (!pgt()->is_linear()) {
           if (have_pfp()) {
@@ -196,30 +303,6 @@ namespace getfem {
     }
   }
 
-  fem_interpolation_context::fem_interpolation_context() :
-    bgeot::geotrans_interpolation_context(),
-    convex_num_(size_type(-1)), face_num_(short_type(-1)), xfem_side_(0) {}
-  fem_interpolation_context::fem_interpolation_context
-  (bgeot::pgeotrans_precomp pgp__, pfem_precomp pfp__, size_type ii__,
-   const base_matrix& G__, size_type convex_num__, short_type face_num__) :
-    bgeot::geotrans_interpolation_context(pgp__,ii__,G__),
-    convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
-    { set_pfp(pfp__); }
-  fem_interpolation_context::fem_interpolation_context
-  (bgeot::pgeometric_trans pgt__, pfem_precomp pfp__, size_type ii__,
-   const base_matrix& G__, size_type convex_num__, short_type face_num__) :
-    bgeot::geotrans_interpolation_context(pgt__,pfp__->get_ppoint_tab(),
-                                          ii__, G__),
-    convex_num_(convex_num__), face_num_(face_num__), xfem_side_(0)
-  { set_pfp(pfp__); }
-  fem_interpolation_context::fem_interpolation_context(
-   bgeot::pgeometric_trans pgt__, pfem pf__,
-   const base_node& xref__,const base_matrix& G__, size_type convex_num__,
-   short_type face_num__) :
-    bgeot::geotrans_interpolation_context(pgt__,xref__,G__),
-    pf_(pf__), pfp_(0), convex_num_(convex_num__), face_num_(face_num__),
-    xfem_side_(0) {}
-
   void virtual_fem::real_base_value(const fem_interpolation_context &c,
                                     base_tensor &t, bool withM) const
   { c.base_value(t, withM); }
@@ -245,10 +328,12 @@ namespace getfem {
     gmm::int16_type hier_degree;
     short_type hier_raff;
     bool operator < (const ddl_elem &l) const {
-      if (t < l.t) return true; if (t > l.t) return false;
+      if (t < l.t) return true;
+      if (t > l.t) return false;
       if (hier_degree < l.hier_degree) return true;
       if (hier_degree > l.hier_degree) return false;
-      if (hier_raff < l.hier_raff) return true; return false;
+      if (hier_raff < l.hier_raff) return true;
+      return false;
     }
     ddl_elem(ddl_type s = LAGRANGE, gmm::int16_type k = -1, short_type l = 0)
       : t(s), hier_degree(k), hier_raff(l) {}
@@ -275,15 +360,20 @@ namespace getfem {
                                          const dof_description &n) const {
     int nn = gmm::lexicographical_less<std::vector<ddl_elem> >()
       (m.ddl_desc, n.ddl_desc);
-    if (nn < 0) return -1; if (nn > 0) return 1;
+    if (nn < 0) return -1;
+    if (nn > 0) return 1;
     nn = int(m.linkable) - int(n.linkable);
-    if (nn < 0) return -1; if (nn > 0) return 1;
+    if (nn < 0) return -1;
+    if (nn > 0) return 1;
     nn = int(m.coord_index) - int(n.coord_index);
-    if (nn < 0) return -1; if (nn > 0) return 1;
+    if (nn < 0) return -1;
+    if (nn > 0) return 1;
     nn = int(m.xfem_index) - int(n.xfem_index);
-    if (nn < 0) return -1; if (nn > 0) return 1;
+    if (nn < 0) return -1;
+    if (nn > 0) return 1;
     nn = int(m.all_faces) - int(n.all_faces);
-    if (nn < 0) return -1; if (nn > 0) return 1;
+    if (nn < 0) return -1;
+    if (nn > 0) return 1;
     return 0;
   }
 
@@ -591,6 +681,7 @@ namespace getfem {
     is_pol = f.is_pol;
     is_polycomp = f.is_polycomp;
     real_element_defined = f.real_element_defined;
+    is_standard_fem = f.is_standard_fem;
     es_degree = f.es_degree;
     hier_raff = f.hier_raff;
     debug_name_ = f.debug_name_;
@@ -638,7 +729,7 @@ namespace getfem {
   PK_fem_::PK_fem_(dim_type nc, short_type k) {
     cvr = bgeot::simplex_of_reference(nc);
     dim_ = cvr->structure()->dim();
-    is_equiv = is_pol = is_lag = true;
+    is_standard_fem = is_equiv = is_pol = is_lag = true;
     es_degree = k;
 
     init_cvs_node();
@@ -685,7 +776,8 @@ namespace getfem {
     is_equiv = fi1->is_equivalent() && fi2->is_equivalent();
     GMM_ASSERT1(is_equiv,
                 "Product of non equivalent elements not available, sorry.");
-    is_lag = fi1->is_lagrange() && fi2->is_lagrange();;
+    is_lag = fi1->is_lagrange() && fi2->is_lagrange();
+    is_standard_fem = fi1->is_standard() && fi2->is_standard();
     es_degree = short_type(fi1->estimated_degree() + fi2->estimated_degree());
 
     bgeot::convex<base_node> cv
@@ -860,7 +952,7 @@ namespace getfem {
       name << "FEM_PK_HIERARCHICAL(1," << k << ")";
     else
       name << "FEM_PRODUCT(FEM_PK_HIERARCHICAL(" << n-1 << "," << k
-           << "),FEM_PK(1_HIERARCHICAL," << k << "))";
+           << "),FEM_PK_HIERARCHICAL(1," << k << "))";
     return fem_descriptor(name.str());
   }
 
@@ -990,7 +1082,8 @@ namespace getfem {
     auto p = std::make_shared<fem<base_poly>>();
     p->mref_convex() = bgeot::simplex_of_reference(2);
     p->dim() = 2;
-    p->is_equivalent() = p->is_polynomial() = p->is_lagrange() = true;
+    p->is_standard() = p->is_equivalent() = true;
+    p->is_polynomial() = p->is_lagrange() = true;
     p->estimated_degree() = 1;
     p->init_cvs_node();
     p->base().resize(3);
@@ -1009,7 +1102,7 @@ namespace getfem {
 
 
   /* ******************************************************************** */
-  /*        Quad8/Hexa20 SERENDIPITY ELEMENT (dim 2 or 3) (incomplete Q2)     */
+  /*     Quad8/Hexa20 SERENDIPITY ELEMENT (dim 2 or 3) (incomplete Q2)    */
   /* ******************************************************************** */
 
   // local dof numeration for 2D:
@@ -1045,7 +1138,8 @@ namespace getfem {
     auto p = std::make_shared<fem<base_poly>>();
     p->mref_convex() = bgeot::parallelepiped_of_reference(n);
     p->dim() = n;
-    p->is_equivalent() = p->is_polynomial() = p->is_lagrange() = true;
+    p->is_standard() = p->is_equivalent() = true;
+    p->is_polynomial() = p->is_lagrange() = true;
     p->estimated_degree() = 2;
     p->init_cvs_node();
     p->base().resize(n == 2 ? 8 : 20);
@@ -1131,8 +1225,146 @@ namespace getfem {
   }
 
 
+  /* ******************************************************************** */
+  /*    Lagrange Pyramidal element of degree 0, 1 and 2                   */
+  /* ******************************************************************** */
+
+  // local dof numeration for K=1:
+  //    4 
+  //   /|||
+  //  / || |
+  // 2-|--|-3
+  // | |  | |
+  // ||    ||
+  // ||    ||
+  // 0------1
+  //
+  // local dof numeration for K=2:
+  //
+  //    13
+  //   /  |
+  //  11---12
+  //  |    |
+  //  9----10
+  //  /     |
+  // 6---7---8
+  // |       |
+  // 3   4   5
+  // |       |
+  // 0---1---2
+
+  static pfem build_pyramidal_pk_fem(short_type k, bool disc) {
+    auto p = std::make_shared<fem<bgeot::base_rational_fraction>>();
+    p->mref_convex() = bgeot::pyramidal_element_of_reference(1);
+    p->dim() = 3;
+    p->is_standard() = p->is_equivalent() = true;
+    p->is_polynomial() = false;
+    p->is_lagrange() = true;
+    p->estimated_degree() = k;
+    p->init_cvs_node();
+    auto lag_dof = disc ? lagrange_nonconforming_dof(3) : lagrange_dof(3);
+
+    if (k == 0) {
+      p->base().resize(1);
+      p->base()[0] = bgeot::read_base_poly(3, "1");
+      p->add_node(lagrange_0_dof(3), base_small_vector(0.0, 0.0, 0.5));
+    } else if (k == 1) {
+      p->base().resize(5);
+      bgeot::base_rational_fraction // Q = xy/(1-z)
+	Q(bgeot::read_base_poly(3, "x*y"), bgeot::read_base_poly(3, "1-z"));
+      p->base()[0] = (bgeot::read_base_poly(3, "1-x-y-z") + Q)*0.25;
+      p->base()[1] = (bgeot::read_base_poly(3, "1+x-y-z") - Q)*0.25;
+      p->base()[2] = (bgeot::read_base_poly(3, "1-x+y-z") - Q)*0.25;
+      p->base()[3] = (bgeot::read_base_poly(3, "1+x+y-z") + Q)*0.25;
+      p->base()[4] = bgeot::read_base_poly(3, "z");
+
+      p->add_node(lag_dof, base_small_vector(-1.0, -1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector( 1.0, -1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector(-1.0,  1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector( 1.0,  1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector( 0.0,  0.0, 1.0));
+
+    } else if (k == 2) {
+      p->base().resize(14);
+
+      base_poly xi0  = bgeot::read_base_poly(3, "(1-z-x)*0.5");
+      base_poly xi1  = bgeot::read_base_poly(3, "(1-z-y)*0.5");
+      base_poly xi2  = bgeot::read_base_poly(3, "(1-z+x)*0.5");
+      base_poly xi3  = bgeot::read_base_poly(3, "(1-z+y)*0.5");
+      base_poly x    = bgeot::read_base_poly(3, "x");
+      base_poly y    = bgeot::read_base_poly(3, "y");
+      base_poly z    = bgeot::read_base_poly(3, "z");
+      base_poly ones = bgeot::read_base_poly(3, "1");
+      base_poly un_z = bgeot::read_base_poly(3, "1-z");
+      bgeot::base_rational_fraction Q(bgeot::read_base_poly(3, "1"), un_z);
+      
+      p->base()[ 0] = Q*Q*xi0*xi1*(x*y-z*un_z);
+      p->base()[ 1] = -Q*Q*xi0*xi1*xi2*y*4.;
+      p->base()[ 2] = Q*Q*xi1*xi2*(-x*y-z*un_z);
+      p->base()[ 3] = -Q*Q*xi3*xi0*xi1*x*4.;
+      p->base()[ 4] = Q*Q*xi0*xi1*xi2*xi3*16.;
+      p->base()[ 5] = Q*Q*xi1*xi2*xi3*x*4.;
+      p->base()[ 6] = Q*Q*xi3*xi0*(-x*y-z*un_z);
+      p->base()[ 7] = Q*Q*xi2*xi3*xi0*y*4.;
+      p->base()[ 8] = Q*Q*xi2*xi3*(x*y-z*un_z);
+      p->base()[ 9] = Q*z*xi0*xi1*4.;
+      p->base()[10] = Q*z*xi1*xi2*4.;
+      p->base()[11] = Q*z*xi3*xi0*4.;
+      p->base()[12] = Q*z*xi2*xi3*4.;
+      p->base()[13] = bgeot::read_base_poly(3, "z*(2*z-1)");
+      
+      p->add_node(lag_dof, base_small_vector(-1.0, -1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector( 0.0, -1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector( 1.0, -1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector(-1.0,  0.0, 0.0));
+      p->add_node(lag_dof, base_small_vector( 0.0,  0.0, 0.0));
+      p->add_node(lag_dof, base_small_vector( 1.0,  0.0, 0.0));
+      p->add_node(lag_dof, base_small_vector(-1.0,  1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector( 0.0,  1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector( 1.0,  1.0, 0.0));
+      p->add_node(lag_dof, base_small_vector(-0.5, -0.5, 0.5));
+      p->add_node(lag_dof, base_small_vector( 0.5, -0.5, 0.5));
+      p->add_node(lag_dof, base_small_vector(-0.5,  0.5, 0.5));
+      p->add_node(lag_dof, base_small_vector( 0.5,  0.5, 0.5));
+      p->add_node(lag_dof, base_small_vector( 0.0,  0.0, 1.0));
+
+    } else GMM_ASSERT1(false, "Sorry, pyramidal Lagrange fem "
+		       "implemented only for degree 0, 1 or 2");
+    
+    return pfem(p);
+  }
+  
+  
+  static pfem pyramidal_pk_fem(fem_param_list &params,
+		      std::vector<dal::pstatic_stored_object> &dependencies) {
+    GMM_ASSERT1(params.size() <= 1, "Bad number of parameters");
+    short_type k = 2;
+    if (params.size() > 0) {
+      GMM_ASSERT1(params[0].type() == 0, "Bad type of parameters");
+      k = dim_type(::floor(params[0].num() + 0.01));
+    }
+    pfem p = build_pyramidal_pk_fem(k, false);
+    dependencies.push_back(p->ref_convex(0));
+    dependencies.push_back(p->node_tab(0));
+    return p;
+  }
+
+  static pfem pyramidal_disc_pk_fem(fem_param_list &params,
+		     std::vector<dal::pstatic_stored_object> &dependencies) {
+    GMM_ASSERT1(params.size() <= 1, "Bad number of parameters");
+    short_type k = 2;
+    if (params.size() > 0) {
+      GMM_ASSERT1(params[0].type() == 0, "Bad type of parameters");
+      k = dim_type(::floor(params[0].num() + 0.01));
+    }
+    pfem p = build_pyramidal_pk_fem(k, true);
+    dependencies.push_back(p->ref_convex(0));
+    dependencies.push_back(p->node_tab(0));
+    return p;
+  }
+
    /* ******************************************************************** */
-   /*        P1 element with a bubble base fonction on a face                   */
+   /*        P1 element with a bubble base fonction on a face              */
    /* ******************************************************************** */
 
    struct P1_wabbfoaf_ : public PK_fem_ {
@@ -1224,7 +1456,7 @@ namespace getfem {
     init_cvs_node();
     es_degree = 1;
     is_pol = true;
-    is_lag = is_equiv = false;
+    is_standard_fem = is_lag = is_equiv = false;
     ntarget_dim = nc;
     vtype = VECTORIAL_PRIMAL_TYPE;
     base_.resize(nc*(nc+1));
@@ -1321,7 +1553,7 @@ namespace getfem {
     init_cvs_node();
     es_degree = 1;
     is_pol = true;
-    is_lag = is_equiv = false;
+    is_standard_fem = is_lag = is_equiv = false;
     ntarget_dim = nc;
     vtype = VECTORIAL_PRIMAL_TYPE;
     base_.resize(nc*2*nc);
@@ -1425,7 +1657,7 @@ namespace getfem {
     init_cvs_node();
     es_degree = 1;
     is_pol = true;
-    is_lag = is_equiv = false;
+    is_standard_fem = is_lag = is_equiv = false;
     ntarget_dim = nc;
     vtype = VECTORIAL_DUAL_TYPE;
     base_.resize(nc*(nc+1)*nc/2);
@@ -2651,7 +2883,7 @@ namespace getfem {
   PK_GL_fem_::PK_GL_fem_(unsigned k) {
     cvr = bgeot::simplex_of_reference(1);
     dim_ = cvr->structure()->dim();
-    is_equiv = is_pol = is_lag = true;
+    is_standard_fem = is_equiv = is_pol = is_lag = true;
     es_degree = short_type(k);
     GMM_ASSERT1(k < fem_coeff_gausslob_max_k && fem_coeff_gausslob[k],
                 "try another degree");
@@ -2737,7 +2969,7 @@ namespace getfem {
     init_cvs_node();
     es_degree = 3;
     is_pol = true;
-    is_lag = is_equiv = false;
+    is_standard_fem = is_lag = is_equiv = false;
     base_.resize(4);
 
     pt[0] = 0.0; add_node(lagrange_dof(1), pt);
@@ -2791,7 +3023,7 @@ namespace getfem {
     init_cvs_node();
     es_degree = 3;
     is_pol = true;
-    is_lag = is_equiv = false;
+    is_standard_fem = is_lag = is_equiv = false;
     base_.resize(10);
 
     add_node(lagrange_dof(2), base_node(0.0, 0.0));
@@ -2862,7 +3094,7 @@ namespace getfem {
     init_cvs_node();
     es_degree = 3;
     is_pol = true;
-    is_lag = is_equiv = false;
+    is_standard_fem = is_lag = is_equiv = false;
     base_.resize(20);
     std::stringstream s
       ( "1 - 3*x*x - 13*x*y - 13*x*z - 3*y*y - 13*y*z - 3*z*z + 2*x*x*x"
@@ -3027,7 +3259,7 @@ namespace getfem {
     es_degree = 5;
     is_pol = true;
     is_lag = false;
-    is_equiv = false;
+    is_standard_fem = is_equiv = false;
     base_.resize(21);
 
     std::stringstream s
@@ -3172,7 +3404,7 @@ namespace getfem {
     init_cvs_node();
     es_degree = 2;
     is_pol = true;
-    is_lag = is_equiv = false;
+    is_standard_fem = is_lag = is_equiv = false;
     base_.resize(6);
 
     std::stringstream s("1 - x - y + 2*x*y;  (x + y + x^2 - 2*x*y - y^2)/2;"
@@ -3214,8 +3446,8 @@ namespace getfem {
       if (alpha != scalar_type(0)) {
         base_node G =
           gmm::mean_value(cv_node.points().begin(), cv_node.points().end());
-      for (size_type i=0; i < cv_node.nb_points(); ++i)
-        cv_node.points()[i] = (1-alpha)*cv_node.points()[i] + alpha*G;
+	for (size_type i=0; i < cv_node.nb_points(); ++i)
+	  cv_node.points()[i] = (1-alpha)*cv_node.points()[i] + alpha*G;
         for (size_type d = 0; d < nc; ++d) {
           base_poly S(1,2);
           S[0] = -alpha * G[d] / (1-alpha);
@@ -3308,7 +3540,7 @@ namespace getfem {
     DEFINE_STATIC_THREAD_LOCAL_INITIALIZED(short_type, k_last, short_type(-1));
     DEFINE_STATIC_THREAD_LOCAL_INITIALIZED(pfem, fm_last, 0);
     DEFINE_STATIC_THREAD_LOCAL_INITIALIZED(char, isuffix_last, 0);
-    bool found = false, isuffix = suffix[0];
+    bool found = false, isuffix = suffix[0], spec_dim = true;
 
     if (pgt_last == pgt && k_last == k && isuffix == isuffix_last)
       return fm_last;
@@ -3325,22 +3557,30 @@ namespace getfem {
     /* Identifying P1-simplexes.                                          */
     if (nbp == n+1)
       if (pgt->basic_structure() == bgeot::simplex_structure(dim_type(n)))
-            { name << "FEM_PK" << suffix << "("; found = true; }
+	{ name << "FEM_PK" << suffix << "("; found = true; }
 
     /* Identifying Q1-parallelepiped.                                     */
     if (!found && nbp == (size_type(1) << n))
       if (pgt->basic_structure()==bgeot::parallelepiped_structure(dim_type(n)))
-            { name << "FEM_QK" << suffix << "("; found = true; }
+	{ name << "FEM_QK" << suffix << "("; found = true; }
 
     /* Identifying Q1-prisms.                                             */
     if (!found && nbp == 2 * n)
       if (pgt->basic_structure() == bgeot::prism_structure(dim_type(n)))
-             { name << "FEM_PK_PRISM" << suffix << "("; found = true; }
+	{ name << "FEM_PK_PRISM" << suffix << "("; found = true; }
+    
+    /* Identifying pyramids.                                              */
+    if (!found && nbp == 5)
+      if (pgt->basic_structure() == bgeot::pyramidal_structure(1)) {
+	name << "FEM_PYRAMID" << suffix << "_LAGRANGE(";
+	found = true; spec_dim = false;
+      }
 
     // To be completed
 
     if (found) {
-      name << int(n) << ',' << int(k) << arg << ')';
+      if (spec_dim) name << int(n) << ',';
+      name << int(k) << arg << ')';
       fm_last = fem_descriptor(name.str());
       pgt_last = pgt;
       k_last = k;
@@ -3416,6 +3656,8 @@ namespace getfem {
       add_suffix("RT0", P1_RT0);
       add_suffix("RT0Q", P1_RT0Q);
       add_suffix("NEDELEC", P1_nedelec);
+      add_suffix("PYRAMID_LAGRANGE", pyramidal_pk_fem);
+      add_suffix("PYRAMID_DISCONTINUOUS_LAGRANGE", pyramidal_disc_pk_fem);
     }
   };
 
diff --git a/src/getfem_fem_composite.cc b/src/getfem_fem_composite.cc
index 51cbe6e..2f3c81e 100644
--- a/src/getfem_fem_composite.cc
+++ b/src/getfem_fem_composite.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -37,7 +37,7 @@ namespace getfem {
     auto p = std::make_shared<fem<bgeot::polynomial_composite>>();
     p->mref_convex() = cr;
     p->dim() = cr->structure()->dim();
-    p->is_polynomialcomp() = p->is_equivalent() = true;
+    p->is_polynomialcomp() = p->is_equivalent() = p->is_standard() = true;
     p->is_polynomial() = false;
     p->is_lagrange() = true;
     p->estimated_degree() = 0;
@@ -181,6 +181,7 @@ namespace getfem {
     is_equivalent() = true;
     is_polynomial() = false;
     is_lagrange() = false;
+    is_standard() = true;
     estimated_degree() = 3;
     init_cvs_node();
 
@@ -346,6 +347,7 @@ namespace getfem {
     is_equivalent() = false;
     is_polynomial() = false;
     is_lagrange() = false;
+    is_standard() = false;
     estimated_degree() = 5;
     init_cvs_node();
 
@@ -421,6 +423,7 @@ namespace getfem {
     is_equivalent() = false;
     is_polynomial() = false;
     is_lagrange() = false;
+    is_standard() = false;
     estimated_degree() = 5;
     base() = HCT->base();
 
@@ -610,6 +613,7 @@ namespace getfem {
     is_equivalent() = false;
     is_polynomial() = false;
     is_lagrange() = false;
+    is_standard() = false;
     estimated_degree() = 5;
     init_cvs_node();
 
@@ -690,6 +694,7 @@ namespace getfem {
     is_equivalent() = false;
     is_polynomial() = false;
     is_lagrange() = false;
+    is_standard() = false;
     estimated_degree() = 5;
     base() = HCT->base();
 
diff --git a/src/getfem_fem_global_function.cc b/src/getfem_fem_global_function.cc
index 9c3f8ad..74ef34b 100644
--- a/src/getfem_fem_global_function.cc
+++ b/src/getfem_fem_global_function.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
  Copyright (C) 2016      Konstantinos Poulios
 
  This file is a part of GetFEM++
@@ -26,7 +26,7 @@ namespace getfem {
 
 
   void fem_global_function::init() {
-    is_pol = is_lag = false; es_degree = 5;
+    is_pol = is_lag = is_standard_fem = false; es_degree = 5;
     is_equiv = real_element_defined = true;
     ntarget_dim = 1; // An extension for vectorial elements should be easy
 
@@ -68,19 +68,17 @@ namespace getfem {
 
   void fem_global_function::update_from_context() const {
 
-    precompval.clear();
-    precompgrad.clear();
-    precomphess.clear();
-
-    mib.resize(2);
-    mib[0] = short_type(1);
-    mib[1] = target_dim();
-    mig.resize(3);
-    mig[0] = short_type(1);
-    mig[1] = target_dim(); mig[2] = dim();
-    mih.resize(4);
-    mih[0] = short_type(1);
-    mih[1] = target_dim(); mih[3] = mih[2] = dim();
+    if (precomps) {
+      for (const auto &cv_precomps : *precomps)
+        for (const auto &keyval : cv_precomps)
+          dal::del_dependency(precomps, keyval.first);
+      precomps->clear();
+    } else {
+      precomps = std::make_shared<precomp_pool>();
+      dal::pstatic_stored_object_key pkey
+        = std::make_shared<precomp_pool_key>(precomps);
+      dal::add_stored_object(pkey, precomps);
+    }
 
     size_type nb_total_dof(functions.size());
     base_node bmin(dim()), bmax(dim());
@@ -93,7 +91,7 @@ namespace getfem {
     scalar_type EPS=1E-13;
     size_type max_dof(0);
     index_of_global_dof_.clear();
-    index_of_global_dof_.resize(m.convex_index().last_true()+1);
+    index_of_global_dof_.resize(m.nb_allocated_convex());
     for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
       GMM_ASSERT1(dim_ == m.structure_of_convex(cv)->dim(),
                   "Convexes of different dimension: to be done");
@@ -185,25 +183,33 @@ namespace getfem {
     assert(target_dim() == 1);
     size_type cv = c.convex_num();
     size_type nbdof = nb_dof(cv);
-    mib[0] = short_type(nbdof);
-    t.adjust_sizes(mib);
+    t.adjust_sizes(nbdof, target_dim());
     if (c.have_pfp() && c.ii() != size_type(-1)) {
-      if (precompval.size() == 0)
-        precompval.resize(m.convex_index().last_true()+1);
+      GMM_ASSERT1(precomps, "Internal error");
+      if (precomps->size() == 0)
+        precomps->resize(m.nb_allocated_convex());
+      GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(), "Internal error");
       const bgeot::pstored_point_tab ptab = c.pfp()->get_ppoint_tab();
-      auto it = precompval[cv].find(ptab);
-      if (it == precompval[cv].end()) {
-        it = precompval[cv]
-             .emplace(ptab, std::vector<base_tensor>(ptab->size())).first;
+      auto it = (*precomps)[cv].find(ptab);
+      if (it == (*precomps)[cv].end()) {
+        it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
+        dal::add_dependency(precomps, ptab);
+        // we could have added the dependency to this->shared_from_this()
+        // instead, but there is a risk that this will shadow the same
+        // dependency through a different path, so that it becomes dangerous
+        // to delete the dependency later
+      }
+      if (it->second.val.size() == 0) {
+        it->second.val.resize(ptab->size());
         base_matrix G;
         bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
         for (size_type k = 0; k < ptab->size(); ++k) {
           const fem_interpolation_context
             ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
-          real_base_value(ctx, it->second[k]);
+          real_base_value(ctx, it->second.val[k]);
         }
       }
-      gmm::copy(it->second[c.ii()].as_vector(), t.as_vector());
+      gmm::copy(it->second.val[c.ii()].as_vector(), t.as_vector());
     } else
       for (size_type i=0; i < nbdof; ++i) {
         /*cerr << "fem_global_function: real_base_value(" << c.xreal() << ")\n";
@@ -218,25 +224,29 @@ namespace getfem {
     assert(target_dim() == 1);
     size_type cv = c.convex_num();
     size_type nbdof = nb_dof(cv);
-    mig[0] = short_type(nbdof);
-    t.adjust_sizes(mig);
+    t.adjust_sizes(nbdof, target_dim(), dim());
     if (c.have_pfp() && c.ii() != size_type(-1)) {
-      if (precompgrad.size() == 0)
-        precompgrad.resize(m.convex_index().last_true()+1);
+      GMM_ASSERT1(precomps, "Internal error");
+      if (precomps->size() == 0)
+        precomps->resize(m.nb_allocated_convex());
+      GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(), "Internal error");
       const bgeot::pstored_point_tab ptab = c.pfp()->get_ppoint_tab();
-      auto it = precompgrad[cv].find(ptab);
-      if (it == precompgrad[cv].end()) {
-        it = precompgrad[cv]
-             .emplace(ptab, std::vector<base_tensor>(ptab->size())).first;
+      auto it = (*precomps)[cv].find(ptab);
+      if (it == (*precomps)[cv].end()) {
+        it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
+        dal::add_dependency(precomps, ptab);
+      }
+      if (it->second.grad.size() == 0) {
+        it->second.grad.resize(ptab->size());
         base_matrix G;
         bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
         for (size_type k = 0; k < ptab->size(); ++k) {
           const fem_interpolation_context
             ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
-          real_grad_base_value(ctx, it->second[k]);
+          real_grad_base_value(ctx, it->second.grad[k]);
         }
       }
-      gmm::copy(it->second[c.ii()].as_vector(), t.as_vector());
+      gmm::copy(it->second.grad[c.ii()].as_vector(), t.as_vector());
     } else {
       base_small_vector G(dim());
       for (size_type i=0; i < nbdof; ++i) {
@@ -252,25 +262,29 @@ namespace getfem {
     assert(target_dim() == 1);
     size_type cv = c.convex_num();
     size_type nbdof = nb_dof(cv);
-    mih[0] = short_type(nbdof);
-    t.adjust_sizes(mih);
+    t.adjust_sizes(nbdof, target_dim(), gmm::sqr(dim()));
     if (c.have_pfp() && c.ii() != size_type(-1)) {
-      if (precomphess.size() == 0)
-        precomphess.resize(m.convex_index().last_true()+1);
+      GMM_ASSERT1(precomps, "Internal error");
+      if (precomps->size() == 0)
+        precomps->resize(m.nb_allocated_convex());
+      GMM_ASSERT1(precomps->size() == m.nb_allocated_convex(), "Internal error");
       const bgeot::pstored_point_tab ptab = c.pfp()->get_ppoint_tab();
-      auto it = precomphess[cv].find(ptab);
-      if (it == precomphess[cv].end()) {
-        it = precomphess[cv]
-             .emplace(ptab, std::vector<base_tensor>(ptab->size())).first;
+      auto it = (*precomps)[cv].find(ptab);
+      if (it == (*precomps)[cv].end()) {
+        it = (*precomps)[cv].emplace(ptab, precomp_data()).first;
+        dal::add_dependency(precomps, ptab);
+      }
+      if (it->second.hess.size() == 0) {
+        it->second.hess.resize(ptab->size());
         base_matrix G;
         bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
         for (size_type k = 0; k < ptab->size(); ++k) {
           const fem_interpolation_context
             ctx(m.trans_of_convex(cv), shared_from_this(), (*ptab)[k], G, cv);
-          real_hess_base_value(ctx, it->second[k]);
+          real_hess_base_value(ctx, it->second.hess[k]);
         }
       }
-      gmm::copy(it->second[c.ii()].as_vector(), t.as_vector());
+      gmm::copy(it->second.hess[c.ii()].as_vector(), t.as_vector());
     } else {
       base_matrix H(dim(),dim());
       for (size_type i=0; i < nbdof; ++i) {
diff --git a/src/getfem_fem_level_set.cc b/src/getfem_fem_level_set.cc
index 581135f..f04a315 100644
--- a/src/getfem_fem_level_set.cc
+++ b/src/getfem_fem_level_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -29,7 +29,7 @@ namespace getfem {
     cvr = bfem->ref_convex(0);
     dim_ = cvr->structure()->dim();
     is_equiv = true; real_element_defined = true;
-    is_polycomp = is_pol = is_lag = false;
+    is_polycomp = is_pol = is_lag = is_standard_fem = false;
     es_degree = 5; /* humm ... */
     ntarget_dim = bfem->target_dim();
 
@@ -201,10 +201,7 @@ namespace getfem {
   
   void fem_level_set::real_hess_base_value(const fem_interpolation_context &c,
                                            base_tensor &t, bool) const {
-    // bgeot::multi_index mi(4);
-    // mi[3] = mi[2] = short_type(c.N()); mi[1] = target_dim();
-    // mi[0] = short_type(nb_base(0));
-    t.adjust_sizes(nb_base(0), target_dim(), c.N(), c.N());
+    t.adjust_sizes(nb_base(0), target_dim(), gmm::sqr(c.N()));
     fem_interpolation_context c0 = c;
     if (c0.have_pfp())
       c0.set_pfp(fem_precomp(bfem, c0.pfp()->get_ppoint_tab(), c0.pfp()));
@@ -217,17 +214,15 @@ namespace getfem {
     std::vector<bool> zid;
     find_zone_id(c, zid, c.xfem_side());
 
-    for (dim_type i = 0; i < c.N() ; ++i) {
-      for (dim_type j = 0; j < c.N() ; ++j) {
-	for (dim_type q = 0; q < target_dim(); ++q) {
-	  unsigned cnt = 0;
-	  for (size_type d = 0; d < bfem->nb_dof(0); ++d, ++itf) {
-	    if (dofzones[d]) { /* enriched dof ? */
-	      for (size_type k = 0; k < dofzones[d]->size(); ++k, ++cnt)
-		*it++ = zid[cnt] ? *itf : 0;
-	    } else *it++ = *itf;
-	  }
-	}
+    dim_type NNdim = dim_type(gmm::sqr(c.N())*target_dim());
+    for (dim_type ijq = 0; ijq < NNdim ; ++ijq) {
+      unsigned cnt = 0;
+      for (size_type d = 0; d < bfem->nb_dof(0); ++d, ++itf) {
+        if (dofzones[d]) /* enriched dof ? */
+          for (size_type k = 0; k < dofzones[d]->size(); ++k, ++cnt)
+            *it++ = zid[cnt] ? *itf : 0;
+        else
+          *it++ = *itf;
       }
     }
     assert(it == t.end());
diff --git a/src/getfem_fourth_order.cc b/src/getfem_fourth_order.cc
index 1032d95..aed677b 100644
--- a/src/getfem_fourth_order.cc
+++ b/src/getfem_fourth_order.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard
+ Copyright (C) 2009-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -240,7 +240,7 @@ namespace getfem {
       set_flags("Normal derivative source term", true /* is linear*/,
 		true /* is symmetric */, true /* is coercive */,
 		true /* is real */, true /* is complex */,
-		false /* compute each time */, false /* has a Neumann term */);
+		false /* compute each time */);
     }
 
 
@@ -323,7 +323,7 @@ namespace getfem {
       set_flags("Kirchhoff Love Neumann term", true /* is linear*/,
 		true /* is symmetric */, true /* is coercive */,
 		true /* is real */, false /* is complex */,
-		false /* compute each time */, false /* has a Neumann term */);
+		false /* compute each time */);
     }
 
 
@@ -470,9 +470,11 @@ namespace getfem {
 	      asm_source_term(*R, mim, mf_mult, *mf_data, *A, rg);
 	  }
 	  else {
-	    asm_real_or_complex_1_param
-	      (*R, mim, mf_mult, *mf_data, *A, rg,
-	       "R=data(#2); V(#1)+=comp(Base(#1).Grad(#2).Normal())(:,i,j,j).R(i)");
+	    asm_real_or_complex_1_param_vec
+	      (*R, mim, mf_mult, mf_data, *A, rg, "(Grad_A.Normal)*Test_u");
+	    // asm_real_or_complex_1_param
+	    //   (*R, mim, mf_mult, *mf_data, *A, rg,
+	    //    "R=data(#2); V(#1)+=comp(Base(#1).Grad(#2).Normal())(:,i,j,j).R(i)");
 	  }
 	} else {
 	  GMM_ASSERT1(!R_must_be_derivated, "Incoherent situation");
@@ -580,9 +582,11 @@ namespace getfem {
 	      asm_source_term(*R, mim, mf_mult, *mf_data, *A, rg);
 	  }
 	  else {
-	    asm_real_or_complex_1_param
-	      (*R, mim, mf_mult, *mf_data, *A, rg,
-	       "R=data(#2); V(#1)+=comp(Base(#1).Grad(#2).Normal())(:,i,j,j).R(i)");
+	    asm_real_or_complex_1_param_vec
+	      (*R, mim, mf_mult, mf_data, *A, rg, "(Grad_A.Normal)*Test_u");
+	    // asm_real_or_complex_1_param
+	    //   (*R, mim, mf_mult, *mf_data, *A, rg,
+	    //    "R=data(#2); V(#1)+=comp(Base(#1).Grad(#2).Normal())(:,i,j,j).R(i)");
 	  }
 	} else {
 	  GMM_ASSERT1(!R_must_be_derivated, "Incoherent situation");
@@ -608,7 +612,7 @@ namespace getfem {
 		true /* is linear*/,
 		true /* is symmetric */, penalized /* is coercive */,
 		true /* is real */, true /* is complex */,
-		false /* compute each time */, false /* has a Neumann term */);
+		false /* compute each time */);
     }
   };
 
diff --git a/src/getfem_generic_assembly.cc b/src/getfem_generic_assembly.cc
index bcfcf6f..99dd345 100644
--- a/src/getfem_generic_assembly.cc
+++ b/src/getfem_generic_assembly.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2013-2016 Yves Renard
+ Copyright (C) 2013-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -19,8 +19,8 @@
 
 ===========================================================================*/
 
-
 #include "getfem/getfem_generic_assembly.h"
+#include "getfem/getfem_models.h"
 #include "gmm/gmm_blas.h"
 #include <iomanip>
 #include "getfem/getfem_omp.h"
@@ -48,10 +48,11 @@ BoostMathFunction const erfc = boost::math::erfc<double>;
 #endif
 
 
-// #define GA_USES_BLAS // not so interesting, at leat for debian blas
+// #define GA_USES_BLAS // not so interesting, at least for debian blas
 
 // #define GA_DEBUG_INFO(a) { cout << a << endl; }
 #define GA_DEBUG_INFO(a)
+
 #define GA_DEBUG_ASSERT(a, b) GMM_ASSERT1(a, b)
 // #define GA_DEBUG_ASSERT(a, b)
 
@@ -61,7 +62,7 @@ BoostMathFunction const erfc = boost::math::erfc<double>;
 #  define GA_TOCTIC(a)
 #else
 #  define GA_TIC scalar_type _ga_time_ = gmm::uclock_sec();
-#  define GA_TOC(a) { cout << (a) << " : " << gmm::uclock_sec() - _ga_time_ << endl; }
+#  define GA_TOC(a) { cout <<(a)<<" : "<<gmm::uclock_sec()-_ga_time_<< endl; }
 #  define GA_TOCTIC(a) { GA_TOC(a); _ga_time_ = gmm::uclock_sec(); }
 #endif
 
@@ -71,6 +72,12 @@ namespace getfem {
   extern bool predef_operators_plasticity_initialized;
   extern bool predef_operators_contact_initialized;
 
+  base_matrix& __mat_aux1()
+  {
+    DEFINE_STATIC_THREAD_LOCAL(base_matrix, m);
+    return m;
+  }
+
   //=========================================================================
   // Lexical analysis for the generic assembly language
   //=========================================================================
@@ -117,7 +124,7 @@ namespace getfem {
   static int ga_operator_priorities[GA_NB_TOKEN_TYPE];
 
   // Initialize ga_char_type and ga_operator_priorities arrays
-  static bool init_ga_char_type(void) {
+  static bool init_ga_char_type() {
     for (int i = 0; i < 256; ++i) ga_char_type[i] = GA_INVALID;
     ga_char_type['+'] = GA_PLUS;        ga_char_type['-'] = GA_MINUS;
     ga_char_type['*'] = GA_MULT;        ga_char_type['/'] = GA_DIV;
@@ -356,12 +363,92 @@ namespace getfem {
     GA_NODE_XFEM_MINUS_DIVERG_TEST,
     GA_NODE_ZERO};
 
+  struct assembly_tensor {
+    bool is_copied;
+    int sparsity_; // 0: plain, 1: vectorized base, 2: vectorised grad, ...
+    size_type qdim_; // Dimension of the vectorization for sparsityy tensors
+    base_tensor t;
+    assembly_tensor *tensor_copied;
+
+    const base_tensor &org_tensor() const
+    { return is_copied ? tensor_copied->org_tensor() : t; }
+    base_tensor &org_tensor()
+    { return is_copied ? tensor_copied->org_tensor() : t; }
+    
+    const base_tensor &tensor() const
+    { return (is_copied ? tensor_copied->tensor() : t); }
+    
+    base_tensor &tensor()
+    { return (is_copied ? tensor_copied->tensor() : t); }
+
+    void set_sparsity(int sp, size_type q)
+    { sparsity_ = sp; qdim_ = q; }
+
+    size_type qdim() { return is_copied ? tensor_copied->qdim() : qdim_; }
+
+    int sparsity() const
+    { return is_copied ? tensor_copied->sparsity() : sparsity_; }
+
+    inline void set_to_original() { is_copied = false; }
+    inline void set_to_copy(assembly_tensor &t_) {
+      is_copied = true; sparsity_ = t_.sparsity_; qdim_ = t_.qdim_;
+      t = t_.org_tensor(); tensor_copied = &(t_);
+    }
+    
+    inline void adjust_sizes(const bgeot::multi_index &ssizes)
+    { t.adjust_sizes(ssizes); }
+
+    inline void adjust_sizes()
+    { if (t.sizes().size() || t.size() != 1) t.init(); }
+    
+    inline void adjust_sizes(size_type i)
+    { if (t.sizes().size() != 1 || t.sizes()[0] != i) t.init(i); }
+
+    inline void adjust_sizes(size_type i, size_type j) {
+      if (t.sizes().size() != 2 || t.sizes()[0] != i || t.sizes()[1] != j)
+	t.init(i, j);
+    }
+    
+    inline void adjust_sizes(size_type i, size_type j, size_type k) {
+      if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
+          || t.sizes()[2] != k)
+        t.init(i, j, k);
+    }
+    inline void adjust_sizes(size_type i, size_type j,
+			     size_type k, size_type l) {
+      if (t.sizes().size() != 3 || t.sizes()[0] != i || t.sizes()[1] != j
+          || t.sizes()[2] != k || t.sizes()[3] != l)
+       t.init(i, j, k, l);
+    }
+
+    void init_scalar_tensor(scalar_type v)
+    { set_to_original(); t.adjust_sizes(); t[0] = v; }
+
+    void init_vector_tensor(size_type d)
+    { set_to_original(); t.adjust_sizes(d); }
+
+    void init_matrix_tensor(size_type n, size_type m)
+    { set_to_original(); t.adjust_sizes(n, m); }
+
+    void init_third_order_tensor(size_type n, size_type m,  size_type l)
+    { set_to_original(); t.adjust_sizes(n, m, l); }
+
+    void init_fourth_order_tensor(size_type n, size_type m,
+                                  size_type l, size_type k)
+    { set_to_original(); t.adjust_sizes(n, m, l, k); }
+    
+    const bgeot::multi_index &sizes() const { return t.sizes(); }
+
+    assembly_tensor() : is_copied(false), sparsity_(0), tensor_copied(0) {}
+  };
+
   struct ga_tree_node;
   typedef ga_tree_node *pga_tree_node;
 
   struct ga_tree_node {
     GA_NODE_TYPE node_type;
-    base_tensor t;
+    GA_TOKEN_TYPE op_type;
+    assembly_tensor t;
     size_type test_function_type; // -1 = undetermined
                                   // 0 = no test function,
                                   // 1 = first order, 2 = second order,
@@ -381,28 +468,31 @@ namespace getfem {
                                   // name of transformation
     size_type der1, der2;         // For functions and nonlinear operators,
                                   // optional derivative or second derivative.
-    GA_TOKEN_TYPE op_type;
     bool symmetric_op;
     pga_tree_node parent;         // Parent node
     std::vector<pga_tree_node> children; // Children nodes
     scalar_type hash_value;       // Hash value to identify nodes.
     bool marked;                  // For specific use of some algorithms
 
-    inline size_type nb_test_functions(void) const {
+    inline const base_tensor &tensor() const { return t.tensor(); }
+    inline base_tensor &tensor() { return t.tensor(); }
+    int sparsity() const { return t.sparsity(); }
+    
+    inline size_type nb_test_functions() const {
       if (test_function_type == size_type(-1)) return 0;
       return test_function_type  - (test_function_type >= 2 ? 1 : 0);
     }
 
-    inline size_type tensor_order(void) const
+    inline size_type tensor_order() const
     { return t.sizes().size() - nb_test_functions(); }
 
-    inline size_type tensor_test_size(void) const {
+    inline size_type tensor_test_size() const {
       size_type st = nb_test_functions();
       return (st >= 1 ? t.sizes()[0] : 1) * (st == 2 ? t.sizes()[1] : 1);
     }
 
-    inline size_type tensor_proper_size(void) const
-    { return t.size() / tensor_test_size(); }
+    inline size_type tensor_proper_size() const
+    { return t.org_tensor().size() / tensor_test_size(); }
 
     inline size_type tensor_proper_size(size_type i) const
     { return t.sizes()[nb_test_functions()+i]; }
@@ -413,7 +503,8 @@ namespace getfem {
       size_type test0 = n0->test_function_type, test1 = n1->test_function_type;
       if (test0 && test1 && (test0 == test1 ||
                              test0 >= 3 || test1 >= 3))
-        ga_throw_error(expr, pos, "Incompatibility of test functions in product.");
+        ga_throw_error(expr, pos,
+		       "Incompatibility of test functions in product.");
       GMM_ASSERT1(test0 != size_type(-1) && test1 != size_type(-1),
                   "internal error");
 
@@ -451,37 +542,34 @@ namespace getfem {
       t.adjust_sizes(mi);
     }
 
-    bool tensor_is_zero(void) {
+    bool tensor_is_zero() {
       if (node_type == GA_NODE_ZERO) return true;
       if (node_type != GA_NODE_CONSTANT) return false;
-      for (size_type i = 0; i < t.size(); ++i)
-        if (t[i] != scalar_type(0)) return false;
+      for (size_type i = 0; i < tensor().size(); ++i)
+        if (tensor()[i] != scalar_type(0)) return false;
       return true;
     }
 
-    void init_scalar_tensor(scalar_type v)
-    { t.adjust_sizes(); t[0] = v; test_function_type = 0; }
+    inline void init_scalar_tensor(scalar_type v)
+    { t.init_scalar_tensor(v); test_function_type = 0; }
 
-    void init_vector_tensor(size_type d)
-    { t.adjust_sizes(d); test_function_type = 0; }
+    inline void init_vector_tensor(size_type d)
+    { t.init_vector_tensor(d); test_function_type = 0; }
 
-    void init_matrix_tensor(size_type n, size_type m)
-    { t.adjust_sizes(n, m); test_function_type = 0; }
+    inline void init_matrix_tensor(size_type n, size_type m)
+    { t.init_matrix_tensor(n, m); test_function_type = 0; }
 
-    void init_third_order_tensor(size_type n, size_type m,  size_type l) {
-      t.adjust_sizes(bgeot::multi_index(n,m,l));
-      test_function_type = 0;
-    }
-    void init_fourth_order_tensor(size_type n, size_type m,
-                                  size_type l, size_type k) {
-      t.adjust_sizes(bgeot::multi_index(n,m,l,k));
-      test_function_type = 0;
-    }
+    inline void init_third_order_tensor(size_type n, size_type m,  size_type l)
+    { t.init_third_order_tensor(n, m, l); test_function_type = 0; }
+
+    inline void init_fourth_order_tensor(size_type n, size_type m,
+					 size_type l, size_type k)
+    { t.init_fourth_order_tensor(n, m, l, k); test_function_type = 0; }
 
     ga_tree_node()
-      : node_type(GA_NODE_VOID), test_function_type(-1),
-        qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
-        pos(0), der1(0), der2(0), symmetric_op(false), hash_value(0) {}
+      : node_type(GA_NODE_VOID), test_function_type(-1), qdim1(0), qdim2(0),
+	nbc1(0), nbc2(0), nbc3(0), pos(0), der1(0), der2(0),
+	symmetric_op(false), hash_value(0) {}
     ga_tree_node(GA_NODE_TYPE ty, size_type p)
       : node_type(ty), test_function_type(-1),
         qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
@@ -498,11 +586,10 @@ namespace getfem {
         pos(p), name(n, l), der1(0), der2(0), symmetric_op(false),
         hash_value(0) {}
     ga_tree_node(GA_TOKEN_TYPE op, size_type p)
-      : node_type(GA_NODE_OP), test_function_type(-1),
+      : node_type(GA_NODE_OP), op_type(op), test_function_type(-1),
         qdim1(0), qdim2(0), nbc1(0), nbc2(0), nbc3(0),
-        pos(p), der1(0), der2(0), op_type(op), symmetric_op(false),
+        pos(p), der1(0), der2(0), symmetric_op(false),
         hash_value(0) {}
-
   };
 
   struct ga_tree {
@@ -557,9 +644,10 @@ namespace getfem {
     }
 
     void add_sub_tree(ga_tree &sub_tree) {
-      if (current_node && (current_node->node_type == GA_NODE_PARAMS ||
-                           current_node->node_type == GA_NODE_INTERPOLATE_FILTER ||
-                           current_node->node_type == GA_NODE_C_MATRIX)) {
+      if (current_node &&
+	  (current_node->node_type == GA_NODE_PARAMS ||
+	   current_node->node_type == GA_NODE_INTERPOLATE_FILTER ||
+	   current_node->node_type == GA_NODE_C_MATRIX)) {
         GMM_ASSERT1(sub_tree.root, "Invalid tree operation");
         current_node->children.push_back(sub_tree.root);
         sub_tree.root->parent = current_node;
@@ -698,7 +786,8 @@ namespace getfem {
     }
 
     void clear() {
-      if (root) clear_node_rec(root); root = current_node = 0;
+      if (root) clear_node_rec(root);
+      root = current_node = 0;
     }
 
     void clear_children(pga_tree_node pnode) {
@@ -796,9 +885,9 @@ namespace getfem {
   // version = 0 : strict equality
   //           1 : give the same result
   //           2 : give the same result with transposition of test functions
-  static bool sub_tree_are_equal(const pga_tree_node pnode1, const pga_tree_node pnode2,
-                                 const ga_workspace &workspace,
-                                 int version) {
+  static bool sub_tree_are_equal
+  (const pga_tree_node pnode1, const pga_tree_node pnode2,
+   const ga_workspace &workspace, int version) {
     size_type ntype1 = pnode1->node_type;
     if (ntype1 == GA_NODE_ZERO) ntype1 = GA_NODE_CONSTANT;
     size_type ntype2 = pnode2->node_type;
@@ -819,7 +908,7 @@ namespace getfem {
       if (pnode1->name.compare(pnode2->name)) return false;
       break;
     case GA_NODE_CONSTANT: case GA_NODE_ZERO:
-      if (pnode1->t.size() != pnode2->t.size()) return false;
+      if (pnode1->tensor().size() != pnode2->tensor().size()) return false;
 
       switch(version) {
       case 0: case 1:
@@ -846,12 +935,13 @@ namespace getfem {
           return false;
         break;
       }
-      if (pnode1->t.size() != 1 &&
+      if (pnode1->tensor().size() != 1 &&
           pnode1->t.sizes().size() != pnode2->t.sizes().size()) return false;
       for (size_type i = 0; i < pnode1->t.sizes().size(); ++i)
         if (pnode1->t.sizes()[i] != pnode2->t.sizes()[i]) return false;
-      for (size_type i = 0; i < pnode1->t.size(); ++i)
-        if (gmm::abs(pnode1->t[i] - pnode2->t[i]) > 1E-25) return false;
+      for (size_type i = 0; i < pnode1->tensor().size(); ++i)
+        if (gmm::abs(pnode1->tensor()[i] - pnode2->tensor()[i]) > 1E-25)
+	  return false;
       break;
     case GA_NODE_C_MATRIX:
       if (pnode1->nbc1 != pnode2->nbc1 || pnode1->nbc2 != pnode2->nbc2 ||
@@ -954,7 +1044,8 @@ namespace getfem {
     return true;
   }
 
-  static void verify_tree(const pga_tree_node pnode, const pga_tree_node parent) {
+  static void verify_tree(const pga_tree_node pnode,
+			  const pga_tree_node parent) {
     GMM_ASSERT1(pnode->parent == parent,
                 "Invalid tree node " << pnode->node_type);
     for (size_type i = 0; i < pnode->children.size(); ++i)
@@ -977,14 +1068,14 @@ namespace getfem {
     size_type nt = pnode->nb_test_functions(); // for printing zero tensors
     switch (pnode->tensor_order()) {
     case 0:
-      str << (nt ? scalar_type(0) : pnode->t[0]);
+      str << (nt ? scalar_type(0) : pnode->tensor()[0]);
       break;
 
     case 1:
       str << "[";
       for (size_type i = 0; i < pnode->tensor_proper_size(0); ++i) {
         if (i != 0) str << "; ";
-        str << (nt ? scalar_type(0) : pnode->t[i]);
+        str << (nt ? scalar_type(0) : pnode->tensor()[i]);
       }
       str << "]";
       break;
@@ -994,8 +1085,10 @@ namespace getfem {
         size_type ii(0);
         size_type n0 = pnode->tensor_proper_size(0);
         size_type n1 = pnode->tensor_proper_size(1);
-        size_type n2 = (pnode->tensor_order() > 2) ? pnode->tensor_proper_size(2) : 1;
-        size_type n3 = (pnode->tensor_order() > 3) ? pnode->tensor_proper_size(3) : 1;
+        size_type n2 = ((pnode->tensor_order() > 2) ?
+			pnode->tensor_proper_size(2) : 1);
+        size_type n3 = ((pnode->tensor_order() > 3) ?
+			pnode->tensor_proper_size(3) : 1);
         if (n3 > 1) str << "[";
         for (size_type l = 0; l < n3; ++l) {
           if (l != 0) str << ",";
@@ -1008,7 +1101,7 @@ namespace getfem {
               if (n0 > 1) str << "[";
               for (size_type i = 0; i < n0; ++i) {
                 if (i != 0) str << ",";
-                str << (nt ? scalar_type(0) : pnode->t[ii++]);
+                str << (nt ? scalar_type(0) : pnode->tensor()[ii++]);
               }
               if (n0 > 1) str << "]";
             }
@@ -1024,7 +1117,7 @@ namespace getfem {
       str << "Reshape([";
       for (size_type i = 0; i < pnode->tensor_proper_size(); ++i) {
         if (i != 0) str << "; ";
-        str << (nt ? scalar_type(0) : pnode->t[i]);
+        str << (nt ? scalar_type(0) : pnode->tensor()[i]);
       }
       str << "]";
       for (size_type i = 0; i < pnode->tensor_order(); ++i) {
@@ -1662,24 +1755,28 @@ namespace getfem {
               r_type = ga_read_term(expr, pos, sub_tree);
 
               if (sub_tree.root->node_type == GA_NODE_C_MATRIX) {
-
                 // nested format
-
-                if (r_type != GA_COMMA && r_type != GA_RBRACKET)  // in the nested format only "," and "]" are expected
+                if (r_type != GA_COMMA && r_type != GA_RBRACKET)
+		  // in the nested format only "," and "]" are expected
                   ga_throw_error(expr, pos-1, "Bad explicit "
                                  "vector/matrix/tensor format.")
-                else if (sub_tree.root->nbc3 != 1)                // the sub-tensor to be merged cannot be of fourth order
+                else if (sub_tree.root->nbc3 != 1)
+		  // the sub-tensor to be merged cannot be of fourth order
                   ga_throw_error(expr, pos-1, "Definition of explicit "
                                  "tensors is limitted to the fourth order. "
                                  "Limit exceeded.")
-                else if (foundsemi ||                             // Cannot mix with the non-nested format.
-                         (sub_tree.root->children.size() > 1 &&   // The sub-tensor cannot be a column vector [a;b],
-                          sub_tree.root->nbc1 == 1))              // the nested format only accepts row vectors [a,b]
-                  ga_throw_error(expr, pos-1, "Bad explicit "     // and converts them to column vectors internally
+                else if (foundsemi || // Cannot mix with the non-nested format.
+                         (sub_tree.root->children.size() > 1 &&
+			  // The sub-tensor cannot be a column vector [a;b],
+                          sub_tree.root->nbc1 == 1))
+		  // the nested format only accepts row vectors [a,b]
+		  // and converts them to column vectors internally
+                  ga_throw_error(expr, pos-1, "Bad explicit "
                                  "vector/matrix/tensor format.")  // (see below)
 
+		// convert a row vector [a,b] to a column vector [a;b]
                 if (sub_tree.root->children.size() == sub_tree.root->nbc1)
-                  sub_tree.root->nbc1 = 1; // convert a row vector [a,b] to a column vector [a;b]
+                  sub_tree.root->nbc1 = 1;
 
                 nested_format = true;
 
@@ -1862,7 +1959,7 @@ namespace getfem {
   class ga_if_hierarchy : public std::vector<size_type> {
 
   public:
-    void increment(void) { (back())++; }
+    void increment() { (back())++; }
     void child_of(const ga_if_hierarchy &gih)
     { *this = gih; push_back(0); }
     bool is_compatible(const std::list<ga_if_hierarchy> &gihl) {
@@ -1880,7 +1977,7 @@ namespace getfem {
       return false;
     }
 
-    ga_if_hierarchy(void) : std::vector<size_type>(1) { (*this)[0] = 0; }
+    ga_if_hierarchy() : std::vector<size_type>(1) { (*this)[0] = 0; }
   };
 
 
@@ -1976,34 +2073,33 @@ namespace getfem {
       const mesh *m;
       ga_if_hierarchy current_hierarchy;
       std::map<std::string, base_vector> local_dofs;
-      std::map<std::string, std::list<ga_if_hierarchy> > local_dofs_hierarchy;
       std::map<const mesh_fem *, pfem_precomp> pfps;
-      std::map<const mesh_fem *, std::list<ga_if_hierarchy> > pfps_hierarchy;
       std::map<const mesh_fem *, base_tensor> base;
-      std::map<const mesh_fem *, std::list<ga_if_hierarchy> > base_hierarchy;
+      std::map<const mesh_fem *, std::list<ga_if_hierarchy>> base_hierarchy;
       std::map<const mesh_fem *, base_tensor> grad;
-      std::map<const mesh_fem *, std::list<ga_if_hierarchy> > grad_hierarchy;
+      std::map<const mesh_fem *, std::list<ga_if_hierarchy>> grad_hierarchy;
       std::map<const mesh_fem *, base_tensor> hess;
-      std::map<const mesh_fem *, std::list<ga_if_hierarchy> > hess_hierarchy;
-
-      std::map<const mesh_fem *, base_tensor> xfem_plus_base;
-      std::map<const mesh_fem *, std::list<ga_if_hierarchy> > xfem_plus_base_hierarchy;
-      std::map<const mesh_fem *, base_tensor> xfem_plus_grad;
-      std::map<const mesh_fem *, std::list<ga_if_hierarchy> > xfem_plus_grad_hierarchy;
-      std::map<const mesh_fem *, base_tensor> xfem_plus_hess;
-      std::map<const mesh_fem *, std::list<ga_if_hierarchy> > xfem_plus_hess_hierarchy;
-      std::map<const mesh_fem *, base_tensor> xfem_minus_base;
-      std::map<const mesh_fem *,std::list<ga_if_hierarchy> > xfem_minus_base_hierarchy;
-      std::map<const mesh_fem *, base_tensor> xfem_minus_grad;
-      std::map<const mesh_fem *,std::list<ga_if_hierarchy> > xfem_minus_grad_hierarchy;
-      std::map<const mesh_fem *, base_tensor> xfem_minus_hess;
-      std::map<const mesh_fem *,std::list<ga_if_hierarchy> > xfem_minus_hess_hierarchy;
-
-      std::map<std::string, std::set<std::string> > transformations;
+      std::map<const mesh_fem *, std::list<ga_if_hierarchy>> hess_hierarchy;
+
+      std::map<const mesh_fem *, base_tensor>
+        xfem_plus_base,  xfem_plus_grad,  xfem_plus_hess,
+	xfem_minus_base, xfem_minus_grad, xfem_minus_hess;
+      std::map<const mesh_fem *, std::list<ga_if_hierarchy>>
+	xfem_plus_base_hierarchy,  xfem_plus_grad_hierarchy,
+	xfem_plus_hess_hierarchy,  xfem_minus_base_hierarchy,
+	xfem_minus_grad_hierarchy, xfem_minus_hess_hierarchy;
+
+      std::map<std::string, std::set<std::string>> transformations;
       std::set<std::string> transformations_der;
       std::map<std::string, interpolate_info> interpolate_infos;
       std::map<std::string, elementary_trans_info> elementary_trans_infos;
 
+      // Instructions being executed at the first Gauss point after
+      // a change of integration method only.
+      ga_instruction_list begin_instructions;
+      // Instructions executed once per element
+      ga_instruction_list elt_instructions;
+      // Instructions executed on each integration/interpolation point
       ga_instruction_list instructions;
       std::map<scalar_type, std::list<pga_tree_node> > node_list;
 
@@ -2012,12 +2108,13 @@ namespace getfem {
 
     std::list<ga_tree> trees; // The trees are stored mainly because they
                               // contain the intermediary tensors.
+    std::list<ga_tree> interpolation_trees;
 
     typedef std::map<region_mim, region_mim_instructions> instructions_set;
 
     instructions_set  whole_instructions;
 
-    ga_instruction_set() { max_dof = nb_dof = 0; need_elt_size = false; }
+    ga_instruction_set() { max_dof = nb_dof = 0; need_elt_size = false; ipt=0; }
   };
 
 
@@ -2074,12 +2171,16 @@ namespace getfem {
     copyable_ptr<instruction_set> gis;
 
     friend void ga_define_function(const std::string &name, size_type nbargs,
-                                   const std::string &expr, const std::string &der1,
+                                   const std::string &expr,
+				   const std::string &der1,
                                    const std::string &der2);
-    friend void ga_define_function(const std::string &name, pscalar_func_onearg f,
+    friend void ga_define_function(const std::string &name,
+				   pscalar_func_onearg f,
                                    const std::string &der);
-    friend void ga_define_function(const std::string &name, pscalar_func_twoargs f,
-                                   const std::string &der1, const std::string &der2);
+    friend void ga_define_function(const std::string &name,
+				   pscalar_func_twoargs f,
+                                   const std::string &der1,
+				   const std::string &der2);
   public:
     scalar_type operator()(scalar_type t_, scalar_type u_ = 0.) const {
       switch(ftype_) {
@@ -2102,7 +2203,8 @@ namespace getfem {
     bool is_affine(const std::string &varname) const {
       if (ftype_ == 1) {
         for (size_type i = 0; i < workspace.thrd_cast().nb_trees(); ++i) {
-          const ga_workspace::tree_description &td = workspace.thrd_cast().tree_info(i);
+          const ga_workspace::tree_description &
+	    td = workspace.thrd_cast().tree_info(i);
           if (!(ga_is_affine(*(td.ptree), workspace, varname, "")))
             return false;
         }
@@ -2120,7 +2222,8 @@ namespace getfem {
     pscalar_func_onearg f1() const {return f1_;}
     pscalar_func_twoargs f2() const {return f2_;}
 
-    ga_predef_function() : expr_(""), derivative1_(""), derivative2_(""), gis(nullptr) {}
+    ga_predef_function() : expr_(""), derivative1_(""),
+			   derivative2_(""), gis(nullptr) {}
     ga_predef_function(pscalar_func_onearg f, size_type dtype__ = 0,
                        const std::string &der = "")
       : ftype_(0), dtype_(dtype__), nbargs_(1), f1_(f), expr_(""),
@@ -2309,54 +2412,64 @@ namespace getfem {
 
     void value(const arg_list &args, base_tensor &result) const {
       size_type N = args[0]->sizes()[0];
-      base_matrix M(N, N);
-      gmm::copy(args[0]->as_vector(), M.as_vector());
-      result[0] = gmm::lu_det(M);
-
+      // base_matrix M(N, N);
+      // gmm::copy(args[0]->as_vector(), M.as_vector());
+      // result[0] = gmm::lu_det(M);
+      result[0] = bgeot::lu_det(&(*(args[0]->begin())), N);
     }
 
     // Derivative : det(M)M^{-T}
     void derivative(const arg_list &args, size_type,
-                    base_tensor &result) const { // to be verified
+                    base_tensor &result) const {
       size_type N = args[0]->sizes()[0];
-      base_matrix M(N, N);
-      gmm::copy(args[0]->as_vector(), M.as_vector());
-      scalar_type det = gmm::lu_inverse(M);
-      if (det == scalar_type(0))
-        gmm::clear(result.as_vector());
-      else {
-        base_tensor::iterator it = result.begin();
-        for (size_type j = 0; j < N; ++j)
-          for (size_type i = 0; i < N; ++i, ++it)
-            *it = M(j, i) * det;
-        GA_DEBUG_ASSERT(it == result.end(), "Internal error");
+      if (N) {
+	__mat_aux1().base_resize(N, N);
+	gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
+	scalar_type det = bgeot::lu_inverse(__mat_aux1());
+	if (det == scalar_type(0))
+	  gmm::clear(result.as_vector());
+	else {
+	  auto it = result.begin();
+	  auto ita = __mat_aux1().begin();
+	  for (size_type j = 0; j < N; ++j, ++ita) {
+	    auto itaa = ita;
+	    *it = (*itaa) * det; ++it;
+	    for (size_type i = 1; i < N; ++i, ++it)
+	      { itaa += N; *it = (*itaa) * det; }
+	  }
+	  GA_DEBUG_ASSERT(it == result.end(), "Internal error");
+	}
       }
     }
 
     // Second derivative : det(M)(M^{-T}@M^{-T} - M^{-T}_{jk}M^{-T}_{li})
     void second_derivative(const arg_list &args, size_type, size_type,
-                           base_tensor &result) const { // To be verified
+                           base_tensor &result) const {
       size_type N = args[0]->sizes()[0];
-      base_matrix M(N, N);
-      gmm::copy(args[0]->as_vector(), M.as_vector());
-      scalar_type det = gmm::lu_inverse(M);
+      __mat_aux1().base_resize(N, N);
+      gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
+      scalar_type det = bgeot::lu_inverse(__mat_aux1());
       if (det == scalar_type(0))
         gmm::clear(result.as_vector());
       else {
-        base_tensor::iterator it = result.begin();
-        for (size_type l = 0; l < N; ++l)
-          for (size_type k = 0; k < N; ++k)
-            for (size_type j = 0; j < N; ++j)
-              for (size_type i = 0; i < N; ++i, ++it)
-                *it = (M(j, i) * M(l,k) - M(j,k) * M(l, i)) * det;
+        auto it = result.begin();
+	auto ita = __mat_aux1().begin(), ita_l = ita;
+        for (size_type l = 0; l < N; ++l, ++ita_l) {
+	  auto ita_lk = ita_l, ita_jk = ita;
+	  for (size_type k = 0; k < N; ++k, ita_lk += N, ita_jk += N) {
+	    auto ita_j = ita;
+            for (size_type j = 0; j < N; ++j, ++ita_j, ++ita_jk) {
+	      auto ita_ji = ita_j, ita_li = ita_l;
+              for (size_type i = 0; i < N; ++i, ++it, ita_ji += N, ita_li += N)
+                *it = ((*ita_ji) * (*ita_lk) - (*ita_jk) * (*ita_li)) * det;
+	    }
+	  }
+	}
         GA_DEBUG_ASSERT(it == result.end(), "Internal error");
       }
     }
   };
 
-
-
-
   // Inverse Operator (for square matrices)
   struct inverse_operator : public ga_nonlinear_operator {
     bool result_size(const arg_list &args, bgeot::multi_index &sizes) const {
@@ -2369,25 +2482,32 @@ namespace getfem {
     // Value : M^{-1}
     void value(const arg_list &args, base_tensor &result) const {
       size_type N = args[0]->sizes()[0];
-      base_matrix M(N, N);
-      gmm::copy(args[0]->as_vector(), M.as_vector());
-      gmm::lu_inverse(M);
-      gmm::copy(M.as_vector(), result.as_vector());
+      __mat_aux1().base_resize(N, N);
+      gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
+      bgeot::lu_inverse(__mat_aux1());
+      gmm::copy(__mat_aux1().as_vector(), result.as_vector());
     }
 
     // Derivative : -M^{-1}{ik}M^{-1}{lj}  (comes from H -> M^{-1}HM^{-1})
     void derivative(const arg_list &args, size_type,
                     base_tensor &result) const { // to be verified
       size_type N = args[0]->sizes()[0];
-      base_matrix M(N, N);
-      gmm::copy(args[0]->as_vector(), M.as_vector());
-      gmm::lu_inverse(M);
-      base_tensor::iterator it = result.begin();
-      for (size_type l = 0; l < N; ++l)
-        for (size_type k = 0; k < N; ++k)
-          for (size_type j = 0; j < N; ++j)
-            for (size_type i = 0; i < N; ++i, ++it)
-              *it = -M(i,k)*M(l,j);
+      __mat_aux1().base_resize(N, N);
+      gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
+      bgeot::lu_inverse(__mat_aux1());
+      auto it = result.begin();
+      auto ita = __mat_aux1().begin(), ita_l = ita;
+      for (size_type l = 0; l < N; ++l, ++ita_l) {
+	auto ita_k = ita;
+        for (size_type k = 0; k < N; ++k, ita_k += N) {
+	  auto ita_lj = ita_l;
+          for (size_type j = 0; j < N; ++j, ++ita_lj) {
+	    auto ita_ik = ita_k;
+            for (size_type i = 0; i < N; ++i, ++it, ++ita_ik)
+              *it = -(*ita_ik) * (*ita_lj);
+	  }
+	}
+      }
       GA_DEBUG_ASSERT(it == result.end(), "Internal error");
     }
 
@@ -2397,9 +2517,9 @@ namespace getfem {
     void second_derivative(const arg_list &args, size_type, size_type,
                            base_tensor &result) const { // to be verified
       size_type N = args[0]->sizes()[0];
-      base_matrix M(N, N);
-      gmm::copy(args[0]->as_vector(), M.as_vector());
-      gmm::lu_inverse(M);
+      __mat_aux1().base_resize(N, N);
+      gmm::copy(args[0]->as_vector(), __mat_aux1().as_vector());
+      bgeot::lu_inverse(__mat_aux1());
       base_tensor::iterator it = result.begin();
       for (size_type n = 0; n < N; ++n)
         for (size_type m = 0; m < N; ++m)
@@ -2407,20 +2527,18 @@ namespace getfem {
             for (size_type k = 0; k < N; ++k)
               for (size_type j = 0; j < N; ++j)
                 for (size_type i = 0; i < N; ++i, ++it)
-                  *it = M(i,k)*M(l,m)*M(n,j)+M(i,m)*M(m,k)*M(l,j);
+                  *it = __mat_aux1()(i,k)*__mat_aux1()(l,m)*__mat_aux1()(n,j)
+		    + __mat_aux1()(i,m)*__mat_aux1()(m,k)*__mat_aux1()(l,j);
       GA_DEBUG_ASSERT(it == result.end(), "Internal error");
     }
   };
 
-
-
-
   //=========================================================================
   // Initialization of predefined functions and operators.
   //=========================================================================
 
 
-  bool init_predef_functions(void) {
+  bool init_predef_functions() {
 
     // Predefined functions
     ga_predef_function_tab &PREDEF_FUNCTIONS
@@ -2477,12 +2595,12 @@ namespace getfem {
     PREDEF_FUNCTIONS["asin"] = ga_predef_function(asin, 1, "DER_PDFUNC_ASIN");
     PREDEF_FUNCTIONS["acos"] = ga_predef_function(acos, 1, "DER_PDFUNC_ACOS");
     PREDEF_FUNCTIONS["atan"] = ga_predef_function(atan, 1, "DER_PDFUNC_ATAN");
-    PREDEF_FUNCTIONS["atan2"] = ga_predef_function(atan2, 1, "DER_PDFUNC1_ATAN2",
-                                                             "DER_PDFUNC2_ATAN2");
+    PREDEF_FUNCTIONS["atan2"] = ga_predef_function(atan2,1,"DER_PDFUNC1_ATAN2",
+                                                           "DER_PDFUNC2_ATAN2");
     PREDEF_FUNCTIONS["sinc"] = ga_predef_function(ga_sinc, 1,
                                                   "DER_PDFUNC_SINC");
-    PREDEF_FUNCTIONS["DER_PDFUNC_SINC"] = ga_predef_function(ga_der_sinc, 1,
-                                                             "DER2_PDFUNC_SINC");
+    PREDEF_FUNCTIONS["DER_PDFUNC_SINC"] =ga_predef_function(ga_der_sinc, 1,
+							    "DER2_PDFUNC_SINC");
     PREDEF_FUNCTIONS["DER2_PDFUNC_SINC"] = ga_predef_function(ga_der2_sinc);
 
 
@@ -2500,10 +2618,11 @@ namespace getfem {
       ga_predef_function(ga_der_atan, 2, "-2*t/sqr(1+t*t)");
     PREDEF_FUNCTIONS["DER_PDFUNC1_ATAN2"] =
       ga_predef_function(ga_der_t_atan2, 2, "-2*t*u/sqr(sqr(u)+sqr(t))",
-                                            "(sqrt(t)-sqr(u))/sqr(sqr(u)+sqr(t))");
+			 "(sqrt(t)-sqr(u))/sqr(sqr(u)+sqr(t))");
     PREDEF_FUNCTIONS["DER_PDFUNC2_ATAN2"] =
-      ga_predef_function(ga_der_u_atan2, 2, "(sqrt(t)-sqr(u))/sqr(sqr(u)+sqr(t))",
-                                            "2*t*u/sqr(sqr(u)+sqr(t))");
+      ga_predef_function(ga_der_u_atan2, 2,
+			 "(sqrt(t)-sqr(u))/sqr(sqr(u)+sqr(t))",
+			 "2*t*u/sqr(sqr(u)+sqr(t))");
 
 
     // Error functions
@@ -2576,6 +2695,10 @@ namespace getfem {
   void ga_define_function(const std::string &name, size_type nbargs,
                           const std::string &expr, const std::string &der1,
                           const std::string &der2) {
+    auto guard = omp_guard{};
+
+    auto &PREDEF_FUNCTIONS = dal::singleton<ga_predef_function_tab>::instance(0);
+    if(PREDEF_FUNCTIONS.find(name) != PREDEF_FUNCTIONS.end()) return;
     GMM_ASSERT1(nbargs >= 1 && nbargs <= 2, "Generic assembly only allows "
                 "the definition of scalar function with one or two arguments");
     { // Only for syntax analysis
@@ -2587,20 +2710,16 @@ namespace getfem {
       workspace.add_function_expression(expr);
     }
 
-    ga_predef_function_tab &PREDEF_FUNCTIONS
-      = dal::singleton<ga_predef_function_tab>::instance(0);
-    GMM_ASSERT1(PREDEF_FUNCTIONS.find(name) == PREDEF_FUNCTIONS.end(),
-                "Already defined function " << name);
     PREDEF_FUNCTIONS[name] = ga_predef_function(expr);
     ga_predef_function &F = PREDEF_FUNCTIONS[name];
-    GMM_ASSERT1(!me_is_multithreaded_now(),
-                "functions should not be defined in multi-threaded code");
     F.gis = std::make_unique<instruction_set>();
     for (size_type thread = 0; thread < num_threads(); ++thread)
     {
-      F.workspace(thread).add_fixed_size_variable("t", gmm::sub_interval(0,1), F.t(thread));
+      F.workspace(thread).add_fixed_size_variable("t", gmm::sub_interval(0,1),
+						  F.t(thread));
       if (nbargs == 2)
-        F.workspace(thread).add_fixed_size_variable("u", gmm::sub_interval(0,1), F.u(thread));
+        F.workspace(thread).add_fixed_size_variable("u", gmm::sub_interval(0,1),
+						    F.u(thread));
       F.workspace(thread).add_function_expression(expr);
       ga_compile_function(F.workspace(thread), (*F.gis)(thread), true);
     }
@@ -2676,8 +2795,8 @@ namespace getfem {
       size_type ipt = imd.filtered_index_of_point(cv, ctx.ii());
       GMM_ASSERT1(ipt != size_type(-1),
                   "Im data with no data on the current integration point.");
-      gmm::copy(gmm::sub_vector(U, gmm::sub_interval(ipt*qdim, qdim)),
-                t.as_vector());
+      auto it = U.begin()+ipt*qdim;
+      std::copy(it, it+qdim, t.begin());
       return 0;
     }
     ga_instruction_extract_local_im_data
@@ -2693,15 +2812,20 @@ namespace getfem {
     const base_vector &U;
     const fem_interpolation_context &ctx;
     base_vector &coeff;
+    size_type qmult1, qmult2;
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: Slice local dofs");
-      slice_vector_on_basic_dof_of_element(mf, U, ctx.convex_num(), coeff);
+      GMM_ASSERT1(qmult1 != 0 && qmult2 != 0, "Internal error");
+      slice_vector_on_basic_dof_of_element(mf, U, ctx.convex_num(),
+					   coeff, qmult1, qmult2);
       return 0;
     }
     ga_instruction_slice_local_dofs(const mesh_fem &mf_, const base_vector &U_,
                                     const fem_interpolation_context &ctx_,
-                                    base_vector &coeff_)
-      : mf(mf_), U(U_), ctx(ctx_), coeff(coeff_) {}
+                                    base_vector &coeff_,
+				    size_type qmult1_, size_type qmult2_)
+      : mf(mf_), U(U_), ctx(ctx_), coeff(coeff_),
+	qmult1(qmult1_), qmult2(qmult2_) {}
   };
 
   struct ga_instruction_update_pfp : public ga_instruction {
@@ -2713,8 +2837,10 @@ namespace getfem {
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: Pfp update");
       if (ctx.have_pgp()) {
-        pfem pf = mf.fem_of_element(ctx.convex_num());
-        if (!pfp || pf != pfp->get_pfem() ||
+        size_type cv = ctx.is_convex_num_valid()
+                     ? ctx.convex_num() : mf.convex_index().first_true();
+        pfem pf = mf.fem_of_element(cv);
+	if (!pfp || pf != pfp->get_pfem() ||
             ctx.pgp()->get_ppoint_tab() != pfp->get_ppoint_tab()) {
           pfp = fp_pool(pf, ctx.pgp()->get_ppoint_tab());
         }
@@ -2735,28 +2861,19 @@ namespace getfem {
     const fem_interpolation_context &ctx;
     size_type qdim;
     const mesh_fem *mfn, **mfg;
-
+    
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: adapt first index of tensor");
       const mesh_fem &mf = *(mfg ? *mfg : mfn);
-      // cout << "mfg = " << mfg << endl;
-      GA_DEBUG_ASSERT(&mf, "Internal error");
-      // cout << "ctx.is_convex_num_valid() = " << int(ctx.is_convex_num_valid()) << endl;
+      GA_DEBUG_ASSERT(mfg ? *mfg : mfn, "Internal error");
       size_type cv_1 = ctx.is_convex_num_valid()
-                     ? ctx.convex_num() : mf.convex_index().first_true();
-      if (!mf.convex_index().is_in(cv_1))
-        cv_1 = mf.convex_index().first_true();
-
-
-      // cout << "cv_1 " << cv_1 << endl;
+	? ctx.convex_num() : mf.convex_index().first_true();
       pfem pf = mf.fem_of_element(cv_1);
-      GMM_ASSERT1(pf, "An element without finite element methode defined");
-      // cout << "pf = " << pf << endl;
+      GMM_ASSERT1(pf, "An element without finite element method defined");
       size_type Qmult = qdim / pf->target_dim();
       size_type s = pf->nb_dof(cv_1) * Qmult;
       if (t.sizes()[0] != s)
-        { bgeot::multi_index mi = t.sizes(); mi[0] = s; t.adjust_sizes(mi); }
-      // cout << "here " << endl;
+	{ bgeot::multi_index mi = t.sizes(); mi[0] = s; t.adjust_sizes(mi); }
       return 0;
     }
 
@@ -2767,28 +2884,28 @@ namespace getfem {
       : t(t_),  ctx(ctx_), qdim(qdim_), mfn(mfn_), mfg(mfg_) {}
   };
 
-  struct ga_instruction_second_ind_tensor : public ga_instruction_first_ind_tensor {
+  struct ga_instruction_second_ind_tensor
+    : public ga_instruction_first_ind_tensor {
 
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: adapt second index of tensor");
       const mesh_fem &mf = *(mfg ? *mfg : mfn);
       size_type cv_1 = ctx.is_convex_num_valid()
-        ? ctx.convex_num() : mf.convex_index().first_true();
+	? ctx.convex_num() : mf.convex_index().first_true();
       pfem pf = mf.fem_of_element(cv_1);
       GMM_ASSERT1(pf, "An element without finite element methode defined");
       size_type Qmult = qdim / pf->target_dim();
       size_type s = pf->nb_dof(cv_1) * Qmult;
       if (t.sizes()[1] != s)
-        { bgeot::multi_index mi = t.sizes(); mi[1] = s; t.adjust_sizes(mi); }
+	{ bgeot::multi_index mi = t.sizes(); mi[1] = s; t.adjust_sizes(mi); }
       return 0;
     }
 
-    ga_instruction_second_ind_tensor(base_tensor &t_, fem_interpolation_context &ctx_,
+    ga_instruction_second_ind_tensor(base_tensor &t_,
+				     fem_interpolation_context &ctx_,
                                      size_type qdim_, const mesh_fem *mfn_,
                                      const mesh_fem **mfg_)
-   : ga_instruction_first_ind_tensor(t_, ctx_, qdim_, mfn_, mfg_)
-   {}
-;
+      : ga_instruction_first_ind_tensor(t_, ctx_, qdim_, mfn_, mfg_) {}
 
   };
 
@@ -2799,15 +2916,15 @@ namespace getfem {
     const mesh_fem *mfn1, **mfg1;
     size_type qdim2;
     const mesh_fem *mfn2, **mfg2;
-
+    
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: adapt two first indices of tensor");
       const mesh_fem &mf1 = *(mfg1 ? *mfg1 : mfn1);
       const mesh_fem &mf2 = *(mfg2 ? *mfg2 : mfn2);
       size_type cv_1 = ctx1.is_convex_num_valid()
-        ? ctx1.convex_num() : mf1.convex_index().first_true();
+	? ctx1.convex_num() : mf1.convex_index().first_true();
       size_type cv_2 = ctx2.is_convex_num_valid()
-        ? ctx2.convex_num() : mf2.convex_index().first_true();
+	? ctx2.convex_num() : mf2.convex_index().first_true();
       pfem pf1 = mf1.fem_of_element(cv_1);
       GMM_ASSERT1(pf1, "An element without finite element method defined");
       pfem pf2 = mf2.fem_of_element(cv_2);
@@ -2817,9 +2934,9 @@ namespace getfem {
       size_type Qmult2 = qdim2 / pf2->target_dim();
       size_type s2 = pf2->nb_dof(cv_2) * Qmult2;
       if (t.sizes()[0] != s1 || t.sizes()[1] != s2) {
-        bgeot::multi_index mi = t.sizes();
-        mi[0] = s1; mi[1] = s2;
-        t.adjust_sizes(mi);
+	bgeot::multi_index mi = t.sizes();
+	mi[0] = s1; mi[1] = s2;
+	t.adjust_sizes(mi);
       }
       return 0;
     }
@@ -2845,8 +2962,8 @@ namespace getfem {
       return 0;
     }
 
-    ga_instruction_X_component(scalar_type &t_,
-                               const fem_interpolation_context &ctx_, size_type n_)
+    ga_instruction_X_component
+    (scalar_type &t_, const fem_interpolation_context &ctx_, size_type n_)
       : t(t_),  ctx(ctx_), n(n_) {}
   };
 
@@ -2947,10 +3064,16 @@ namespace getfem {
 
     virtual int exec() { // --> t(ndof,target_dim)
       GA_DEBUG_INFO("Instruction: compute value of base functions");
-      if (pfp) ctx.set_pfp(pfp);
-      else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
-      GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
-      ctx.pf()->real_base_value(ctx, t);
+      // if (ctx.have_pgp()) ctx.set_pfp(pfp);
+      // else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
+      // GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
+      // ctx.base_value(t);
+      if (ctx.have_pgp()) ctx.pfp_base_value(t, pfp);
+      else {
+        ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
+        GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
+        ctx.base_value(t);
+      }
       return 0;
     }
 
@@ -2967,12 +3090,12 @@ namespace getfem {
 
     virtual int exec() { // --> t(ndof,target_dim)
       GA_DEBUG_INFO("Instruction: compute value of base functions");
-      if (pfp) ctx.set_pfp(pfp);
+      if (ctx.have_pgp()) ctx.set_pfp(pfp);
       else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
       GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
       int old_xfem_side = ctx.xfem_side();
       ctx.set_xfem_side(1);
-      ctx.pf()->real_base_value(ctx, t);
+      ctx.base_value(t);
       ctx.set_xfem_side(old_xfem_side);
       return 0;
     }
@@ -2991,18 +3114,19 @@ namespace getfem {
 
     virtual int exec() { // --> t(ndof,target_dim)
       GA_DEBUG_INFO("Instruction: compute value of base functions");
-      if (pfp) ctx.set_pfp(pfp);
+      if (ctx.have_pgp()) ctx.set_pfp(pfp);
       else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
       GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
       int old_xfem_side = ctx.xfem_side();
       ctx.set_xfem_side(-1);
-      ctx.pf()->real_base_value(ctx, t);
+      ctx.base_value(t);
       ctx.set_xfem_side(old_xfem_side);
       return 0;
     }
 
-    ga_instruction_xfem_minus_val_base(base_tensor &tt, fem_interpolation_context &ct,
-                                       const mesh_fem &mf_, pfem_precomp &pfp_)
+    ga_instruction_xfem_minus_val_base
+    (base_tensor &tt, fem_interpolation_context &ct,
+     const mesh_fem &mf_, pfem_precomp &pfp_)
       : t(tt), ctx(ct), mf(mf_), pfp(pfp_) {}
   };
 
@@ -3010,10 +3134,16 @@ namespace getfem {
 
     virtual int exec() { // --> t(ndof,target_dim,N)
       GA_DEBUG_INFO("Instruction: compute gradient of base functions");
-      if (pfp) ctx.set_pfp(pfp);
-      else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
-      GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
-      ctx.pf()->real_grad_base_value(ctx, t);
+      // if (ctx.have_pgp()) ctx.set_pfp(pfp);
+      // else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
+      // GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
+      // ctx.grad_base_value(t);
+      if (ctx.have_pgp()) ctx.pfp_grad_base_value(t, pfp);
+      else {
+        ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
+        GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
+        ctx.grad_base_value(t);
+      }
       return 0;
     }
 
@@ -3027,18 +3157,19 @@ namespace getfem {
 
     virtual int exec() { // --> t(ndof,target_dim,N)
       GA_DEBUG_INFO("Instruction: compute gradient of base functions");
-      if (pfp) ctx.set_pfp(pfp);
+      if (ctx.have_pgp()) ctx.set_pfp(pfp);
       else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
       GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
       int old_xfem_side = ctx.xfem_side();
       ctx.set_xfem_side(1);
-      ctx.pf()->real_grad_base_value(ctx, t);
+      ctx.grad_base_value(t);
       ctx.set_xfem_side(old_xfem_side);
       return 0;
     }
 
-    ga_instruction_xfem_plus_grad_base(base_tensor &tt, fem_interpolation_context &ct,
-                                       const mesh_fem &mf_, pfem_precomp &pfp_)
+    ga_instruction_xfem_plus_grad_base
+    (base_tensor &tt, fem_interpolation_context &ct,
+     const mesh_fem &mf_, pfem_precomp &pfp_)
     : ga_instruction_val_base(tt, ct, mf_, pfp_)
     {}
   };
@@ -3047,18 +3178,19 @@ namespace getfem {
 
     virtual int exec() { // --> t(ndof,target_dim,N)
       GA_DEBUG_INFO("Instruction: compute gradient of base functions");
-      if (pfp) ctx.set_pfp(pfp);
+      if (ctx.have_pgp()) ctx.set_pfp(pfp);
       else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
       GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
       int old_xfem_side = ctx.xfem_side();
       ctx.set_xfem_side(-1);
-      ctx.pf()->real_grad_base_value(ctx, t);
+      ctx.grad_base_value(t);
       ctx.set_xfem_side(old_xfem_side);
       return 0;
     }
 
-    ga_instruction_xfem_minus_grad_base(base_tensor &tt, fem_interpolation_context &ct,
-                                        const mesh_fem &mf_, pfem_precomp &pfp_)
+    ga_instruction_xfem_minus_grad_base
+    (base_tensor &tt, fem_interpolation_context &ct,
+     const mesh_fem &mf_, pfem_precomp &pfp_)
     : ga_instruction_val_base(tt, ct, mf_, pfp_)
     {}
   };
@@ -3066,12 +3198,12 @@ namespace getfem {
 
   struct ga_instruction_hess_base : public ga_instruction_val_base {
 
-    virtual int exec() { // --> t(ndof,target_dim,N,N)
+    virtual int exec() { // --> t(ndof,target_dim,N*N)
       GA_DEBUG_INFO("Instruction: compute Hessian of base functions");
-      if (pfp) ctx.set_pfp(pfp);
+      if (ctx.have_pgp()) ctx.set_pfp(pfp);
       else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
       GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
-      ctx.pf()->real_hess_base_value(ctx, t);
+      ctx.hess_base_value(t);
       return 0;
     }
 
@@ -3083,45 +3215,48 @@ namespace getfem {
 
   struct ga_instruction_xfem_plus_hess_base : public ga_instruction_val_base {
 
-    virtual int exec() { // --> t(ndof,target_dim,N,N)
+    virtual int exec() { // --> t(ndof,target_dim,N*N)
       GA_DEBUG_INFO("Instruction: compute Hessian of base functions");
-      if (pfp) ctx.set_pfp(pfp);
+      if (ctx.have_pgp()) ctx.set_pfp(pfp);
       else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
       GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
       int old_xfem_side = ctx.xfem_side();
       ctx.set_xfem_side(1);
-      ctx.pf()->real_hess_base_value(ctx, t);
+      ctx.hess_base_value(t);
       ctx.set_xfem_side(old_xfem_side);
       return 0;
     }
 
-    ga_instruction_xfem_plus_hess_base(base_tensor &tt, fem_interpolation_context &ct,
-                                       const mesh_fem &mf_, pfem_precomp &pfp_)
+    ga_instruction_xfem_plus_hess_base
+    (base_tensor &tt, fem_interpolation_context &ct,
+     const mesh_fem &mf_, pfem_precomp &pfp_)
     : ga_instruction_val_base(tt, ct, mf_, pfp_)
     {}
   };
 
   struct ga_instruction_xfem_minus_hess_base : public ga_instruction_val_base {
 
-    virtual int exec() { // --> t(ndof,target_dim,N,N)
+    virtual int exec() { // --> t(ndof,target_dim,N*N)
       GA_DEBUG_INFO("Instruction: compute Hessian of base functions");
-      if (pfp) ctx.set_pfp(pfp);
+      if (ctx.have_pgp()) ctx.set_pfp(pfp);
       else ctx.set_pf(mf.fem_of_element(ctx.convex_num()));
       GMM_ASSERT1(ctx.pf(), "Undefined finite element method");
       int old_xfem_side = ctx.xfem_side();
       ctx.set_xfem_side(-1);
-      ctx.pf()->real_hess_base_value(ctx, t);
+      ctx.hess_base_value(t);
       ctx.set_xfem_side(old_xfem_side);
       return 0;
     }
 
-    ga_instruction_xfem_minus_hess_base(base_tensor &tt, fem_interpolation_context &ct,
-                                        const mesh_fem &mf_, pfem_precomp &pfp_)
+    ga_instruction_xfem_minus_hess_base
+    (base_tensor &tt, fem_interpolation_context &ct,
+     const mesh_fem &mf_, pfem_precomp &pfp_)
     : ga_instruction_val_base(tt, ct, mf_, pfp_)
     {}
   };
 
   struct ga_instruction_val : public ga_instruction {
+    scalar_type &a;
     base_tensor &t;
     const base_tensor &Z;
     const base_vector &coeff;
@@ -3130,27 +3265,50 @@ namespace getfem {
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: variable value");
       size_type ndof = Z.sizes()[0];
-      size_type target_dim = Z.sizes()[1];
-      size_type Qmult = qdim / target_dim;
+      if (!ndof) { gmm::clear(t.as_vector()); return 0; }
       GA_DEBUG_ASSERT(t.size() == qdim, "dimensions mismatch");
-      GA_DEBUG_ASSERT(gmm::vect_size(coeff) == ndof*Qmult,
-                      "Wrong size for coeff vector");
-
-      gmm::clear(t.as_vector());
-      for (size_type j = 0; j < ndof; ++j) {
-        for (size_type q = 0; q < Qmult; ++q) {
-          scalar_type co = coeff[j*Qmult+q];
-          for (size_type r = 0; r < target_dim; ++r)
-            t[r + q*target_dim] += co * Z[j + r*ndof];
-        }
+      
+      if (qdim == 1) {
+	GA_DEBUG_ASSERT(gmm::vect_size(coeff) == ndof,
+			"Wrong size for coeff vector");
+	auto itc = coeff.begin(); auto itZ = Z.begin();
+	a = (*itc++) * (*itZ++);
+	while (itc != coeff.end()) a += (*itc++) * (*itZ++);
+      } else {
+	size_type target_dim = Z.sizes()[1];
+	if (target_dim == 1) {
+	  GA_DEBUG_ASSERT(gmm::vect_size(coeff) == ndof*qdim,
+			  "Wrong size for coeff vector");
+	  auto itc = coeff.begin(); auto itZ = Z.begin();
+	  for (auto it = t.begin(); it != t.end(); ++it)
+	    *it = (*itc++) * (*itZ);
+	  ++itZ;
+	  for (size_type j = 1; j < ndof; ++j, ++itZ) {
+	    for (auto it = t.begin(); it != t.end(); ++it)
+	      *it += (*itc++) * (*itZ);
+	  }
+	} else {
+	  size_type Qmult = qdim / target_dim;
+	  GA_DEBUG_ASSERT(gmm::vect_size(coeff) == ndof*Qmult,
+			  "Wrong size for coeff vector");
+	  
+	  gmm::clear(t.as_vector());
+	  auto itc = coeff.begin();
+	  for (size_type j = 0; j < ndof; ++j) {
+	    auto it = t.begin();
+	    for (size_type q = 0; q < Qmult; ++q, ++itc) {
+	      for (size_type r = 0; r < target_dim; ++r)
+		*it++ += (*itc) * Z[j + r*ndof];
+	    }
+	  }
+	}
       }
-      GA_DEBUG_INFO("Instruction: end of variable value");
       return 0;
     }
 
     ga_instruction_val(base_tensor &tt, const base_tensor &Z_,
                        const base_vector &co, size_type q)
-      : t(tt), Z(Z_), coeff(co), qdim(q) {}
+      : a(tt[0]), t(tt), Z(Z_), coeff(co), qdim(q) {}
   };
 
   struct ga_instruction_grad : public ga_instruction_val {
@@ -3158,22 +3316,47 @@ namespace getfem {
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: gradient");
       size_type ndof = Z.sizes()[0];
-      size_type target_dim = Z.sizes()[1];
+      if (!ndof) { gmm::clear(t.as_vector()); return 0; }
       size_type N = Z.sizes()[2];
-      size_type Qmult = qdim / target_dim;
-      GA_DEBUG_ASSERT((qdim == 1 && t.sizes()[0] == N) ||
-                      (t.sizes()[1] == N && t.sizes()[0] == qdim) ||
-                      (N == 1 && t.sizes()[0] == qdim),
-                      "dimensions mismatch");
-      GA_DEBUG_ASSERT(gmm::vect_size(coeff) == ndof*Qmult,
-                      "Wrong size for coeff vector");
-      gmm::clear(t.as_vector());
-      for (size_type q = 0; q < Qmult; ++q) {
-        base_tensor::const_iterator it = Z.begin();
-        for (size_type k = 0; k < N; ++k)
-          for (size_type r = 0; r < target_dim; ++r)
-            for (size_type j = 0; j < ndof; ++j, ++it)
-              t[r + q*target_dim + k*qdim] += coeff[j*Qmult+q] * (*it);
+      if (qdim == 1) {
+	GA_DEBUG_ASSERT(t.size() == N, "dimensions mismatch");
+	GA_DEBUG_ASSERT(coeff.size() == ndof, "Wrong size for coeff vector");
+	auto itZ = Z.begin();
+	for (auto it = t.begin(); it != t.end(); ++it) {
+	  auto itc = coeff.begin();
+	  *it =  (*itc++) * (*itZ++);
+	  while (itc != coeff.end()) *it += (*itc++) * (*itZ++);
+	}
+      } else {
+	size_type target_dim = Z.sizes()[1];
+	if (target_dim == 1) {
+	  GA_DEBUG_ASSERT(t.size() == N*qdim, "dimensions mismatch");
+	  GA_DEBUG_ASSERT(coeff.size() == ndof*qdim,
+			  "Wrong size for coeff vector");
+	  for (size_type q = 0; q < qdim; ++q) {
+	    auto itZ = Z.begin(); auto it = t.begin() + q;
+	    for (size_type k = 0; k < N; ++k) {
+	      if (k)  it += qdim;
+	      auto itc = coeff.begin() + q;
+	      *it = (*itc) * (*itZ++);
+	      for (size_type j = 1; j < ndof; ++j)
+		{ itc += qdim; *it += (*itc) * (*itZ++); }
+	    }
+	  }
+	} else {
+	  size_type Qmult = qdim / target_dim;
+	  GA_DEBUG_ASSERT(t.size() == N*qdim, "dimensions mismatch");
+	  GA_DEBUG_ASSERT(coeff.size() == ndof*Qmult,
+			  "Wrong size for coeff vector");
+	  gmm::clear(t.as_vector());
+	  for (size_type q = 0; q < Qmult; ++q) {
+	    auto itZ = Z.begin();
+	    for (size_type k = 0; k < N; ++k)
+	      for (size_type r = 0; r < target_dim; ++r)
+		for (size_type j = 0; j < ndof; ++j)
+		  t[r + q*target_dim + k*qdim] += coeff[j*Qmult+q] * (*itZ++);
+	  }
+	}
       }
       return 0;
     }
@@ -3190,24 +3373,46 @@ namespace getfem {
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: Hessian");
       size_type ndof = Z.sizes()[0];
-      size_type target_dim = Z.sizes()[1];
-      size_type N = size_type(round(sqrt(scalar_type(Z.sizes()[2]))));
-      size_type Qmult = qdim / target_dim;
-      GA_DEBUG_ASSERT((qdim == 1 && N == 1 && t.sizes()[0] == 1) ||
-                      (qdim == 1 && t.sizes()[0] == N && t.sizes()[1] == N) ||
-                      (t.sizes()[1] == N && t.sizes()[2] == N
-                       && t.sizes()[0] == qdim), "dimensions mismatch");
-      GA_DEBUG_ASSERT(gmm::vect_size(coeff) == ndof*Qmult,
-                      "Wrong size for coeff vector");
-      gmm::clear(t.as_vector());
-      for (size_type q = 0; q < Qmult; ++q) {
-        base_tensor::const_iterator it = Z.begin();
-        for (size_type k = 0; k < N; ++k)
-          for (size_type l = 0; l < N; ++l)
-            for (size_type r = 0; r < target_dim; ++r)
+      if (!ndof) { gmm::clear(t.as_vector()); return 0; }
+      size_type NN = gmm::sqr(t.sizes().back());
+      GA_DEBUG_ASSERT(NN == Z.sizes()[2], "Internal error");
+      if (qdim == 1) {
+        GA_DEBUG_ASSERT(gmm::vect_size(coeff) == ndof,
+                        "Wrong size for coeff vector");
+        auto it = Z.begin(); auto itt = t.begin();
+        for (size_type kl = 0; kl < NN; ++kl, ++itt) {
+          *itt = scalar_type(0);
+          for (auto itc = coeff.begin(); itc != coeff.end(); ++itc, ++it)
+            *itt += (*itc) * (*it);
+        }
+        GMM_ASSERT1(itt == t.end(),  "dimensions mismatch");
+      } else {
+        size_type target_dim = Z.sizes()[1];
+        if (target_dim == 1) {
+          GA_DEBUG_ASSERT(t.size() == NN*qdim, "dimensions mismatch");
+          GA_DEBUG_ASSERT(gmm::vect_size(coeff) == ndof*qdim,
+                          "Wrong size for coeff vector");
+          gmm::clear(t.as_vector());
+          for (size_type q = 0; q < qdim; ++q) {
+            base_tensor::const_iterator it = Z.begin();
+            for (size_type kl = 0; kl < NN; ++kl)
               for (size_type j = 0; j < ndof; ++j, ++it)
-                t[r + q*target_dim + k*qdim + l*qdim*N]
-                  += coeff[j*Qmult+q] * (*it);
+                t[q + kl*qdim] += coeff[j*qdim+q] * (*it);
+          }
+        } else {
+          size_type Qmult = qdim / target_dim;
+          GA_DEBUG_ASSERT(t.size() == NN*qdim, "dimensions mismatch");
+          GA_DEBUG_ASSERT(gmm::vect_size(coeff) == ndof*Qmult,
+                          "Wrong size for coeff vector");
+          gmm::clear(t.as_vector());
+          for (size_type q = 0; q < Qmult; ++q) {
+            base_tensor::const_iterator it = Z.begin();
+            for (size_type kl = 0; kl < NN; ++kl)
+              for (size_type r = 0; r < target_dim; ++r)
+                for (size_type j = 0; j < ndof; ++j, ++it)
+                  t[r + q*target_dim + kl*qdim] += coeff[j*Qmult+q] * (*it);
+          } 
+        }
       }
       return 0;
     }
@@ -3223,6 +3428,7 @@ namespace getfem {
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: divergence");
       size_type ndof = Z.sizes()[0];
+      if (!ndof) { gmm::clear(t.as_vector()); return 0; }
       size_type target_dim = Z.sizes()[1];
       size_type N = Z.sizes()[2];
       size_type Qmult = qdim / target_dim;
@@ -3258,7 +3464,6 @@ namespace getfem {
     {}
   };
 
-
   struct ga_instruction_copy_val_base : public ga_instruction {
     base_tensor &t;
     const base_tensor &Z;
@@ -3266,111 +3471,217 @@ namespace getfem {
     // Z(ndof,target_dim) --> t(Qmult*ndof,Qmult*target_dim)
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: value of test functions");
-      size_type ndof = Z.sizes()[0];
-      size_type target_dim = Z.sizes()[1];
-      size_type Qmult = qdim / target_dim;
-      GA_DEBUG_ASSERT(t.size() == Z.size() * Qmult * Qmult,
-                      "Wrong size for base vector");
-      if (Qmult == 1) {
-        gmm::copy(Z.as_vector(), t.as_vector());
+      if (qdim == 1) {
+	std::copy(Z.begin(), Z.end(), t.begin());
       } else {
-        gmm::clear(t.as_vector());
-        base_tensor::const_iterator itZ = Z.begin();
-        size_type s = t.sizes()[0], ss = s * Qmult, sss = s+1;
-
-        // Performs t(i*Qmult+j, k*Qmult + j) = Z(i,k);
-        for (size_type k = 0; k < target_dim; ++k) {
-          base_tensor::iterator it = t.begin() + (ss * k);
-          for (size_type i = 0; i < ndof; ++i, ++itZ) {
-            if (i) it += Qmult;
-            base_tensor::iterator it2 = it;
-            *it2 = *itZ;
-            for (size_type j = 1; j < Qmult; ++j) { it2 += sss; *it2 = *itZ; }
-          }
-        }
+	size_type target_dim = Z.sizes()[1];
+	size_type Qmult = qdim / target_dim;
+	if (Qmult == 1) {
+	  std::copy(Z.begin(), Z.end(), t.begin());
+	} else {
+	  if (target_dim == 1) {
+	    size_type ndof = Z.sizes()[0];
+	    GA_DEBUG_ASSERT(t.size() == Z.size() * Qmult * Qmult,
+			    "Wrong size for base vector");
+	    std::fill(t.begin(), t.end(), scalar_type(0));
+	    auto itZ = Z.begin();
+	    size_type s = t.sizes()[0], sss = s+1;
+	    
+	    // Performs t(i*Qmult+j, k*Qmult + j) = Z(i,k);
+	    auto it = t.begin();
+	    for (size_type i = 0; i < ndof; ++i, ++itZ) {
+	      if (i) it += Qmult;
+	      auto it2 = it;
+	      *it2 = *itZ;
+	      for (size_type j = 1; j < Qmult; ++j) { it2 += sss; *it2 = *itZ; }
+	    }
+	  } else {
+	    size_type ndof = Z.sizes()[0];
+	    GA_DEBUG_ASSERT(t.size() == Z.size() * Qmult * Qmult,
+			    "Wrong size for base vector");
+	    std::fill(t.begin(), t.end(), scalar_type(0));
+	    auto itZ = Z.begin();
+	    size_type s = t.sizes()[0], ss = s * Qmult, sss = s+1;
+	    
+	    // Performs t(i*Qmult+j, k*Qmult + j) = Z(i,k);
+	    for (size_type k = 0; k < target_dim; ++k) {
+	      auto it = t.begin() + (ss * k);
+	      for (size_type i = 0; i < ndof; ++i, ++itZ) {
+		if (i) it += Qmult;
+		auto it2 = it;
+		*it2 = *itZ;
+		for (size_type j = 1; j < Qmult; ++j)
+		  { it2 += sss; *it2 = *itZ; }
+	      }
+	    }
+	  }
+	}
       }
       return 0;
     }
 
-    ga_instruction_copy_val_base(base_tensor &tt, const base_tensor &Z_, size_type q)
-      : t(tt), Z(Z_), qdim(q) {}
+    ga_instruction_copy_val_base(base_tensor &tt, const base_tensor &Z_,
+                                 size_type q) : t(tt), Z(Z_), qdim(q) {}
   };
 
   struct ga_instruction_copy_grad_base : public ga_instruction_copy_val_base {
     // Z(ndof,target_dim,N) --> t(Qmult*ndof,Qmult*target_dim,N)
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: gradient of test functions");
+      if (qdim == 1) {
+	std::copy(Z.begin(), Z.end(), t.begin());
+      } else {
+	size_type target_dim = Z.sizes()[1];
+	size_type Qmult = qdim / target_dim;
+	if (Qmult == 1) {
+	  std::copy(Z.begin(), Z.end(), t.begin());
+	} else {
+	  if (target_dim == 1) {
+	    size_type ndof = Z.sizes()[0];
+	    size_type N = Z.sizes()[2];
+	    GA_DEBUG_ASSERT(t.size() == Z.size() * Qmult * Qmult,
+			    "Wrong size for gradient vector");
+	    std::fill(t.begin(), t.end(), scalar_type(0));
+	    base_tensor::const_iterator itZ = Z.begin();
+	    size_type s = t.sizes()[0], sss = s+1, ssss = s*target_dim*Qmult;
+	    
+	    // Performs t(i*Qmult+j, k*Qmult + j, l) = Z(i,k,l);
+	    for (size_type l = 0; l < N; ++l) {
+	      base_tensor::iterator it = t.begin() + (ssss*l);
+	      for (size_type i = 0; i < ndof; ++i, ++itZ) {
+		if (i) it += Qmult;
+		base_tensor::iterator it2 = it;
+		*it2 = *itZ;
+		for (size_type j = 1; j < Qmult; ++j) { it2+=sss; *it2=*itZ; }
+	      }
+	    }
+	  } else {
+	    size_type ndof = Z.sizes()[0];
+	    size_type N = Z.sizes()[2];
+	    GA_DEBUG_ASSERT(t.size() == Z.size() * Qmult * Qmult,
+			    "Wrong size for gradient vector");
+	    std::fill(t.begin(), t.end(), scalar_type(0));
+	    base_tensor::const_iterator itZ = Z.begin();
+	    size_type s = t.sizes()[0], ss = s * Qmult, sss = s+1;
+	    size_type ssss = ss*target_dim;
+	    
+	    // Performs t(i*Qmult+j, k*Qmult + j, l) = Z(i,k,l);
+	    for (size_type l = 0; l < N; ++l)
+	      for (size_type k = 0; k < target_dim; ++k) {
+		base_tensor::iterator it = t.begin() + (ss * k + ssss*l);
+		for (size_type i = 0; i < ndof; ++i, ++itZ) {
+		  if (i) it += Qmult;
+		  base_tensor::iterator it2 = it;
+		  *it2 = *itZ;
+		  for (size_type j = 1; j < Qmult; ++j) { it2+=sss; *it2=*itZ; }
+		}
+	      }
+	  }
+	}
+      }
+      return 0;
+    }
+
+    ga_instruction_copy_grad_base(base_tensor &tt, const base_tensor &Z_,
+                                  size_type q)
+      : ga_instruction_copy_val_base(tt,Z_,q) {}
+  };
+
+  struct ga_instruction_copy_vect_val_base : public ga_instruction {
+    base_tensor &t;
+    const base_tensor &Z;
+    size_type qdim;
+    // Z(ndof) --> t(qdim*ndof,qdim*target_dim)
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: vectorized value of test functions");
+      
+      size_type ndof = Z.sizes()[0];
+      GA_DEBUG_ASSERT(t.size() == Z.size() * qdim * qdim,
+		      "Wrong size for base vector");
+      // std::fill(t.begin(), t.end(), scalar_type(0)); // Factorized
+      auto itZ = Z.begin();
+      size_type s = t.sizes()[0], sss = s+1;
+      
+      // Performs t(i*qdim+j, k*qdim + j) = Z(i,k);
+      auto it = t.begin();
+      for (size_type i = 0; i < ndof; ++i, ++itZ) {
+	if (i) it += qdim;
+	auto it2 = it;
+	*it2 = *itZ;
+	for (size_type j = 1; j < qdim; ++j) { it2 += sss; *it2 = *itZ; }
+      }
+      return 0;
+    }
+
+    ga_instruction_copy_vect_val_base(base_tensor &tt, const base_tensor &Z_,
+				      size_type q) : t(tt), Z(Z_), qdim(q) {}
+  };
+
+  struct ga_instruction_copy_vect_grad_base
+    : public ga_instruction_copy_vect_val_base {
+    // Z(ndof,N) --> t(qdim*ndof,qdim,N)
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: vectorized gradient of test functions");
       size_type ndof = Z.sizes()[0];
-      size_type target_dim = Z.sizes()[1];
       size_type N = Z.sizes()[2];
-      size_type Qmult = qdim / target_dim;
-      GA_DEBUG_ASSERT(t.size() == Z.size() * Qmult * Qmult,
-                      "Wrong size for gradient vector");
-      if (Qmult == 1) {
-        gmm::copy(Z.as_vector(), t.as_vector());
-      } else {
-        gmm::clear(t.as_vector());
-        base_tensor::const_iterator itZ = Z.begin();
-        size_type s = t.sizes()[0], ss = s * Qmult, sss = s+1;
-        size_type ssss=ss*target_dim;
-
-        // Performs t(i*Qmult+j, k*Qmult + j, l) = Z(i,k,l);
-        for (size_type l = 0; l < N; ++l)
-          for (size_type k = 0; k < target_dim; ++k) {
-            base_tensor::iterator it = t.begin() + (ss * k + ssss*l);
-            for (size_type i = 0; i < ndof; ++i, ++itZ) {
-              if (i) it += Qmult;
-              base_tensor::iterator it2 = it;
-              *it2 = *itZ;
-              for (size_type j = 1; j < Qmult; ++j) { it2 += sss; *it2 = *itZ; }
-            }
-          }
+      GA_DEBUG_ASSERT(t.size() == Z.size() * qdim * qdim,
+		      "Wrong size for gradient vector");
+      // std::fill(t.begin(), t.end(), scalar_type(0)); // Factorized
+      base_tensor::const_iterator itZ = Z.begin();
+      size_type s = t.sizes()[0], sss = s+1, ssss = s*qdim;
+      
+      // Performs t(i*qdim+j, k*qdim + j, l) = Z(i,k,l);
+      for (size_type l = 0; l < N; ++l) {
+	base_tensor::iterator it = t.begin() + (ssss*l);
+	for (size_type i = 0; i < ndof; ++i, ++itZ) {
+	  if (i) it += qdim;
+	  base_tensor::iterator it2 = it;
+	  *it2 = *itZ;
+	  for (size_type j = 1; j < qdim; ++j) { it2+=sss; *it2=*itZ; }
+	}
       }
       return 0;
     }
 
-     ga_instruction_copy_grad_base(base_tensor &tt, const base_tensor &Z_, size_type q)
-     : ga_instruction_copy_val_base(tt,Z_,q)
-     {}
+    ga_instruction_copy_vect_grad_base(base_tensor &tt, const base_tensor &Z_,
+				       size_type q)
+      : ga_instruction_copy_vect_val_base(tt,Z_,q) {}
   };
 
   struct ga_instruction_copy_hess_base : public ga_instruction_copy_val_base {
     // Z(ndof,target_dim,N*N) --> t(Qmult*ndof,Qmult*target_dim,N,N)
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: Hessian of test functions");
-      size_type ndof = Z.sizes()[0];
       size_type target_dim = Z.sizes()[1];
-      size_type N2 = Z.sizes()[2];
       size_type Qmult = qdim / target_dim;
-      GA_DEBUG_ASSERT(t.size() == Z.size() * Qmult * Qmult,
-                      "Wrong size for Hessian vector");
       if (Qmult == 1) {
         gmm::copy(Z.as_vector(), t.as_vector());
       } else {
+        size_type ndof = Z.sizes()[0];
+        GA_DEBUG_ASSERT(t.size() == Z.size() * Qmult * Qmult,
+                      "Wrong size for Hessian vector");
         gmm::clear(t.as_vector());
-
         base_tensor::const_iterator itZ = Z.begin();
         size_type s = t.sizes()[0], ss = s * Qmult, sss = s+1;
-        size_type ssss=ss*target_dim;
 
         // Performs t(i*Qmult+j, k*Qmult + j, l, m) = Z(i,k,l*N+m)
-        for (size_type l = 0; l < N2; ++l)
-          for (size_type k = 0; k < target_dim; ++k) {
-            base_tensor::iterator it = t.begin() + (ss * k + ssss*l);
-            for (size_type i = 0; i < ndof; ++i, ++itZ) {
-              if (i) it += Qmult;
-              base_tensor::iterator it2 = it;
-              *it2 = *itZ;
-              for (size_type j = 1; j < Qmult; ++j) { it2 += sss; *it2 = *itZ; }
-            }
+        size_type NNdim = Z.sizes()[2]*target_dim;
+        for (size_type klm = 0; klm < NNdim; ++klm) {
+          base_tensor::iterator it = t.begin() + (ss * klm);
+          for (size_type i = 0; i < ndof; ++i, ++itZ) {
+	    if (i) it += Qmult;
+            base_tensor::iterator it2 = it;
+            *it2 = *itZ;
+            for (size_type j = 1; j < Qmult; ++j) { it2 += sss; *it2 = *itZ; }
           }
+        }
       }
       return 0;
     }
 
-    ga_instruction_copy_hess_base(base_tensor &tt, const base_tensor &Z_, size_type q)
-    : ga_instruction_copy_val_base(tt, Z_, q)
-    {}
+    ga_instruction_copy_hess_base(base_tensor &tt, const base_tensor &Z_,
+                                  size_type q)
+    : ga_instruction_copy_val_base(tt, Z_, q) {}
   };
 
   struct ga_instruction_copy_diverg_base : public ga_instruction_copy_val_base {
@@ -3411,12 +3722,11 @@ namespace getfem {
       return 0;
     }
 
-    ga_instruction_copy_diverg_base(base_tensor &tt, const base_tensor &Z_, size_type q)
-    : ga_instruction_copy_val_base(tt, Z_, q)
-    {}
+    ga_instruction_copy_diverg_base(base_tensor &tt, const base_tensor &Z_,
+                                    size_type q)
+      : ga_instruction_copy_val_base(tt, Z_, q) {}
   };
 
-
   struct ga_instruction_elementary_transformation {
     const base_vector &coeff_in;
     base_vector coeff_out;
@@ -3430,7 +3740,7 @@ namespace getfem {
     void do_transformation() {
       size_type nn = gmm::vect_size(coeff_in);
       if (M.size() == 0 || icv != ctx.convex_num() || &mf != *mf_M) {
-        gmm::resize(M, nn, nn);
+        M.base_resize(nn, nn);
         *mf_M = &mf; icv = ctx.convex_num();
         elemtrans->give_transformation(mf, icv, M);
       }
@@ -3449,7 +3759,7 @@ namespace getfem {
 
   struct ga_instruction_elementary_transformation_val
     : public ga_instruction_val, ga_instruction_elementary_transformation {
-    // Z(ndof,target_dim), coeff_in(Qmult,ndof) --> coeff_out --> t(target_dim*Qmult)
+    // Z(ndof,target_dim), coeff_in(Qmult,ndof) --> t(target_dim*Qmult)
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: variable value with elementary "
                     "transformation");
@@ -3469,7 +3779,7 @@ namespace getfem {
 
   struct ga_instruction_elementary_transformation_grad
     : public ga_instruction_grad, ga_instruction_elementary_transformation {
-    // Z(ndof,target_dim,N), coeff_in(Qmult,ndof) --> coeff_out --> t(target_dim*Qmult,N)
+    // Z(ndof,target_dim,N), coeff_in(Qmult,ndof) --> t(target_dim*Qmult,N)
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: gradient with elementary transformation");
       do_transformation();
@@ -3488,7 +3798,7 @@ namespace getfem {
 
   struct ga_instruction_elementary_transformation_hess
     : public ga_instruction_hess, ga_instruction_elementary_transformation {
-    // Z(ndof,target_dim,N*N), coeff_in(Qmult,ndof) --> coeff_out --> t(target_dim*Qmult,N,N)
+    // Z(ndof,target_dim,N,N), coeff_in(Qmult,ndof) --> t(target_dim*Qmult,N,N)
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: Hessian with elementary transformation");
       do_transformation();
@@ -3507,7 +3817,7 @@ namespace getfem {
 
   struct ga_instruction_elementary_transformation_diverg
     : public ga_instruction_diverg, ga_instruction_elementary_transformation {
-    // Z(ndof,target_dim,N), coeff_in(Qmult,ndof) --> coeff_out --> t(1)
+    // Z(ndof,target_dim,N), coeff_in(Qmult,ndof) --> t(1)
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: divergence with elementary transformation");
       do_transformation();
@@ -3671,7 +3981,7 @@ namespace getfem {
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: interpolated variable hessian");
       ga_instruction_interpolate::exec();
-      base_matrix v(qdim, ctx.N()*ctx.N());
+      base_matrix v(qdim, ctx.N()*ctx.N()); // To be optimized
       ctx.pf()->interpolation_hess(ctx, coeff, v, dim_type(qdim));
       gmm::copy(v.as_vector(), t.as_vector());
       return 0;
@@ -3831,7 +4141,7 @@ namespace getfem {
 
     void do_transformation(size_type n) {
       if (M.size() == 0 || icv != ctx.convex_num() || &mf != *mf_M) {
-        gmm::resize(M, n, n);
+        M.base_resize(n, n);
         *mf_M = &mf; icv = ctx.convex_num();
         elemtrans->give_transformation(mf, icv, M);
       }
@@ -3899,7 +4209,7 @@ namespace getfem {
   struct ga_instruction_elementary_transformation_hess_base
     : public ga_instruction_copy_hess_base,
              ga_instruction_elementary_transformation_base {
-    // Z(ndof,target_dim,N*N) --> t_in --> t_out(Qmult*ndof,Qmult*target_dim,N,N)
+    // Z(ndof,target_dim,N*N) --> t_out(Qmult*ndof,Qmult*target_dim,N,N)
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: Hessian of test functions with elementary "
                     "transformation");
@@ -3924,7 +4234,7 @@ namespace getfem {
   struct ga_instruction_elementary_transformation_diverg_base
     : public ga_instruction_copy_diverg_base,
              ga_instruction_elementary_transformation_base {
-    // Z(ndof,target_dim,N) --> t_in --> t_out(Qmult*ndof)
+    // Z(ndof,target_dim,N) --> t_out(Qmult*ndof)
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: divergence of test functions with elementary "
                     "transformation");
@@ -4027,13 +4337,24 @@ namespace getfem {
     const base_tensor &tc1;
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: tensor copy");
-      gmm::copy(tc1.as_vector(), t.as_vector());
+      std::copy(tc1.begin(), tc1.end(), t.begin());
+      // gmm::copy(tc1.as_vector(), t.as_vector());
       return 0;
     }
     ga_instruction_copy_tensor(base_tensor &t_, const base_tensor &tc1_)
       : t(t_), tc1(tc1_) {}
   };
 
+  struct ga_instruction_clear_tensor : public ga_instruction {
+    base_tensor &t;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: clear tensor");
+      std::fill(t.begin(), t.end(), scalar_type(0));
+      return 0;
+    }
+    ga_instruction_clear_tensor(base_tensor &t_) : t(t_) {}
+  };
+
   struct ga_instruction_copy_tensor_possibly_void : public ga_instruction {
     base_tensor &t;
     const base_tensor &tc1;
@@ -4082,12 +4403,11 @@ namespace getfem {
       GA_DEBUG_INFO("Instruction: Trace");
       GA_DEBUG_ASSERT(t.size()*n*n == tc1.size(), "Wrong sizes");
       size_type s = t.size() * (n+1);
-      base_tensor::iterator it = t.begin();
-      base_tensor::const_iterator it1 = tc1.begin();
+      auto it = t.begin();
+      auto it1 = tc1.begin();
       for (; it != t.end(); ++it, ++it1) {
-        *it = scalar_type(0);
-        base_tensor::const_iterator it2 = it1;
-        *it += *it2;
+        auto it2 = it1;
+        *it = *it2;
         for (size_type i = 1; i < n; ++i) { it2 += s; *it += *it2; }
       }
       return 0;
@@ -4126,7 +4446,8 @@ namespace getfem {
       return 0;
     }
 
-    ga_instruction_deviator(base_tensor &t_, const base_tensor &tc1_, size_type n_)
+    ga_instruction_deviator(base_tensor &t_, const base_tensor &tc1_,
+			    size_type n_)
       : t(t_), tc1(tc1_), n(n_) {}
   };
 
@@ -4272,7 +4593,7 @@ namespace getfem {
     base_tensor &t, &tc1;
     const scalar_type &c;
     virtual int exec() {
-      GA_DEBUG_INFO("Instruction: multiplication of a tensor by a scalar");
+      GA_DEBUG_INFO("Instruction: multiplication of a tensor by a scalar " << c);
       gmm::copy(gmm::scaled(tc1.as_vector(), c), t.as_vector());
       return 0;
     }
@@ -4355,7 +4676,7 @@ namespace getfem {
       : t(t_), tc1(tc1_), tc2(tc2_) {}
   };
 
-  // Performs Amij Bjk -> Cmik
+  // Performs Amij Bjk -> Cmik. To be optimized
   struct ga_instruction_matrix_mult : public ga_instruction {
     base_tensor &t, &tc1, &tc2;
     virtual int exec() {
@@ -4382,7 +4703,7 @@ namespace getfem {
       : t(t_), tc1(tc1_), tc2(tc2_) {}
   };
 
-  // Performs Amij Bnjk -> Cmnik
+  // Performs Amij Bnjk -> Cmnik. To be optimized
   struct ga_instruction_matrix_mult_spec : public ga_instruction {
     base_tensor &t, &tc1, &tc2;
     virtual int exec() {
@@ -4412,53 +4733,40 @@ namespace getfem {
   };
 
 
-  // Performs Ani Bmi -> Cmn for i index of size 2  Unroll loop test.
-  struct ga_instruction_reduction_2 : public ga_instruction {
-    base_tensor &t, &tc1, &tc2;
-    virtual int exec() {
-      GA_DEBUG_INFO("Instruction: reduction operation of size 2 optimized ");
-      size_type s1 = tc1.size()/2, s2 = tc2.size()/2;
-      GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error");
-
-      base_tensor::iterator it1=tc1.begin(), it2=tc2.begin(), it2end=it2 + s2;
-      for (base_tensor::iterator it = t.begin(); it != t.end(); ++it) {
-        *it = (*it1)*(*it2) + it1[s1] * it2[s2];
-        ++it2; if (it2 == it2end) { it2 = tc2.begin(), ++it1; }
-      }
-      return 0;
-    }
-    ga_instruction_reduction_2(base_tensor &t_, base_tensor &tc1_,
-                               base_tensor &tc2_)
-      : t(t_), tc1(tc1_), tc2(tc2_) {}
-  };
-
   // Performs Ani Bmi -> Cmn
   struct ga_instruction_reduction : public ga_instruction {
     base_tensor &t, &tc1, &tc2;
     size_type nn;
     virtual int exec() {
       GA_DEBUG_INFO("Instruction: reduction operation of size " << nn);
-      #ifdef GA_USES_BLAS
+#if GA_USES_BLAS
       int m = int(tc1.size()/nn), k = int(nn), n = int(tc2.size()/nn);
       int lda = m, ldb = n, ldc = m;
       char T = 'T', N = 'N';
       scalar_type alpha(1), beta(0);
       gmm::dgemm_(&N, &T, &m, &n, &k, &alpha, &(tc1[0]), &lda, &(tc2[0]), &ldb,
                   &beta, &(t[0]), &ldc);
-      #else
+#else
       size_type s1 = tc1.size()/nn, s2 = tc2.size()/nn;
       GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error");
 
-      base_tensor::iterator it1=tc1.begin(), it2=tc2.begin(), it2end=it2 + s2;
-      for (base_tensor::iterator it = t.begin(); it != t.end(); ++it) {
-        base_tensor::iterator it11 = it1, it22 = it2;
+      auto it1=tc1.begin(), it2=tc2.begin(), it2end=it2 + s2;
+      for (auto it = t.begin(); it != t.end(); ++it) {
+        auto it11 = it1, it22 = it2;
         scalar_type a = (*it11) * (*it22);
         for (size_type i = 1; i < nn; ++i)
           { it11 += s1; it22 += s2; a += (*it11) * (*it22); }
         *it = a;
         ++it2; if (it2 == it2end) { it2 = tc2.begin(), ++it1; }
       }
-      #endif
+      // auto it = t.begin(); // Unoptimized version.
+      // for (size_type i = 0; i < s1; ++i)
+      //  	for (size_type j = 0; j < s2; ++j, ++it) {
+      // 	  *it = scalar_type(0);
+      //  	  for (size_type k = 0; k < nn; ++k)
+      // 	    *it += tc1[i+k*s1] * tc2[j+k*s2];
+      // 	}
+#endif
       return 0;
     }
     ga_instruction_reduction(base_tensor &t_, base_tensor &tc1_,
@@ -4466,7 +4774,881 @@ namespace getfem {
       : t(t_), tc1(tc1_), tc2(tc2_), nn(n_) {}
   };
 
-  // Performs Amij Bnj -> Cmni
+  // Performs Ani Bmi -> Cmn
+  struct ga_instruction_reduction_opt0_2 : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    size_type n, q;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: reduction operation of size " << n*q <<
+		    " optimized for vectorized second tensor of type 2");
+      size_type nn = n*q, s1 = tc1.size()/nn, s2 = tc2.size()/nn, s2_q = s2/q;
+      size_type s1_qq = s1*q, s2_qq = s2*q;
+      GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error");
+      
+      auto it = t.begin(), it1 = tc1.begin();
+      for (size_type i = 0; i < s1; ++i, ++it1) {
+      	auto it2 = tc2.begin();
+       	for (size_type j = 0; j < s2_q; ++j) {
+	  if (j) it2+=q;
+      	  auto itt1 = it1;
+      	  for (size_type l = 0; l < q; ++l, ++it) {
+	    if (l) itt1 += s1;
+      	    auto ittt1 = itt1, ittt2 = it2;
+      	    *it = *ittt1 * (*ittt2);
+      	    for (size_type m = 1; m < n; ++m) {
+      	      ittt1 += s1_qq, ittt2 += s2_qq; *it += *ittt1 * (*ittt2);
+      	    }
+      	  }
+      	}
+      }
+      // base_tensor u = t;
+      // ga_instruction_reduction toto(t, tc1, tc2, n*q);
+      // toto.exec();
+      // GMM_ASSERT1(gmm::vect_dist2(t.as_vector(), u.as_vector()) < 1E-9, "Erroneous");
+      return 0;
+    }
+    ga_instruction_reduction_opt0_2(base_tensor &t_, base_tensor &tc1_,
+				    base_tensor &tc2_, size_type n_,
+				    size_type q_)
+      : t(t_), tc1(tc1_), tc2(tc2_), n(n_), q(q_) {}
+  };
+  
+  // Performs Ani Bmi -> Cmn
+  template <int N>
+  struct ga_instruction_reduction_opt0_2_unrolled : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    size_type q;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: unrolled reduction operation of size " << N*q
+		    << " optimized for vectorized second tensor of type 2");
+      size_type nn = N*q, s1 = tc1.size()/nn, s2 = tc2.size()/nn, s2_q = s2/q;
+      size_type s1_qq = s1*q, s2_qq = s2*q;
+      GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error");
+      
+      auto it = t.begin(), it1 = tc1.begin();
+      for (size_type i = 0; i < s1; ++i, ++it1) {
+      	auto it2 = tc2.begin();
+       	for (size_type j = 0; j < s2_q; ++j) {
+	  if (j) it2+=q;
+      	  auto itt1 = it1;
+      	  for (size_type l = 0; l < q; ++l, ++it) {
+	    if (l) itt1 += s1;
+      	    auto ittt1 = itt1, ittt2 = it2;
+      	    *it = *ittt1 * (*ittt2);
+      	    for (size_type m = 1; m < N; ++m) {
+      	      ittt1 += s1_qq, ittt2 += s2_qq; *it += *ittt1 * (*ittt2);
+      	    }
+      	  }
+      	}
+      }
+      return 0;
+    }
+    ga_instruction_reduction_opt0_2_unrolled(base_tensor &t_, base_tensor &tc1_,
+					     base_tensor &tc2_, size_type q_)
+      : t(t_), tc1(tc1_), tc2(tc2_), q(q_) {}
+  };
+
+  // Performs Ani Bmi -> Cmn
+  template <int N, int Q>
+  struct ga_instruction_reduction_opt0_2_dunrolled : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: unrolled reduction operation of size " << N*Q
+		    << " optimized for vectorized second tensor of type 2");
+      size_type s1 = tc1.size()/(N*Q), s2 = tc2.size()/(N*Q), s2_q = s2/Q;
+      size_type s1_qq = s1*Q, s2_qq = s2*Q;
+      GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error");
+      
+      auto it = t.begin(), it1 = tc1.begin();
+      for (size_type i = 0; i < s1; ++i, ++it1) {
+      	auto it2 = tc2.begin();
+       	for (size_type j = 0; j < s2_q; ++j) {
+	  if (j) it2+=Q;
+      	  auto itt1 = it1;
+      	  for (size_type l = 0; l < Q; ++l, ++it) {
+	    if (l) itt1 += s1;
+      	    auto ittt1 = itt1, ittt2 = it2;
+      	    *it = *ittt1 * (*ittt2);
+      	    for (size_type m = 1; m < N; ++m) {
+      	      ittt1 += s1_qq, ittt2 += s2_qq; *it += *ittt1 * (*ittt2);
+      	    }
+      	  }
+      	}
+      }
+      return 0;
+    }
+    ga_instruction_reduction_opt0_2_dunrolled
+    (base_tensor &t_, base_tensor &tc1_, base_tensor &tc2_)
+      : t(t_), tc1(tc1_), tc2(tc2_) {}
+  };
+
+  // Performs Ani Bmi -> Cmn
+  struct ga_instruction_reduction_opt2_0 : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    size_type n, q;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: reduction operation of size " << n*q <<
+		    " optimized for vectorized second tensor of type 2");
+      size_type nn = n*q, s1 = tc1.size()/nn, s2 = tc2.size()/nn;
+      size_type s1_q = s1/q, s1_qq = s1*q, s2_qq = s2*q;
+      GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error");
+
+      auto it = t.begin();
+      for (size_type i = 0; i < s1_q; ++i)  {
+	auto it1 = tc1.begin() + i*q;
+	for (size_type l = 0; l < q; ++l) {
+	  auto it2 = tc2.begin() + l*s2;
+	  for (size_type j = 0; j < s2; ++j, ++it, ++it2) {
+	    auto itt1 = it1, itt2 = it2;
+	    *it = *itt1 * (*itt2);
+	    for (size_type m = 1; m < n; ++m) {
+	      itt1 += s1_qq, itt2 += s2_qq; *it += *itt1 * (*itt2);
+	    }
+	  }
+	}
+      }
+      return 0;
+    }
+    ga_instruction_reduction_opt2_0(base_tensor &t_, base_tensor &tc1_,
+				    base_tensor &tc2_, size_type n_,
+				    size_type q_)
+      : t(t_), tc1(tc1_), tc2(tc2_), n(n_), q(q_) { }
+  };
+
+  // Performs Ani Bmi -> Cmn
+  template <int N>
+  struct ga_instruction_reduction_opt2_0_unrolled : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    size_type q;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: unrolled reduction operation of size " << N*q
+		    << " optimized for vectorized second tensor of type 2");
+      size_type nn = N*q, s1 = tc1.size()/nn, s2 = tc2.size()/nn;
+      size_type s1_q = s1/q, s1_qq = s1*q, s2_qq = s2*q;
+      GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error");
+
+      auto it = t.begin(), it1 = tc1.begin();
+      for (size_type i = 0; i < s1_q; ++i, it1 += q)  {
+	for (size_type l = 0; l < q; ++l) {
+	  auto it2 = tc2.begin() + l*s2;
+	  for (size_type j = 0; j < s2; ++j, ++it, ++it2) {
+	    auto itt1 = it1, itt2 = it2;
+	    *it = *itt1 * (*itt2);
+	    for (size_type m = 1; m < N; ++m) {
+	      itt1 += s1_qq, itt2 += s2_qq; *it += *itt1 * (*itt2);
+	    }
+	  }
+	}
+      }
+      return 0;
+    }
+    ga_instruction_reduction_opt2_0_unrolled(base_tensor &t_, base_tensor &tc1_,
+					     base_tensor &tc2_, size_type q_)
+      : t(t_), tc1(tc1_), tc2(tc2_), q(q_) {}
+  };
+
+  // Performs Ani Bmi -> Cmn
+  template <int N, int Q>
+  struct ga_instruction_reduction_opt2_0_dunrolled : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: unrolled reduction operation of size " << N*Q
+		    << " optimized for vectorized second tensor of type 2");
+      size_type s1 = tc1.size()/(N*Q), s2 = tc2.size()/(N*Q);
+      size_type s1_q = s1/Q, s1_qq = s1*Q, s2_qq = s2*Q;
+      GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error");
+
+      auto it = t.begin(), it1 = tc1.begin();
+      for (size_type i = 0; i < s1_q; ++i, it1 += Q)  {
+	for (size_type l = 0; l < Q; ++l) {
+	  auto it2 = tc2.begin() + l*s2;
+	  for (size_type j = 0; j < s2; ++j, ++it, ++it2) {
+	    auto itt1 = it1, itt2 = it2;
+	    *it = *itt1 * (*itt2);
+	    for (size_type m = 1; m < N; ++m) {
+	      itt1 += s1_qq, itt2 += s2_qq; *it += *itt1 * (*itt2);
+	    }
+	  }
+	}
+      }
+      return 0;
+    }
+    ga_instruction_reduction_opt2_0_dunrolled
+    (base_tensor &t_, base_tensor &tc1_, base_tensor &tc2_)
+      : t(t_), tc1(tc1_), tc2(tc2_) {}
+  };
+
+  // Performs Ani Bmi -> Cmn
+  struct ga_instruction_reduction_opt0_1 : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    size_type nn;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: reduction operation of size " << nn <<
+		    " optimized for vectorized second tensor of type 1");
+      size_type ss1=tc1.size(), s1 = ss1/nn, s2=tc2.size()/nn, s2_n=s2/nn;
+      
+      auto it = t.begin(), it1 = tc1.begin();
+      for (size_type i = 0; i < s1; ++i, ++it1) {
+	auto it2 = tc2.begin();
+	for (size_type j = 0; j < s2_n; ++j) {
+	  if (j) it2 += nn;
+	  auto itt1 = it1;
+	  *it++ = (*itt1) * (*it2);
+	  for (size_type k = 1; k < nn; ++k)
+	    { itt1 += s1; *it++ = (*itt1) * (*it2); }
+	}
+      }
+      return 0;
+    }
+    ga_instruction_reduction_opt0_1(base_tensor &t_, base_tensor &tc1_,
+				    base_tensor &tc2_, size_type n_)
+      : t(t_), tc1(tc1_), tc2(tc2_), nn(n_) {}
+  };
+
+  template<int N> inline void reduc_elem_unrolled_opt1_
+  (const base_vector::iterator &it, const base_vector::iterator &it1,
+   scalar_type a, size_type s1) {
+    it[N-1] = it1[(N-1)*s1] * a;
+    reduc_elem_unrolled_opt1_<N-1>(it, it1, a, s1);
+  }
+  template<> inline void reduc_elem_unrolled_opt1_<1>
+  (const base_vector::iterator &it, const base_vector::iterator &it1,
+   scalar_type a, size_type /* s1 */)
+  { *it = (*it1) * a; }
+
+  // Performs Ani Bmi -> Cmn
+  template <int N>
+  struct ga_instruction_reduction_opt0_1_unrolled : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: unrolled reduction operation of size " << N
+		    << " optimized for vectorized second tensor of type 1");
+      size_type s1 = tc1.size()/N, s2 = tc2.size()/N;
+      auto it = t.begin(), it1 = tc1.begin();
+      for (size_type i = 0; i < s1; ++i, ++it1) {
+	auto it2 = tc2.begin(), it2e = it2 + s2;
+	for (; it2 != it2e; it2 += N, it += N)
+	  reduc_elem_unrolled_opt1_<N>(it, it1, *it2, s1);
+      }
+      return 0;
+    }
+    ga_instruction_reduction_opt0_1_unrolled(base_tensor &t_, base_tensor &tc1_,
+					     base_tensor &tc2_)
+      : t(t_), tc1(tc1_), tc2(tc2_) {}
+  };
+
+  // Performs Ani Bmi -> Cmn
+  struct ga_instruction_reduction_opt1_1 : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    size_type nn;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: reduction operation of size " << nn <<
+		    " optimized for both vectorized tensor of type 1");
+      size_type s1 = tc1.size()/nn, s2 = tc2.size()/nn, s2_1 = s2+1;
+      GA_DEBUG_ASSERT(t.size() == s2*s1, "Internal error");
+      size_type ss1 = s1/nn, ss2 = s2/nn;
+
+      // std::fill(t.begin(), t.end(), scalar_type(0)); // Factorized
+      auto it2 = tc2.begin();
+      for (size_type j = 0; j < ss2; ++j) {
+	if (j) it2 += nn;
+	auto it1 = tc1.begin(), it = t.begin() + j*nn;
+	for (size_type i = 0; i < ss1; ++i) {
+	  if (i) { it1 += nn, it += s2*nn; }
+       	  scalar_type a = (*it1) * (*it2);
+	  auto itt = it;
+	  *itt = a; itt += s2_1; *itt = a;
+       	  for (size_type k = 2; k < nn; ++k) { itt += s2_1; *itt = a; }
+       	}
+      }      
+      return 0;
+    }
+    ga_instruction_reduction_opt1_1(base_tensor &t_, base_tensor &tc1_,
+				    base_tensor &tc2_, size_type n_)
+      : t(t_), tc1(tc1_), tc2(tc2_), nn(n_) {}
+  };
+
+  
+
+  template<int N> inline scalar_type reduc_elem_unrolled__
+  (base_tensor::iterator &it1, base_tensor::iterator &it2,
+   size_type s1, size_type s2) {
+    return (it1[(N-1)*s1])*(it2[(N-1)*s2])
+      + reduc_elem_unrolled__<N-1>(it1, it2, s1, s2);
+  }
+  template<> inline scalar_type reduc_elem_unrolled__<1>
+  (base_tensor::iterator &it1, base_tensor::iterator &it2,
+   size_type /*s1*/, size_type /*s2*/)
+  { return (*it1)*(*it2); }
+
+  // Performs Ani Bmi -> Cmn. Unrolled operation.
+  template<int N> struct ga_instruction_reduction_unrolled
+    : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: unrolled reduction operation of size " << N);
+      size_type s1 = tc1.size()/N, s2 = tc2.size()/N;
+      GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error, " << t.size()
+                      << " != " << s1 << "*" << s2);
+      base_tensor::iterator it1=tc1.begin(), it2=tc2.begin(), it2end=it2 + s2;
+      for (base_tensor::iterator it = t.begin(); it != t.end(); ++it) {
+        *it = reduc_elem_unrolled__<N>(it1, it2, s1, s2);
+        ++it2; if (it2 == it2end) { it2 = tc2.begin(), ++it1; }
+      }
+      return 0;
+    }
+    ga_instruction_reduction_unrolled(base_tensor &t_, base_tensor &tc1_,
+                                      base_tensor &tc2_)
+      : t(t_), tc1(tc1_), tc2(tc2_) {}
+  };
+
+  template<int N, int S2> inline void reduc_elem_d_unrolled__
+  (base_tensor::iterator &it, base_tensor::iterator &it1,
+   base_tensor::iterator &it2, size_type s1, size_type s2)  {
+    *it++ = reduc_elem_unrolled__<N>(it1, it2, s1, s2);
+    reduc_elem_d_unrolled__<N, S2-1>(it, it1, ++it2, s1, s2);
+  }
+  // A Repeated definition is following because partial specialization
+  // of functions is not allowed in C++ for the moment.
+  // The gain in assembly time is small compared to the simply unrolled version
+  template<> inline void reduc_elem_d_unrolled__<1, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<2, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<3, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<4, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<5, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<6, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<7, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<8, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<9, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<10, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<11, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<12, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<13, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<14, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<15, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+  template<> inline void reduc_elem_d_unrolled__<16, 0>
+  (base_tensor::iterator &/* it */, base_tensor::iterator &/* it1 */,
+   base_tensor::iterator &/* it2 */, size_type /* s1 */, size_type /* s2 */) { }
+
+  // Performs Ani Bmi -> Cmn. Automatically doubly unrolled operation
+  // (for uniform meshes).
+  template<int N, int S2> struct ga_ins_red_d_unrolled
+    : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: doubly unrolled reduction operation of size "
+                    << S2 << "x" << N);
+      size_type s1 = tc1.size()/N, s2 = tc2.size()/N;
+      GA_DEBUG_ASSERT(s2 == S2, "Internal error");
+      GA_DEBUG_ASSERT(t.size() == s1*s2, "Internal error, " << t.size()
+                      << " != " << s1 << "*" << s2);
+      base_tensor::iterator it = t.begin(), it1 = tc1.begin();
+      for (size_type ii = 0; ii < s1; ++ii, ++it1) {
+        base_tensor::iterator it2 = tc2.begin();
+        reduc_elem_d_unrolled__<N, S2>(it, it1, it2, s1, s2);
+      }
+      GA_DEBUG_ASSERT(it == t.end(), "Internal error");
+      return 0;
+    }
+    ga_ins_red_d_unrolled(base_tensor &t_, base_tensor &tc1_, base_tensor &tc2_)
+      : t(t_), tc1(tc1_), tc2(tc2_) {}
+  };
+
+
+  pga_instruction ga_instruction_reduction_switch
+  (assembly_tensor &t_, assembly_tensor &tc1_, assembly_tensor &tc2_,
+   size_type n, bool &to_clear) {
+    base_tensor &t = t_.tensor(), &tc1 = tc1_.tensor(), &tc2 = tc2_.tensor();
+   
+    if (tc1_.sparsity() == 1 && tc2_.sparsity() == 1 &&
+	tc1_.qdim() == n && tc2_.qdim() == n) {
+      to_clear = true;
+      t_.set_sparsity(10, tc1_.qdim());
+      return std::make_shared<ga_instruction_reduction_opt1_1>(t, tc1, tc2, n);
+    }
+
+    if (tc2_.sparsity() == 1) {
+      switch(n) {
+      case 2:
+	return std::make_shared<ga_instruction_reduction_opt0_1_unrolled<2>>
+	  (t, tc1, tc2);
+      case 3:
+	return std::make_shared<ga_instruction_reduction_opt0_1_unrolled<3>>
+	  (t, tc1, tc2);
+      case 4:
+	return std::make_shared<ga_instruction_reduction_opt0_1_unrolled<4>>
+	  (t, tc1, tc2);
+      case 5:
+	return std::make_shared<ga_instruction_reduction_opt0_1_unrolled<5>>
+	  (t, tc1, tc2);
+      default:
+	return std::make_shared<ga_instruction_reduction_opt0_1>(t,tc1,tc2, n);
+      }
+    }
+        if (tc2_.sparsity() == 2) {
+      size_type q2 = tc2.sizes()[1];
+      size_type n2 = (tc2.sizes().size() > 2) ? tc2.sizes()[1] : 1;
+      if (n2*q2 == n) {
+	switch (n2) {
+	case 1:
+	  switch (q2) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<1,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<1,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<1,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<1>>
+	      (t, tc1, tc2, q2);
+	  }
+	case 2:
+	  switch (q2) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<2,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<2,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<2,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<2>>
+	      (t, tc1, tc2, q2);
+	  }
+	case 3:
+	  switch (q2) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<3,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<3,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<3,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<3>>
+	      (t, tc1, tc2, q2);
+	  }
+	case 4:
+	  return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<4>>
+	    (t, tc1, tc2, q2);
+	case 5:
+	  return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<5>>
+	    (t, tc1, tc2, q2);
+	default:
+	  return std::make_shared<ga_instruction_reduction_opt0_2>
+	    (t,tc1,tc2,n2,q2);
+	}
+      }
+    }
+    if (tc1_.sparsity() == 2) {
+      size_type q1 = tc1.sizes()[1];
+      size_type n1 = (tc1.sizes().size() > 2) ? tc1.sizes()[1] : 1;
+      if (n1*q1 == n) {
+	switch (n1) {
+	case 1:
+	  switch (q1) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<1,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<1,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<1,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<1>>
+	      (t, tc1, tc2, q1);
+	  }
+	case 2:
+	  switch (q1) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<2,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<2,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<2,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<2>>
+	      (t, tc1, tc2, q1);
+	  }
+	case 3:
+	  switch (q1) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<3,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<3,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<3,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<3>>
+	      (t, tc1, tc2, q1);
+	  }
+	  return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<3>>
+	    (t, tc1, tc2, q1);
+	case 4:
+	  return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<4>>
+	    (t, tc1, tc2, q1);
+	case 5:
+	  return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<5>>
+	    (t, tc1, tc2, q1);
+	default:
+	  return std::make_shared<ga_instruction_reduction_opt2_0>
+	    (t,tc1,tc2, n1, q1);
+	}
+      }
+    }
+
+    switch(n) {
+    case  2 : return std::make_shared<ga_instruction_reduction_unrolled< 2>>
+	             (t, tc1, tc2);
+    case  3 : return std::make_shared<ga_instruction_reduction_unrolled< 3>>
+	             (t, tc1, tc2);
+    case  4 : return std::make_shared<ga_instruction_reduction_unrolled< 4>>
+	             (t, tc1, tc2);
+    case  5 : return std::make_shared<ga_instruction_reduction_unrolled< 5>>
+                     (t, tc1, tc2);
+    case  6 : return std::make_shared<ga_instruction_reduction_unrolled< 6>>
+                     (t, tc1, tc2);
+    case  7 : return std::make_shared<ga_instruction_reduction_unrolled< 7>>
+                     (t, tc1, tc2);
+    case  8 : return std::make_shared<ga_instruction_reduction_unrolled< 8>>
+                     (t, tc1, tc2);
+    case  9 : return std::make_shared<ga_instruction_reduction_unrolled< 9>>
+                     (t, tc1, tc2);
+    case 10 : return std::make_shared<ga_instruction_reduction_unrolled<10>>
+                     (t, tc1, tc2);
+    case 11 : return std::make_shared<ga_instruction_reduction_unrolled<11>>
+                     (t, tc1, tc2);
+    case 12 : return std::make_shared<ga_instruction_reduction_unrolled<12>>
+                     (t, tc1, tc2);
+    case 13 : return std::make_shared<ga_instruction_reduction_unrolled<13>>
+                     (t, tc1, tc2);
+    case 14 : return std::make_shared<ga_instruction_reduction_unrolled<14>>
+                     (t, tc1, tc2);
+    case 15 : return std::make_shared<ga_instruction_reduction_unrolled<15>>
+	             (t, tc1, tc2);
+    case 16 : return std::make_shared<ga_instruction_reduction_unrolled<16>>
+	             (t, tc1, tc2);
+    default : return std::make_shared<ga_instruction_reduction>
+	             (t, tc1, tc2, n);
+    }
+  }
+
+  pga_instruction  ga_uniform_instruction_reduction_switch
+  (assembly_tensor &t_, assembly_tensor &tc1_, assembly_tensor &tc2_,
+   size_type n, bool &to_clear) {
+    base_tensor &t = t_.tensor(), &tc1 = tc1_.tensor(), &tc2 = tc2_.tensor();
+
+    if (tc1_.sparsity() == 1 && tc2_.sparsity() == 1 &&
+	tc1_.qdim() == n && tc2_.qdim() == n) {
+      to_clear = true;
+      t_.set_sparsity(10, tc1_.qdim());
+      return std::make_shared<ga_instruction_reduction_opt1_1>(t,tc1,tc2,n);
+    }
+    if (tc2_.sparsity() == 1) {
+      switch(n) {
+      case 2:
+	return std::make_shared<ga_instruction_reduction_opt0_1_unrolled<2>>
+	  (t, tc1, tc2);
+      case 3:
+	return std::make_shared<ga_instruction_reduction_opt0_1_unrolled<3>>
+	  (t, tc1, tc2);
+      case 4:
+	return std::make_shared<ga_instruction_reduction_opt0_1_unrolled<4>>
+	  (t, tc1, tc2);
+      case 5:
+	return std::make_shared<ga_instruction_reduction_opt0_1_unrolled<5>>
+	  (t, tc1, tc2);
+      default:
+	return std::make_shared<ga_instruction_reduction_opt0_1>(t,tc1,tc2, n);
+      }
+    }
+    if (tc2_.sparsity() == 2) {
+      size_type q2 = tc2.sizes()[1];
+      size_type n2 = (tc2.sizes().size() > 2) ? tc2.sizes()[1] : 1;
+      if (n2*q2 == n) {
+	switch (n2) {
+	case 1:
+	  switch (q2) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<1,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<1,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<1,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<1>>
+	      (t, tc1, tc2, q2);
+	  }
+	case 2:
+	  switch (q2) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<2,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<2,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<2,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<2>>
+	      (t, tc1, tc2, q2);
+	  }
+	case 3:
+	  switch (q2) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<3,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<3,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt0_2_dunrolled<3,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<3>>
+	      (t, tc1, tc2, q2);
+	  }
+	case 4:
+	  return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<4>>
+	    (t, tc1, tc2, q2);
+	case 5:
+	  return std::make_shared<ga_instruction_reduction_opt0_2_unrolled<5>>
+	    (t, tc1, tc2, q2);
+	default:
+	  return std::make_shared<ga_instruction_reduction_opt0_2>
+	    (t,tc1,tc2,n2,q2);
+	}
+      }
+    }
+    if (tc1_.sparsity() == 2) {
+      size_type q1 = tc1.sizes()[1];
+      size_type n1 = (tc1.sizes().size() > 2) ? tc1.sizes()[1] : 1;
+      if (n1*q1 == n) {
+	switch (n1) {
+	case 1:
+	  switch (q1) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<1,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<1,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<1,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<1>>
+	      (t, tc1, tc2, q1);
+	  }
+	case 2:
+	  switch (q1) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<2,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<2,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<2,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<2>>
+	      (t, tc1, tc2, q1);
+	  }
+	case 3:
+	  switch (q1) {
+	  case 2:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<3,2>>
+	      (t, tc1, tc2);
+	  case 3:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<3,3>>
+	      (t, tc1, tc2);
+	  case 4:
+	    return
+	      std::make_shared<ga_instruction_reduction_opt2_0_dunrolled<3,4>>
+	      (t, tc1, tc2);
+	  default :
+	    return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<3>>
+	      (t, tc1, tc2, q1);
+	  }
+	  return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<3>>
+	    (t, tc1, tc2, q1);
+	case 4:
+	  return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<4>>
+	    (t, tc1, tc2, q1);
+	case 5:
+	  return std::make_shared<ga_instruction_reduction_opt2_0_unrolled<5>>
+	    (t, tc1, tc2, q1);
+	default:
+	  return std::make_shared<ga_instruction_reduction_opt2_0>
+	    (t,tc1,tc2, n1, q1);
+	}
+      }
+    }
+
+    // Only specialized for certain values
+    size_type s2 = tc2.size()/n;
+    switch(s2) {
+    case 1 :
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,1>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,1>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,1>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    case 2 :
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,2>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,2>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,2>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    case 3 :
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,3>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,3>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,3>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    case 4 :
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,4>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,4>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,4>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    case 5 :
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,5>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,5>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,5>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    case 6 :
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,6>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,6>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,6>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    case 7 :
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,7>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,7>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,7>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    case 8 :
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,8>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,8>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,8>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    case 9 :
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,9>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,9>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,9>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    case 10:
+      switch(n) {
+      case 2: return std::make_shared<ga_ins_red_d_unrolled<2,10>>(t, tc1, tc2);
+      case 3: return std::make_shared<ga_ins_red_d_unrolled<3,10>>(t, tc1, tc2);
+      case 4: return std::make_shared<ga_ins_red_d_unrolled<4,10>>(t, tc1, tc2);
+      default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+      }
+    default: return ga_instruction_reduction_switch(t_,tc1_,tc2_,n,to_clear);
+    }
+  }
+
+
+  // Performs Amij Bnj -> Cmni. To be optimized.
   struct ga_instruction_spec_reduction : public ga_instruction {
     base_tensor &t, &tc1, &tc2;
     size_type nn;
@@ -4491,7 +5673,7 @@ namespace getfem {
       : t(t_), tc1(tc1_), tc2(tc2_), nn(n_) {}
   };
 
-  // Performs Amik Bnjk -> Cmnij
+  // Performs Amik Bnjk -> Cmnij. To be optimized.
   struct ga_instruction_spec2_reduction : public ga_instruction {
     base_tensor &t, &tc1, &tc2;
     size_type nn;
@@ -4517,7 +5699,7 @@ namespace getfem {
       : t(t_), tc1(tc1_), tc2(tc2_), nn(n_) {}
   };
 
-  // Performs Aij Bjk -> Cijkl
+  // Performs Aij Bkl -> Cijkl
   struct ga_instruction_simple_tmult : public ga_instruction {
     base_tensor &t, &tc1, &tc2;
     virtual int exec() {
@@ -4536,7 +5718,80 @@ namespace getfem {
       : t(t_), tc1(tc1_), tc2(tc2_) {}
   };
 
-  // Performs Ami Bnj -> Cmnij
+  template<int S1> inline void tmult_elem_unrolled__
+  (base_tensor::iterator &it, base_tensor::iterator &it1,
+   base_tensor::iterator &it2) {
+    *it++ = (*it1++)*(*it2);
+    tmult_elem_unrolled__<S1-1>(it, it1, it2);
+  }
+  template<> inline void tmult_elem_unrolled__<0>
+  (base_tensor::iterator &/*it*/, base_tensor::iterator &/*it1*/,
+   base_tensor::iterator &/*it2*/) { }
+
+  // Performs Aij Bkl -> Cijkl, partially unrolled version
+  template<int S1> struct ga_instruction_simple_tmult_unrolled
+    : public ga_instruction {
+    base_tensor &t, &tc1, &tc2;
+    virtual int exec() {
+      size_type s2 = tc2.size();
+      GA_DEBUG_INFO("Instruction: simple tensor product, unrolled with "
+                    << tc1.size() << " operations");
+      GA_DEBUG_ASSERT(t.size() == tc1.size() * s2, "Wrong sizes");
+      GA_DEBUG_ASSERT(tc1.size() == S1, "Wrong sizes");
+
+      base_tensor::iterator it = t.begin(), it2 = tc2.begin();
+      for (size_type ii = 0; ii < s2; ++ii, ++it2) {
+        base_tensor::iterator it1 = tc1.begin();
+        tmult_elem_unrolled__<S1>(it, it1, it2);
+      }
+      GA_DEBUG_ASSERT(it == t.end(), "Internal error");
+      return 0;
+    }
+    ga_instruction_simple_tmult_unrolled(base_tensor &t_, base_tensor &tc1_,
+                                         base_tensor &tc2_)
+      : t(t_), tc1(tc1_), tc2(tc2_) {}
+  };
+
+  pga_instruction  ga_uniform_instruction_simple_tmult
+  (base_tensor &t, base_tensor &tc1, base_tensor &tc2) {
+    switch(tc1.size()) {
+    case  2 : return std::make_shared<ga_instruction_simple_tmult_unrolled< 2>>
+                     (t, tc1, tc2);
+    case  3 : return std::make_shared<ga_instruction_simple_tmult_unrolled< 3>>
+                     (t, tc1, tc2);
+    case  4 : return std::make_shared<ga_instruction_simple_tmult_unrolled< 4>>
+                     (t, tc1, tc2);
+    case  5 : return std::make_shared<ga_instruction_simple_tmult_unrolled< 5>>
+                     (t, tc1, tc2);
+    case  6 : return std::make_shared<ga_instruction_simple_tmult_unrolled< 6>>
+                     (t, tc1, tc2);
+    case  7 : return std::make_shared<ga_instruction_simple_tmult_unrolled< 7>>
+                     (t, tc1, tc2);
+    case  8 : return std::make_shared<ga_instruction_simple_tmult_unrolled< 8>>
+                     (t, tc1, tc2);
+    case  9 : return std::make_shared<ga_instruction_simple_tmult_unrolled< 9>>
+                     (t, tc1, tc2);
+    case 10 : return std::make_shared<ga_instruction_simple_tmult_unrolled<10>>
+                     (t, tc1, tc2);
+    case 11 : return std::make_shared<ga_instruction_simple_tmult_unrolled<11>>
+                     (t, tc1, tc2);
+    case 12 : return std::make_shared<ga_instruction_simple_tmult_unrolled<12>>
+                     (t, tc1, tc2);
+    case 13 : return std::make_shared<ga_instruction_simple_tmult_unrolled<13>>
+                     (t, tc1, tc2);
+    case 14 : return std::make_shared<ga_instruction_simple_tmult_unrolled<14>>
+                     (t, tc1, tc2);
+    case 15 : return std::make_shared<ga_instruction_simple_tmult_unrolled<15>>
+                     (t, tc1, tc2);
+    case 16 : return std::make_shared<ga_instruction_simple_tmult_unrolled<16>>
+                     (t, tc1, tc2);
+    default : return std::make_shared<ga_instruction_simple_tmult>
+                     (t, tc1, tc2);
+    }
+  }
+
+
+  // Performs Ami Bnj -> Cmnij. To be optimized.
   struct ga_instruction_spec_tmult : public ga_instruction {
     base_tensor &t, &tc1, &tc2;
     size_type s1_2, s2_2;
@@ -4561,7 +5816,7 @@ namespace getfem {
       : t(t_), tc1(tc1_), tc2(tc2_), s1_2(s1_2_), s2_2(s2_2_) {}
   };
 
-  // Performs Ai Bmj -> Cmij
+  // Performs Ai Bmj -> Cmij. To be optimized.
   struct ga_instruction_spec2_tmult : public ga_instruction {
     base_tensor &t, &tc1, &tc2;
     virtual int exec() {
@@ -4613,7 +5868,8 @@ namespace getfem {
       for (size_type i = 0; i < components.size(); ++i) {
         const base_tensor &t1 = *(components[i]);
         if (t1.size() > 1) {
-          GA_DEBUG_ASSERT(t1.size() == s, "Wrong sizes, " << t1.size() << " != " << s);
+          GA_DEBUG_ASSERT(t1.size() == s, "Wrong sizes, " << t1.size()
+			  << " != " << s);
           for (size_type j = 0; j < s; ++j) *it++ = t1[j];
         } else {
           for (size_type j = 0; j < s; ++j) *it++ = t1[0];
@@ -4621,8 +5877,8 @@ namespace getfem {
       }
       return 0;
     }
-    ga_instruction_c_matrix_with_tests(base_tensor &t_,
-                                       const std::vector<const base_tensor *>  &components_)
+    ga_instruction_c_matrix_with_tests
+    (base_tensor &t_, const std::vector<const base_tensor *>  &components_)
       : t(t_), components(components_) {}
   };
 
@@ -4909,9 +6165,9 @@ namespace getfem {
                                       inin.derivatives, compute_der);
       if (inin.pt_type) {
         if (cv != size_type(-1)) {
-          bgeot::vectors_to_base_matrix(inin.G, (inin.m)->points_of_convex(cv));
-          inin.ctx = fem_interpolation_context((inin.m)->trans_of_convex(cv),
-                                               0, P_ref, inin.G, cv, face_num);
+          inin.m->points_of_convex(cv, inin.G);
+          inin.ctx.change((inin.m)->trans_of_convex(cv),
+                          0, P_ref, inin.G, cv, face_num);
           inin.has_ctx = true;
           if (face_num != short_type(-1)) {
             inin.Normal = bgeot::compute_normal(inin.ctx, face_num);
@@ -4920,12 +6176,12 @@ namespace getfem {
             inin.Normal.resize(0);
           inin.pt_y = inin.ctx.xreal();
         } else {
-          inin.ctx = fem_interpolation_context();
+          inin.ctx.invalid_convex_num();
           inin.pt_y = P_ref;
           inin.has_ctx = false;
         }
       } else {
-        inin.ctx = fem_interpolation_context();
+        inin.ctx.invalid_convex_num();
         inin.Normal.resize(0);
         inin.pt_y.resize(0);
         inin.has_ctx = false;
@@ -4959,14 +6215,14 @@ namespace getfem {
       if (ipt == 0) {
         if (!(ctx.have_pgp()) || !pai || pai->is_built_on_the_fly()
             || cancel_optimization) {
-          inin.ctx = fem_interpolation_context();
+          inin.ctx.invalid_convex_num();
         } else {
           // Test if the situation has already been encountered
           size_type cv = ctx.convex_num();
           short_type f = ctx.face_num();
           auto adj_face = m.adjacent_face(cv, f);
           if (adj_face.cv == size_type(-1)) {
-            inin.ctx = fem_interpolation_context();
+            inin.ctx.invalid_convex_num();
           } else {
             gauss_pt_corresp gpc;
             gpc.pgt1 = m.trans_of_convex(cv);
@@ -5004,7 +6260,7 @@ namespace getfem {
               const bgeot::stored_point_tab
                 &spt = *(pai->pintegration_points());
               base_matrix G;
-              bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
+              m.points_of_convex(cv, G);
               fem_interpolation_context ctx_x(gpc.pgt1, 0, spt[0], G, cv, f);
               std::vector<base_node> P_ref(nbpt);
 
@@ -5018,11 +6274,9 @@ namespace getfem {
               pspt = store_point_tab(P_ref);
               neighbour_corresp[gpc] = pspt;
             }
-            bgeot::vectors_to_base_matrix(inin.G,
-                                          m.points_of_convex(adj_face.cv));
+            m.points_of_convex(adj_face.cv, inin.G);
             bgeot::pgeotrans_precomp pgp = gp_pool(gpc.pgt2, pspt);
-            inin.ctx = fem_interpolation_context(pgp, 0, 0, inin.G,
-                                                 adj_face.cv, adj_face.f);
+            inin.ctx.change(pgp, 0, 0, inin.G, adj_face.cv, adj_face.f);
           }
         }
       }
@@ -5045,10 +6299,9 @@ namespace getfem {
                                         inin.derivatives, false);
         if (inin.pt_type) {
           if (cv != size_type(-1)) {
-            bgeot::vectors_to_base_matrix(inin.G,
-                                          (inin.m)->points_of_convex(cv));
-            inin.ctx = fem_interpolation_context((inin.m)->trans_of_convex(cv),
-                                                 0, P_ref, inin.G, cv, face_num);
+            inin.m->points_of_convex(cv, inin.G);
+            inin.ctx.change((inin.m)->trans_of_convex(cv),
+                            0, P_ref, inin.G, cv, face_num);
             inin.has_ctx = true;
             if (face_num != short_type(-1)) {
               inin.Normal = bgeot::compute_normal(inin.ctx, face_num);
@@ -5057,12 +6310,12 @@ namespace getfem {
               inin.Normal.resize(0);
             inin.pt_y = inin.ctx.xreal();
           } else {
-            inin.ctx = fem_interpolation_context();
+            inin.ctx.invalid_convex_num();
             inin.pt_y = P_ref;
             inin.has_ctx = false;
           }
         } else {
-          inin.ctx = fem_interpolation_context();
+          inin.ctx.invalid_convex_num();
           inin.Normal.resize(0);
           inin.pt_y.resize(0);
           inin.has_ctx = false;
@@ -5087,7 +6340,7 @@ namespace getfem {
     base_tensor &t;
     scalar_type &E, &coeff;
      virtual int exec() {
-      GA_DEBUG_INFO("Instruction: scalar term assembly\n");
+      GA_DEBUG_INFO("Instruction: scalar term assembly");
       E += t[0] * coeff;
       return 0;
      }
@@ -5103,31 +6356,64 @@ namespace getfem {
     const gmm::sub_interval &Ir, &In;
     const mesh_fem *mfn, **mfg;
     scalar_type &coeff;
+    const size_type &nbpt, &ipt;
+    base_vector elem;
+    bool interpolate;
     virtual int exec() {
-      GA_DEBUG_INFO("Instruction: vector term assembly for fem variable\n");
-      const mesh_fem &mf = *(mfg ? *mfg : mfn);
-      GMM_ASSERT1(&mf, "Internal error");
-      const gmm::sub_interval &I = mf.is_reduced() ? Ir : In;
-      base_vector &V = mf.is_reduced() ? Vr : Vn;
-      size_type cv_1 = ctx.is_convex_num_valid()
-        ? ctx.convex_num() : mf.convex_index().first_true();
-      GA_DEBUG_ASSERT(V.size() >= I.first() + mf.nb_basic_dof(),
-                      "Bad assembly vector size");
-      mesh_fem::ind_dof_ct ct = mf.ind_basic_dof_of_element(cv_1);
-      for (size_type i = 0; i < ct.size(); ++i)
-        V[I.first()+ct[i]] += t[i] * coeff;
+      GA_DEBUG_INFO("Instruction: vector term assembly for fem variable");
+      if (ipt == 0 || interpolate) {
+        elem.resize(t.size());
+	auto itt = t.begin(); auto it = elem.begin(), ite = elem.end();
+	size_type nd = ((t.size()) >> 2);
+	for (size_type i = 0; i < nd; ++i) {
+	  *it++ = (*itt++) * coeff; *it++ = (*itt++) * coeff;
+	  *it++ = (*itt++) * coeff; *it++ = (*itt++) * coeff;
+	}
+	for (; it != ite;) *it++ = (*itt++) * coeff;
+        // gmm::copy(gmm::scaled(t.as_vector(), coeff), elem);
+      } else {
+	auto itt = t.begin(); auto it = elem.begin(), ite = elem.end();
+	size_type nd = ((t.size()) >> 2);
+	for (size_type i = 0; i < nd; ++i) {
+	  *it++ += (*itt++) * coeff; *it++ += (*itt++) * coeff;
+	  *it++ += (*itt++) * coeff; *it++ += (*itt++) * coeff;
+	}
+	for (; it != ite;) *it++ += (*itt++) * coeff;
+        // gmm::add(gmm::scaled(t.as_vector(), coeff), elem);
+      }
+      if (ipt == nbpt-1 || interpolate) {
+        const mesh_fem &mf = *(mfg ? *mfg : mfn);
+        GMM_ASSERT1(mfg ? *mfg : mfn, "Internal error");
+        const gmm::sub_interval &I = mf.is_reduced() ? Ir : In;
+        base_vector &V = mf.is_reduced() ? Vr : Vn;
+        if (!(ctx.is_convex_num_valid())) return 0;
+        size_type cv_1 = ctx.convex_num();
+        // size_type cv_1 = ctx.is_convex_num_valid()
+        //   ? ctx.convex_num() : mf.convex_index().first_true();
+        GA_DEBUG_ASSERT(V.size() >= I.first() + mf.nb_basic_dof(),
+                        "Bad assembly vector size");
+        auto &ct = mf.ind_scalar_basic_dof_of_element(cv_1);
+        size_type qmult = mf.get_qdim();
+        if (qmult > 1) qmult /= mf.fem_of_element(cv_1)->target_dim();
+	size_type ifirst = I.first();
+	auto ite = elem.begin();
+	for (auto itc = ct.begin(); itc != ct.end(); ++itc)
+	  for (size_type q = 0; q < qmult; ++q)
+	    V[ifirst+(*itc)+q] += *ite++;
+        GMM_ASSERT1(ite == elem.end(), "Internal error");
+      }
       return 0;
     }
-    ga_instruction_fem_vector_assembly(base_tensor &t_, base_vector &Vr_,
-                                       base_vector &Vn_,
-                                       const fem_interpolation_context &ctx_,
-                                       const gmm::sub_interval &Ir_,
-                                       const gmm::sub_interval &In_,
-                                       const mesh_fem *mfn_,
-                                       const mesh_fem **mfg_,
-                                       scalar_type &coeff_)
-      : t(t_), Vr(Vr_), Vn(Vn_), ctx(ctx_), Ir(Ir_), In(In_), mfn(mfn_),
-        mfg(mfg_), coeff(coeff_) {}
+    ga_instruction_fem_vector_assembly
+    (base_tensor &t_, base_vector &Vr_, base_vector &Vn_,
+     const fem_interpolation_context &ctx_,
+     const gmm::sub_interval &Ir_, const gmm::sub_interval &In_,
+     const mesh_fem *mfn_, const mesh_fem **mfg_,
+     scalar_type &coeff_,
+     const size_type &nbpt_, const size_type &ipt_, bool interpolate_)
+    : t(t_), Vr(Vr_), Vn(Vn_), ctx(ctx_), Ir(Ir_), In(In_), mfn(mfn_),
+      mfg(mfg_), coeff(coeff_), nbpt(nbpt_), ipt(ipt_),
+      interpolate(interpolate_) {}
   };
 
   struct ga_instruction_vector_assembly : public ga_instruction {
@@ -5137,7 +6423,7 @@ namespace getfem {
     scalar_type &coeff;
      virtual int exec() {
       GA_DEBUG_INFO("Instruction: vector term assembly for "
-                    "fixed size variable\n");
+                    "fixed size variable");
       gmm::add(gmm::scaled(t.as_vector(), coeff), gmm::sub_vector(V, I));
       return 0;
      }
@@ -5147,9 +6433,117 @@ namespace getfem {
       : t(t_), V(V_), I(I_), coeff(coeff_) {}
   };
 
+  struct ga_instruction_assignment : public ga_instruction {
+    base_tensor &t;
+    base_vector &V;
+    const fem_interpolation_context &ctx;
+    const im_data *imd;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: Assignement to im_data");
+      imd->set_tensor(V, ctx.convex_num(), ctx.ii(), t);
+      return 0;
+     }
+    ga_instruction_assignment(base_tensor &t_, base_vector &V_,
+			      const fem_interpolation_context &ctx_,
+			      const im_data *imd_)
+      : t(t_), V(V_), ctx(ctx_), imd(imd_) {}
+  };
+
+  template <class MAT>
+  inline void add_elem_matrix_
+  (MAT &K, const std::vector<size_type> &dofs1,
+   const std::vector<size_type> &dofs2, std::vector<size_type> &/*dofs1_sort*/,
+   base_vector &elem, scalar_type threshold, size_type /* N */) {
+    base_vector::const_iterator it = elem.cbegin();
+    for (const size_type &dof2 : dofs2)
+      for (const size_type &dof1 : dofs1) {
+	if (gmm::abs(*it) > threshold)
+	  K(dof1, dof2) += *it;
+	++it;
+      }
+  }
+
+  // static const std::vector<size_type> *the_indto_sort;
+  // int compare_my_indices(const void *a, const void *b) {
+  //   size_type aa = *((const size_type *)(a));
+  //   size_type bb = *((const size_type *)(b));
+  //   return  int((*the_indto_sort)[aa]) - int((*the_indto_sort)[bb]);
+  // }
+  
+  inline void add_elem_matrix_
+  (gmm::col_matrix<gmm::rsvector<scalar_type>> &K,
+   const std::vector<size_type> &dofs1, const std::vector<size_type> &dofs2,
+   std::vector<size_type> &dofs1_sort,
+   base_vector &elem, scalar_type threshold, size_type N) {
+    size_type maxest = (N+1) * std::max(dofs1.size(), dofs2.size());
+    size_type s1 = dofs1.size(), s2 = dofs2.size();
+    gmm::elt_rsvector_<scalar_type> ev;
+    
+    dofs1_sort.resize(s1);
+    for (size_type i = 0; i < s1; ++i) { // insertion sort
+      size_type j = i, k = j-1;
+      while (j > 0 && dofs1[i] < dofs1[dofs1_sort[k]])
+    	{ dofs1_sort[j] = dofs1_sort[k]; j--; k--; }
+      dofs1_sort[j] = i;
+    }
+
+    // dofs1_sort.resize(s1); // test with qsort: not faster in the tested cases
+    // for (size_type i = 0; i < s1; ++i) dofs1_sort[i] = i;
+    // the_indto_sort = &dofs1;
+    // qsort(&(dofs1_sort[0]), s1, sizeof(size_type), compare_my_indices);
+
+    base_vector::const_iterator it = elem.cbegin();
+    for (size_type j = 0; j < s2; ++j) { // Iteration on columns
+      if (j) it += s1;
+      std::vector<gmm::elt_rsvector_<scalar_type>> &col = K[dofs2[j]];
+      size_type nb = col.size();
+      
+      if (nb == 0) {
+	col.reserve(maxest);
+	for (size_type i = 0; i < s1; ++i) {
+	  size_type k = dofs1_sort[i]; ev.e = *(it+k);
+	  if (gmm::abs(ev.e) > threshold) { ev.c=dofs1[k]; col.push_back(ev); }
+	}
+      } else { // column merge
+	size_type ind = 0;
+	for (size_type i = 0; i < s1; ++i) {
+	  size_type k = dofs1_sort[i]; ev.e = *(it+k);
+	  if (gmm::abs(ev.e) > threshold) {
+	    ev.c = dofs1[k]; 
+
+	    size_type count = nb - ind, step, l;
+	    while (count > 0) {
+	      step = count / 2; l = ind + step;
+	      if (col[l].c < ev.c) { ind = ++l; count -= step + 1; }
+	      else count = step;
+	    }
+	    
+	    auto itc = col.begin() + ind;
+	    if (ind != nb && itc->c == ev.c) itc->e += ev.e;
+	    else {
+	      if (nb - ind > 1100)
+		GMM_WARNING2("Inefficient addition of element in rsvector with "
+			     << col.size() - ind << " non-zero entries");
+	      col.push_back(ev);
+	      if (ind != nb) {
+		itc = col.begin() + ind;
+		auto ite = col.end(); --ite; auto itee = ite; 
+		for (; ite != itc; --ite) { --itee; *ite = *itee; }
+		*itc = ev;
+	      }
+	      ++nb;
+	    }
+	    ++ind; 
+	  }
+	}
+      }
+    }
+  }
+  
+
   template <class MAT = model_real_sparse_matrix>
   struct ga_instruction_matrix_assembly : public ga_instruction {
-    base_tensor &t;
+    const base_tensor &t;
     MAT &Kr, &Kn;
     const fem_interpolation_context &ctx1, &ctx2;
     const gmm::sub_interval &Ir1, &Ir2;
@@ -5158,91 +6552,495 @@ namespace getfem {
     const mesh_fem **mfg1, **mfg2;
     const scalar_type &coeff, &alpha1, &alpha2;
     const size_type &nbpt, &ipt;
-    base_vector &elem;
+    base_vector elem;
     bool interpolate;
-    mutable std::vector<size_type> dofs1, dofs2;
+    std::vector<size_type> dofs1, dofs2, dofs1_sort;
     virtual int exec() {
-      GA_DEBUG_INFO("Instruction: matrix term assembly\n");
+      GA_DEBUG_INFO("Instruction: matrix term assembly");
       if (ipt == 0 || interpolate) {
-        gmm::resize(elem, t.size());
-        gmm::copy(gmm::scaled(t.as_vector(), coeff*alpha1*alpha2), elem);
+        elem.resize(t.size());
+	auto itt = t.begin(); auto it = elem.begin(), ite = elem.end();
+	scalar_type e = coeff*alpha1*alpha2;
+	size_type nd = ((t.size()) >> 2);
+	for (size_type i = 0; i < nd; ++i) {
+	  *it++ = (*itt++) * e; *it++ = (*itt++) * e;
+	  *it++ = (*itt++) * e; *it++ = (*itt++) * e;
+	}
+	for (; it != ite;) *it++ = (*itt++) * e;
+        // gmm::copy(gmm::scaled(t.as_vector(), coeff*alpha1*alpha2), elem);
       } else {
-        gmm::add(gmm::scaled(t.as_vector(), coeff*alpha1*alpha2), elem);
+	// Faster than a daxpy blas call on my config
+	auto itt = t.begin(); auto it = elem.begin(), ite = elem.end();
+	scalar_type e = coeff*alpha1*alpha2;
+	size_type nd = ((t.size()) >> 2);
+	for (size_type i = 0; i < nd; ++i) {
+	  *it++ += (*itt++) * e; *it++ += (*itt++) * e;
+	  *it++ += (*itt++) * e; *it++ += (*itt++) * e;
+	}
+	for (; it != ite;) *it++ += (*itt++) * e;
+        // gmm::add(gmm::scaled(t.as_vector(), coeff*alpha1*alpha2), elem);
       }
       if (ipt == nbpt-1 || interpolate) {
         const mesh_fem *pmf1 = mfg1 ? *mfg1 : mfn1;
         const mesh_fem *pmf2 = mfg2 ? *mfg2 : mfn2;
-        bool reduced = (pmf1 && pmf1->is_reduced()) || (pmf2 && pmf2->is_reduced());
+        bool reduced = (pmf1 && pmf1->is_reduced())
+	  || (pmf2 && pmf2->is_reduced());
         MAT &K = reduced ? Kr : Kn;
         const gmm::sub_interval &I1 = reduced ? Ir1 : In1;
         const gmm::sub_interval &I2 = reduced ? Ir2 : In2;
         GA_DEBUG_ASSERT(I1.size() && I2.size(), "Internal error");
 
-        scalar_type ninf = gmm::vect_norminf(elem);
-        if (ninf == scalar_type(0))
-          return 0;
-
-        size_type s1 = t.sizes()[0], s2 = t.sizes()[1];
-
-        dofs1.assign(s1, I1.first());
-        if (pmf1) {
-          if (!ctx1.is_convex_num_valid()) return 0;
-          mesh_fem::ind_dof_ct ct1 = pmf1->ind_basic_dof_of_element(ctx1.convex_num());
-          GA_DEBUG_ASSERT(ct1.size() == s1,
-                          "Internal error, " << ct1.size() << " != " << s1);
-          for (size_type i=0; i < s1; ++i) dofs1[i] += ct1[i];
-        } else
-          for (size_type i=0; i < s1; ++i) dofs1[i] += i;
-
-        dofs2.assign(s2, I2.first());
-        if (pmf2) {
-          if (!ctx2.is_convex_num_valid()) return 0;
-          mesh_fem::ind_dof_ct ct2 = pmf2->ind_basic_dof_of_element(ctx2.convex_num());
-          GA_DEBUG_ASSERT(ct2.size() == s2,
-                          "Internal error, " << ct2.size() << " != " << s2);
-          for (size_type i=0; i < s2; ++i) dofs2[i] += ct2[i];
-        } else
-          for (size_type i=0; i < s2; ++i) dofs2[i] += i;
-
-        scalar_type threshold = ninf * 1E-14;
-        base_vector::const_iterator it = elem.cbegin();
-        for (const size_type &dof2 : dofs2)
-          for (const size_type &dof1 : dofs1) {
-            if (gmm::abs(*it) > threshold)
-              K(dof1, dof2) += *it;
-            ++it;
-          }
+        scalar_type ninf = gmm::vect_norminf(elem);
+        if (ninf == scalar_type(0)) return 0;
+
+        size_type s1 = t.sizes()[0], s2 = t.sizes()[1];
+	size_type cv1 = pmf1 ? ctx1.convex_num() : s1;
+	size_type cv2 = pmf2 ? ctx2.convex_num() : s2;
+	size_type N = 1;
+
+        dofs1.assign(s1, I1.first());
+        if (pmf1) {
+          if (!(ctx1.is_convex_num_valid())) return 0;
+	  N = ctx1.N();
+          auto &ct1 = pmf1->ind_scalar_basic_dof_of_element(cv1);
+          size_type qmult1 = pmf1->get_qdim();
+          if (qmult1 > 1) qmult1 /= pmf1->fem_of_element(cv1)->target_dim();
+          auto itd = dofs1.begin();
+          if (qmult1 == 1) {
+            for (auto itt = ct1.begin(); itt != ct1.end(); ++itt)
+              *itd++ += *itt;
+          } else {
+            for (auto itt = ct1.begin(); itt != ct1.end(); ++itt)
+              for (size_type q = 0; q < qmult1; ++q)
+                  *itd++ += *itt + q;
+          }
+        } else
+          for (size_type i=0; i < s1; ++i) dofs1[i] += i;
+
+	if (pmf1 == pmf2 && cv1 == cv2) {
+	  if (I1.first() == I2.first()) {
+	    add_elem_matrix_(K, dofs1, dofs1, dofs1_sort, elem, ninf*1E-14, N);
+	  } else {
+	    dofs2.resize(dofs1.size());
+	    for (size_type i = 0; i < dofs1.size(); ++i)
+	      dofs2[i] =  dofs1[i] + I2.first() - I1.first();
+	    add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf*1E-14, N);
+	  }
+	} else {
+	  dofs2.assign(s2, I2.first());
+	  if (pmf2) {
+	    if (!(ctx2.is_convex_num_valid())) return 0;
+	    N = std::max(N, ctx2.N());
+	    auto &ct2 = pmf2->ind_scalar_basic_dof_of_element(cv2);
+	    size_type qmult2 = pmf2->get_qdim();
+	    if (qmult2 > 1) qmult2 /= pmf2->fem_of_element(cv2)->target_dim();
+	    auto itd = dofs2.begin();
+	    if (qmult2 == 1) {
+	      for (auto itt = ct2.begin(); itt != ct2.end(); ++itt)
+		*itd++ += *itt;
+	    } else {
+	      for (auto itt = ct2.begin(); itt != ct2.end(); ++itt)
+		for (size_type q = 0; q < qmult2; ++q)
+                  *itd++ += *itt + q;
+	    }
+	  } else
+	    for (size_type i=0; i < s2; ++i) dofs2[i] += i;
+
+	  add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf*1E-14, N);
+	}
+      }
+      return 0;
+    }
+    ga_instruction_matrix_assembly
+    (const base_tensor &t_, MAT &Kr_, MAT &Kn_,
+     const fem_interpolation_context &ctx1_,
+     const fem_interpolation_context &ctx2_,
+     const gmm::sub_interval &Ir1_, const gmm::sub_interval &In1_,
+     const gmm::sub_interval &Ir2_, const gmm::sub_interval &In2_,
+     const mesh_fem *mfn1_, const mesh_fem **mfg1_,
+     const mesh_fem *mfn2_, const mesh_fem **mfg2_,
+     const scalar_type &coeff_,
+     const scalar_type &alpha2_, const scalar_type &alpha1_,
+     const size_type &nbpt_, const size_type &ipt_, bool interpolate_)
+      : t(t_), Kr(Kr_), Kn(Kn_), ctx1(ctx1_), ctx2(ctx2_),
+        Ir1(Ir1_), Ir2(Ir2_), In1(In1_), In2(In2_),
+        mfn1(mfn1_), mfn2(mfn2_), mfg1(mfg1_), mfg2(mfg2_),
+        coeff(coeff_), alpha1(alpha1_), alpha2(alpha2_),
+        nbpt(nbpt_), ipt(ipt_), interpolate(interpolate_),
+        dofs1(0), dofs2(0) {}
+  };
+
+  template <class MAT = model_real_sparse_matrix>
+  struct ga_instruction_matrix_assembly_standard_scalar: public ga_instruction {
+    const base_tensor &t;
+    MAT &K;
+    const fem_interpolation_context &ctx1, &ctx2;
+    const gmm::sub_interval &I1, &I2;
+    const mesh_fem *pmf1, *pmf2;
+    const scalar_type &coeff, &alpha1, &alpha2;
+    const size_type &nbpt, &ipt;
+    base_vector elem;
+    std::vector<size_type> dofs1, dofs2, dofs1_sort;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: matrix term assembly for standard "
+                    "scalar fems");
+      if (ipt == 0) {
+        elem.resize(t.size());
+	auto itt = t.begin(); auto it = elem.begin(), ite = elem.end();
+	scalar_type e = coeff*alpha1*alpha2;
+	size_type nd = ((t.size()) >> 2);
+	for (size_type i = 0; i < nd; ++i) {
+	  *it++ = (*itt++) * e; *it++ = (*itt++) * e;
+	  *it++ = (*itt++) * e; *it++ = (*itt++) * e;
+	}
+	for (; it != ite;) *it++ = (*itt++) * e;
+        // gmm::copy(gmm::scaled(t.as_vector(), coeff*alpha1*alpha2), elem);
+      } else {
+	// Faster than a daxpy blas call on my config
+	auto itt = t.begin(); auto it = elem.begin(), ite = elem.end();
+	scalar_type e = coeff*alpha1*alpha2;
+	size_type nd = ((t.size()) >> 2);
+	for (size_type i = 0; i < nd; ++i) {
+	  *it++ += (*itt++) * e; *it++ += (*itt++) * e;
+	  *it++ += (*itt++) * e; *it++ += (*itt++) * e;
+	}
+	for (; it != ite;) *it++ += (*itt++) * e;
+        // gmm::add(gmm::scaled(t.as_vector(), coeff*alpha1*alpha2), elem);
+      }
+      if (ipt == nbpt-1) {
+        GA_DEBUG_ASSERT(I1.size() && I2.size(), "Internal error");
+
+        scalar_type ninf = gmm::vect_norminf(elem);
+        if (ninf == scalar_type(0)) return 0;
+
+        size_type cv1 = ctx1.convex_num(), cv2 = ctx2.convex_num(), N=ctx1.N();
+        if (cv1 == size_type(-1)) return 0;
+        auto &ct1 = pmf1->ind_scalar_basic_dof_of_element(cv1);
+        GA_DEBUG_ASSERT(ct1.size() == t.sizes()[0], "Internal error");
+	dofs1.resize(ct1.size());
+	for (size_type i = 0; i < ct1.size(); ++i)
+	  dofs1[i] = ct1[i] + I1.first();
+
+        if (pmf2 == pmf1 && cv1 == cv2) {
+	  if (I1.first() == I2.first()) {
+	    add_elem_matrix_(K, dofs1, dofs1, dofs1_sort, elem, ninf*1E-14, N);
+	  } else {
+	    dofs2.resize(dofs1.size());
+	    for (size_type i = 0; i < dofs1.size(); ++i)
+	      dofs2[i] =  dofs1[i] + I2.first() - I1.first();
+	    add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf*1E-14, N);
+	  }
+	} else {
+	  if (cv2 == size_type(-1)) return 0;
+	  auto &ct2 = pmf2->ind_scalar_basic_dof_of_element(cv2);
+	  GA_DEBUG_ASSERT(ct2.size() == t.sizes()[1], "Internal error");
+	  dofs2.resize(ct2.size());
+	  for (size_type i = 0; i < ct2.size(); ++i)
+	    dofs2[i] = ct2[i] + I2.first();
+	  add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf*1E-14, N);
+	}
+      }
+      return 0;
+    }
+    ga_instruction_matrix_assembly_standard_scalar
+    (const base_tensor &t_, MAT &Kn_,
+     const fem_interpolation_context &ctx1_,
+     const fem_interpolation_context &ctx2_,
+     const gmm::sub_interval &In1_, const gmm::sub_interval &In2_,
+     const mesh_fem *mfn1_, const mesh_fem *mfn2_,
+     const scalar_type &coeff_, const scalar_type &alpha2_,
+     const scalar_type &alpha1_,
+     const size_type &nbpt_, const size_type &ipt_)
+      : t(t_), K(Kn_), ctx1(ctx1_), ctx2(ctx2_),
+        I1(In1_), I2(In2_),  pmf1(mfn1_), pmf2(mfn2_),
+        coeff(coeff_), alpha1(alpha1_), alpha2(alpha2_),
+        nbpt(nbpt_), ipt(ipt_) {}
+  };
+
+  template <class MAT = model_real_sparse_matrix>
+  struct ga_instruction_matrix_assembly_standard_vector: public ga_instruction {
+    const base_tensor &t;
+    MAT &K;
+    const fem_interpolation_context &ctx1, &ctx2;
+    const gmm::sub_interval &I1, &I2;
+    const mesh_fem *pmf1, *pmf2;
+    const scalar_type &coeff, &alpha1, &alpha2;
+    const size_type &nbpt, &ipt;
+    mutable base_vector elem;
+    mutable std::vector<size_type> dofs1, dofs2, dofs1_sort;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: matrix term assembly for standard "
+                        "vector fems");
+      if (ipt == 0) {
+        elem.resize(t.size());
+	auto itt = t.begin(); auto it = elem.begin(), ite = elem.end();
+	scalar_type e = coeff*alpha1*alpha2;
+	size_type nd = ((t.size()) >> 3);
+	for (size_type i = 0; i < nd; ++i) {
+	  *it++ = (*itt++) * e; *it++ = (*itt++) * e;
+	  *it++ = (*itt++) * e; *it++ = (*itt++) * e;
+	  *it++ = (*itt++) * e; *it++ = (*itt++) * e;
+	  *it++ = (*itt++) * e; *it++ = (*itt++) * e;
+	}
+	for (; it != ite;) *it++ = (*itt++) * e;
+        // gmm::copy(gmm::scaled(t.as_vector(), coeff*alpha1*alpha2), elem);
+      } else {
+	// (Far) faster than a daxpy blas call on my config.
+	auto itt = t.begin(); auto it = elem.begin(), ite = elem.end();
+	scalar_type e = coeff*alpha1*alpha2;
+	size_type nd = ((t.size()) >> 3);
+	for (size_type i = 0; i < nd; ++i) {
+	  *it++ += (*itt++) * e; *it++ += (*itt++) * e;
+	  *it++ += (*itt++) * e; *it++ += (*itt++) * e;
+	  *it++ += (*itt++) * e; *it++ += (*itt++) * e;
+	  *it++ += (*itt++) * e; *it++ += (*itt++) * e;
+	}
+	for (; it != ite;) *it++ += (*itt++) * e;
+        // gmm::add(gmm::scaled(t.as_vector(), coeff*alpha1*alpha2), elem);
+      }
+      if (ipt == nbpt-1) {
+        GA_DEBUG_ASSERT(I1.size() && I2.size(), "Internal error");
+
+        scalar_type ninf = gmm::vect_norminf(elem);
+        if (ninf == scalar_type(0)) return 0;
+        size_type s1 = t.sizes()[0], s2 = t.sizes()[1], N = ctx1.N();
+
+        size_type cv1 = ctx1.convex_num(), cv2 = ctx2.convex_num();
+        if (cv1 == size_type(-1)) return 0;
+        auto &ct1 = pmf1->ind_scalar_basic_dof_of_element(cv1);
+        size_type qmult1 = pmf1->get_qdim();
+        if (qmult1 > 1) qmult1 /= pmf1->fem_of_element(cv1)->target_dim();
+        dofs1.assign(s1, I1.first());
+        auto itd = dofs1.begin();
+        for (auto itt = ct1.begin(); itt != ct1.end(); ++itt)
+          for (size_type q = 0; q < qmult1; ++q)
+            *itd++ += *itt + q;
+
+	if (pmf2 == pmf1 && cv1 == cv2) {
+	  if (I1.first() == I2.first()) {
+	    add_elem_matrix_(K, dofs1, dofs1, dofs1_sort, elem, ninf*1E-14, N);
+	  } else {
+	    dofs2.resize(dofs1.size());
+	    for (size_type i = 0; i < dofs1.size(); ++i)
+	      dofs2[i] =  dofs1[i] + I2.first() - I1.first();
+	    add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf*1E-14, N);
+	  }
+	} else {
+	  if (cv2 == size_type(-1)) return 0;
+	  auto &ct2 = pmf2->ind_scalar_basic_dof_of_element(cv2);
+	  size_type qmult2 = pmf2->get_qdim();
+	  if (qmult2 > 1) qmult2 /= pmf2->fem_of_element(cv2)->target_dim();
+	  dofs2.assign(s2, I2.first());
+	  itd = dofs2.begin();
+	  for (auto itt = ct2.begin(); itt != ct2.end(); ++itt)
+	    for (size_type q = 0; q < qmult2; ++q)
+	      *itd++ += *itt + q;
+	  
+	  add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf*1E-14, N);
+	}
+      }
+      return 0;
+    }
+    ga_instruction_matrix_assembly_standard_vector
+    (const base_tensor &t_, MAT &Kn_,
+     const fem_interpolation_context &ctx1_,
+     const fem_interpolation_context &ctx2_,
+     const gmm::sub_interval &In1_, const gmm::sub_interval &In2_,
+     const mesh_fem *mfn1_, const mesh_fem *mfn2_,
+     const scalar_type &coeff_, const scalar_type &alpha2_,
+     const scalar_type &alpha1_, const size_type &nbpt_,
+     const size_type &ipt_)
+      : t(t_), K(Kn_), ctx1(ctx1_), ctx2(ctx2_),
+        I1(In1_), I2(In2_),  pmf1(mfn1_), pmf2(mfn2_),
+        coeff(coeff_), alpha1(alpha1_), alpha2(alpha2_),
+        nbpt(nbpt_), ipt(ipt_), dofs1(0), dofs2(0) {}
+  };
+
+  struct ga_instruction_matrix_assembly_standard_vector_opt10_2
+    : public ga_instruction {
+    const base_tensor &t;
+    model_real_sparse_matrix &K;
+    const fem_interpolation_context &ctx1, &ctx2;
+    const gmm::sub_interval &I1, &I2;
+    const mesh_fem *pmf1, *pmf2;
+    const scalar_type &coeff, &alpha1, &alpha2;
+    const size_type &nbpt, &ipt;
+    mutable base_vector elem;
+    mutable std::vector<size_type> dofs1, dofs2, dofs1_sort;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: matrix term assembly for standard "
+		    "vector fems optimized for format 10 qdim 2");
+      size_type s1 = t.sizes()[0], s2 = t.sizes()[1], s1_q = 2*s1;
+      size_type ss1 = s1/2, ss2 = s2/2;
+      scalar_type e = coeff*alpha1*alpha2;
+      if (ipt == 0) {
+        elem.resize(ss1*ss2);
+	auto itel = elem.begin();
+	for (size_type j = 0; j < ss2; ++j) {
+	  auto it = t.begin() + j*s1_q;
+	  for (size_type i = 0; i < ss1; ++i, it += 2)
+	    *itel++ = (*it) * e;
+	}
+      } else {
+	auto itel = elem.begin();
+	for (size_type j = 0; j < ss2; ++j) {
+	  auto it = t.begin() + j*s1_q;
+	  for (size_type i = 0; i < ss1; ++i, it += 2)
+	    *itel++ += (*it) * e;
+	}
+      }
+      if (ipt == nbpt-1) {
+        GA_DEBUG_ASSERT(I1.size() && I2.size(), "Internal error");
+
+        scalar_type ninf = gmm::vect_norminf(elem) * 1E-14;
+        if (ninf == scalar_type(0)) return 0;
+        size_type N = ctx1.N();
+        size_type cv1 = ctx1.convex_num(), cv2 = ctx2.convex_num();
+	size_type i1 = I1.first(), i2 = I2.first();
+        if (cv1 == size_type(-1)) return 0;
+        auto &ct1 = pmf1->ind_scalar_basic_dof_of_element(cv1);
+	dofs1.resize(ss1);
+	for (size_type i = 0; i < ss1; ++i) dofs1[i] = i1 + ct1[i];
+	
+	if (pmf2 == pmf1 && cv1 == cv2) {
+	  if (i1 == i2) {
+	    add_elem_matrix_(K, dofs1, dofs1, dofs1_sort, elem, ninf, N);
+	    for (size_type i = 0; i < ss1; ++i) (dofs1[i])++;
+	    add_elem_matrix_(K, dofs1, dofs1, dofs1_sort, elem, ninf, N);
+	  } else {
+	    dofs2.resize(ss2);
+	    for (size_type i = 0; i < ss2; ++i) dofs2[i] = i2 + ct1[i];
+	    add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	    for (size_type i = 0; i < ss1; ++i) (dofs1[i])++;
+	    for (size_type i = 0; i < ss2; ++i) (dofs2[i])++;
+	    add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	  }
+	} else {
+	  if (cv2 == size_type(-1)) return 0;
+	  auto &ct2 = pmf2->ind_scalar_basic_dof_of_element(cv2);
+	  dofs2.resize(ss2);
+	  for (size_type i = 0; i < ss2; ++i) dofs2[i] = i2 + ct2[i];
+	  add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	  for (size_type i = 0; i < ss1; ++i) (dofs1[i])++;
+	  for (size_type i = 0; i < ss2; ++i) (dofs2[i])++;
+	  add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	}
+      }
+      return 0;
+    }
+    ga_instruction_matrix_assembly_standard_vector_opt10_2
+    (const base_tensor &t_, model_real_sparse_matrix &Kn_,
+     const fem_interpolation_context &ctx1_,
+     const fem_interpolation_context &ctx2_,
+     const gmm::sub_interval &In1_, const gmm::sub_interval &In2_,
+     const mesh_fem *mfn1_, const mesh_fem *mfn2_,
+     const scalar_type &coeff_, const scalar_type &alpha2_,
+     const scalar_type &alpha1_, const size_type &nbpt_,
+     const size_type &ipt_)
+      : t(t_), K(Kn_), ctx1(ctx1_), ctx2(ctx2_),
+        I1(In1_), I2(In2_),  pmf1(mfn1_), pmf2(mfn2_),
+        coeff(coeff_), alpha1(alpha1_), alpha2(alpha2_),
+        nbpt(nbpt_), ipt(ipt_), dofs1(0), dofs2(0) {}
+  };
+
+  struct ga_instruction_matrix_assembly_standard_vector_opt10_3
+    : public ga_instruction {
+    const base_tensor &t;
+    model_real_sparse_matrix &K;
+    const fem_interpolation_context &ctx1, &ctx2;
+    const gmm::sub_interval &I1, &I2;
+    const mesh_fem *pmf1, *pmf2;
+    const scalar_type &coeff, &alpha1, &alpha2;
+    const size_type &nbpt, &ipt;
+    mutable base_vector elem;
+    mutable std::vector<size_type> dofs1, dofs2, dofs1_sort;
+    virtual int exec() {
+      GA_DEBUG_INFO("Instruction: matrix term assembly for standard "
+		    "vector fems optimized for format 10 qdim 3");
+      size_type s1 = t.sizes()[0], s2 = t.sizes()[1], s1_q = 3*s1;
+      size_type ss1 = s1/3, ss2 = s2/3;
+      scalar_type e = coeff*alpha1*alpha2;
+      if (ipt == 0) {
+        elem.resize(ss1*ss2);
+	auto itel = elem.begin();
+	for (size_type j = 0; j < ss2; ++j) {
+	  auto it = t.begin() + j*s1_q;
+	  for (size_type i = 0; i < ss1; ++i, it += 3)
+	    *itel++ = (*it) * e;
+	}
+      } else {
+	auto itel = elem.begin();
+	for (size_type j = 0; j < ss2; ++j) {
+	  auto it = t.begin() + j*s1_q;
+	  for (size_type i = 0; i < ss1; ++i, it += 3)
+	    *itel++ += (*it) * e;
+	}
+      }
+      if (ipt == nbpt-1) {
+        GA_DEBUG_ASSERT(I1.size() && I2.size(), "Internal error");
+
+        scalar_type ninf = gmm::vect_norminf(elem)*1E-14;
+        if (ninf == scalar_type(0)) return 0;
+        size_type N = ctx1.N();
+        size_type cv1 = ctx1.convex_num(), cv2 = ctx2.convex_num();
+	size_type i1 = I1.first(), i2 = I2.first();
+        if (cv1 == size_type(-1)) return 0;
+        auto &ct1 = pmf1->ind_scalar_basic_dof_of_element(cv1);
+	dofs1.resize(ss1);
+	for (size_type i = 0; i < ss1; ++i) dofs1[i] = i1 + ct1[i];
+	
+	if (pmf2 == pmf1 && cv1 == cv2) {
+	  if (i1 == i2) {
+	    add_elem_matrix_(K, dofs1, dofs1, dofs1_sort, elem, ninf, N);
+	    for (size_type i = 0; i < ss1; ++i) (dofs1[i])++;
+	    add_elem_matrix_(K, dofs1, dofs1, dofs1_sort, elem, ninf, N);
+	    for (size_type i = 0; i < ss1; ++i) (dofs1[i])++;
+	    add_elem_matrix_(K, dofs1, dofs1, dofs1_sort, elem, ninf, N);
+	  } else {
+	    dofs2.resize(ss2);
+	    for (size_type i = 0; i < ss2; ++i) dofs2[i] = i2 + ct1[i];
+	    add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	    for (size_type i = 0; i < ss1; ++i) (dofs1[i])++;
+	    for (size_type i = 0; i < ss2; ++i) (dofs2[i])++;
+	    add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	    for (size_type i = 0; i < ss1; ++i) (dofs1[i])++;
+	    for (size_type i = 0; i < ss2; ++i) (dofs2[i])++;
+	    add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	  }
+	} else {
+	  if (cv2 == size_type(-1)) return 0;
+	  auto &ct2 = pmf2->ind_scalar_basic_dof_of_element(cv2);
+	  dofs2.resize(ss2);
+	  for (size_type i = 0; i < ss2; ++i) dofs2[i] = i2 + ct2[i];
+	  add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	  for (size_type i = 0; i < ss1; ++i) (dofs1[i])++;
+	  for (size_type i = 0; i < ss2; ++i) (dofs2[i])++;
+	  add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	  for (size_type i = 0; i < ss1; ++i) (dofs1[i])++;
+	  for (size_type i = 0; i < ss2; ++i) (dofs2[i])++;
+	  add_elem_matrix_(K, dofs1, dofs2, dofs1_sort, elem, ninf, N);
+	}
       }
       return 0;
     }
-    ga_instruction_matrix_assembly(base_tensor &t_,
-                                   MAT &Kr_, MAT &Kn_,
-                                   const fem_interpolation_context &ctx1_,
-                                   const fem_interpolation_context &ctx2_,
-                                   const gmm::sub_interval &Ir1_,
-                                   const gmm::sub_interval &In1_,
-                                   const gmm::sub_interval &Ir2_,
-                                   const gmm::sub_interval &In2_,
-                                   const mesh_fem *mfn1_,
-                                   const mesh_fem **mfg1_,
-                                   const mesh_fem *mfn2_,
-                                   const mesh_fem **mfg2_,
-                                   const scalar_type &coeff_,
-                                   const scalar_type &alpha2_,
-                                   const scalar_type &alpha1_,
-                                   const size_type &nbpt_,
-                                   const size_type &ipt_,
-                                   base_vector &elem_,
-                                   bool interpolate_)
-      : t(t_), Kr(Kr_), Kn(Kn_), ctx1(ctx1_), ctx2(ctx2_),
-        Ir1(Ir1_), Ir2(Ir2_), In1(In1_), In2(In2_),
-        mfn1(mfn1_), mfn2(mfn2_), mfg1(mfg1_), mfg2(mfg2_),
+    ga_instruction_matrix_assembly_standard_vector_opt10_3
+    (const base_tensor &t_, model_real_sparse_matrix &Kn_,
+     const fem_interpolation_context &ctx1_,
+     const fem_interpolation_context &ctx2_,
+     const gmm::sub_interval &In1_, const gmm::sub_interval &In2_,
+     const mesh_fem *mfn1_, const mesh_fem *mfn2_,
+     const scalar_type &coeff_, const scalar_type &alpha2_,
+     const scalar_type &alpha1_, const size_type &nbpt_,
+     const size_type &ipt_)
+      : t(t_), K(Kn_), ctx1(ctx1_), ctx2(ctx2_),
+        I1(In1_), I2(In2_),  pmf1(mfn1_), pmf2(mfn2_),
         coeff(coeff_), alpha1(alpha1_), alpha2(alpha2_),
-        nbpt(nbpt_), ipt(ipt_), elem(elem_), interpolate(interpolate_),
-        dofs1(0), dofs2(0) {}
+        nbpt(nbpt_), ipt(ipt_), dofs1(0), dofs2(0) {}
   };
 
 
+
+
   //=========================================================================
   // Structure dealing with user defined environment : constant, variables,
   // functions, operators.
@@ -5621,8 +7419,8 @@ namespace getfem {
       return dummy_mesh_region();
 
     std::list<mesh_region> &lmr = registred_mesh_regions[&m];
-    for (const mesh_region &mr : lmr)
-      if (mr.compare(m, region, m)) return mr;
+    for (const mesh_region &rg : lmr)
+      if (rg.compare(m, region, m)) return rg;
     lmr.push_back(region);
     return lmr.back();
   }
@@ -5699,7 +7497,8 @@ namespace getfem {
                               const mesh_im &mim, const mesh_region &rg,
                               const std::string &expr,
                               size_type add_derivative_order,
-                              bool function_expr) {
+                              bool function_expr, size_type for_interpolation,
+			      const std::string varname_interpolation) {
     if (tree.root) {
 
       // Eliminate the term if it corresponds to disabled variables
@@ -5707,7 +7506,7 @@ namespace getfem {
            is_disabled_variable(tree.root->name_test1)) ||
           (tree.root->test_function_type >= 2 &&
            is_disabled_variable(tree.root->name_test2))) {
-        // cout << "disabling term ";  ga_print_node(tree.root, cout); cout << endl;
+        // cout<<"disabling term ";  ga_print_node(tree.root, cout); cout<<endl;
         return;
       }
       // cout << "add tree with tests functions of " <<  tree.root->name_test1
@@ -5715,13 +7514,17 @@ namespace getfem {
       //      ga_print_node(tree.root, cout); cout << endl;
       bool remain = true;
       size_type order = 0, ind_tree = 0;
-
-      switch(tree.root->test_function_type) {
-      case 0: order = 0; break;
-      case 1: order = 1; break;
-      case 3: order = 2; break;
-      default: GMM_ASSERT1(false, "Inconsistent term "
-                           << tree.root->test_function_type);
+      
+      if (for_interpolation)
+	order = size_type(-1) - add_derivative_order;
+      else {
+	switch(tree.root->test_function_type) {
+	case 0: order = 0; break;
+	case 1: order = 1; break;
+	case 3: order = 2; break;
+	default: GMM_ASSERT1(false, "Inconsistent term "
+			     << tree.root->test_function_type);
+	}
       }
 
       bool found = false;
@@ -5734,7 +7537,8 @@ namespace getfem {
             trees[i].name_test2.compare(tree.root->name_test2) == 0 &&
             trees[i].interpolate_name_test2.compare
             (tree.root->interpolate_name_test2) == 0 &&
-            trees[i].rg == &rg) {
+            trees[i].rg == &rg && trees[i].interpolation == for_interpolation &&
+	    trees[i].varname_interpolation.compare(varname_interpolation)==0) {
           ga_tree &ftree = *(trees[i].ptree);
 
           ftree.insert_node(ftree.root, GA_NODE_OP);
@@ -5761,9 +7565,11 @@ namespace getfem {
         trees.back().interpolate_name_test1 = root->interpolate_name_test1;
         trees.back().interpolate_name_test2 = root->interpolate_name_test2;
         trees.back().order = order;
-      }
+	trees.back().interpolation = for_interpolation;
+	trees.back().varname_interpolation = varname_interpolation;
+       }
 
-      if (order < add_derivative_order) {
+      if (for_interpolation == 0 && order < add_derivative_order) {
         std::set<var_trans_pair> expr_variables;
         ga_extract_variables((remain ? tree : *(trees[ind_tree].ptree)).root,
                              *this, m, expr_variables, true);
@@ -5781,14 +7587,14 @@ namespace getfem {
             GA_TOCTIC("Analysis after Derivative time");
             // cout << "after analysis "  << ga_tree_to_string(dtree) << endl;
             add_tree(dtree, m, mim, rg, expr, add_derivative_order,
-                     function_expr);
+                     function_expr, for_interpolation, varname_interpolation);
           }
         }
       }
     }
   }
 
-  ga_workspace::m_tree::~m_tree(void) { if (ptree) delete ptree; }
+  ga_workspace::m_tree::~m_tree() { if (ptree) delete ptree; }
   ga_workspace::m_tree::m_tree(const m_tree& o)
     : ptree(o.ptree), meshdim(o.meshdim), ignore_X(o.ignore_X)
   { if (o.ptree) ptree = new ga_tree(*(o.ptree)); }
@@ -5842,7 +7648,7 @@ namespace getfem {
           // cout << "adding tree " << ga_tree_to_string(ltrees[i]) << endl;
           max_order = std::max(ltrees[i].root->nb_test_functions(), max_order);
           add_tree(ltrees[i], mim.linked_mesh(), mim, rg, expr,
-                   add_derivative_order);
+                   add_derivative_order, true, 0, "");
         }
       }
     }
@@ -5858,7 +7664,7 @@ namespace getfem {
       // GMM_ASSERT1(tree.root->nb_test_functions() == 0,
       //            "Invalid function expression");
       add_tree(tree, dummy_mesh(), dummy_mesh_im(), dummy_mesh_region(),
-               expr, 0);
+               expr, 0, true, 0, "");
     }
   }
 
@@ -5873,7 +7679,7 @@ namespace getfem {
     if (tree.root) {
       GMM_ASSERT1(tree.root->nb_test_functions() == 0,
                   "Invalid expression containing test functions");
-      add_tree(tree, m, dummy_mesh_im(), rg, expr, 0, false);
+      add_tree(tree, m, dummy_mesh_im(), rg, expr, 0, false, 1, "");
     }
   }
 
@@ -5889,7 +7695,27 @@ namespace getfem {
     if (tree.root) {
       GMM_ASSERT1(tree.root->nb_test_functions() == 0,
                   "Invalid expression containing test functions");
-      add_tree(tree, m, mim, rg, expr, 0, false);
+      add_tree(tree, m, mim, rg, expr, 0, false, 1, "");
+    }
+  }
+
+  void ga_workspace::add_assignment_expression
+  (const std::string &varname, const std::string &expr, const mesh_region &rg_,
+   size_type order, bool before) {
+    const im_data *imd = associated_im_data(varname);
+    GMM_ASSERT1(imd != 0, "Only applicable to im_data");
+    const mesh_im &mim = imd->linked_mesh_im();
+    const mesh &m = mim.linked_mesh();
+    const mesh_region &rg = register_region(m, rg_);
+    ga_tree tree;
+    ga_read_string(expr, tree);
+    ga_semantic_analysis(expr, tree, *this, m.dim(), ref_elt_dim_of_mesh(m),
+                         false, false);
+    if (tree.root) {
+      GMM_ASSERT1(tree.root->nb_test_functions() == 0,
+                  "Invalid expression containing test functions");
+      add_tree(tree, m, mim, rg, expr, order+1, false, (before ? 1 : 2),
+	       varname);
     }
   }
 
@@ -5898,10 +7724,10 @@ namespace getfem {
   ga_workspace::tree_description &ga_workspace::tree_info(size_type i)
   { return trees[i]; }
 
-  bool ga_workspace::used_variables(model::varnamelist &vl,
-                                    model::varnamelist &vl_test1,
-                                    model::varnamelist &vl_test2,
-                                    model::varnamelist &dl,
+  bool ga_workspace::used_variables(std::vector<std::string> &vl,
+                                    std::vector<std::string> &vl_test1,
+                                    std::vector<std::string> &vl_test2,
+                                    std::vector<std::string> &dl,
                                     size_type order) {
     bool islin = true;
     std::set<var_trans_pair> vll, dll;
@@ -6021,16 +7847,21 @@ namespace getfem {
 
 
   void ga_workspace::assembly(size_type order) {
+    size_type ndof;
+    const ga_workspace *w = this;
+    while (w->parent_workspace) w = w->parent_workspace;
+    if (w->md) ndof = w->md->nb_dof(); // To eventually call actualize_sizes()
 
     GA_TIC;
     ga_instruction_set gis;
     ga_compile(*this, gis, order);
-    size_type ndof = gis.nb_dof, max_dof =  gis.max_dof;
+    ndof = gis.nb_dof;
+    size_type max_dof =  gis.max_dof;
     GA_TOCTIC("Compile time");
 
     if (order == 2) {
       if (K.use_count()) {
-        gmm::clear(*K);
+	gmm::clear(*K);
         gmm::resize(*K, max_dof, max_dof);
       }
       gmm::clear(unreduced_K);
@@ -6056,7 +7887,7 @@ namespace getfem {
     }
 
     // Deal with reduced fems.
-    if (order) {
+    if (order > 0) {
       std::set<std::string> vars_vec_done;
       std::set<std::pair<std::string, std::string> > vars_mat_done;
       for (ga_tree &tree : gis.trees) {
@@ -6119,7 +7950,7 @@ namespace getfem {
                       model_real_row_sparse_matrix M(I1.size(), I2.size());
                       gmm::mult(gmm::sub_matrix(unreduced_K, uI1, uI2),
                                 mf2->extension_matrix(), M);
-                      gmm::add(M, gmm::sub_matrix(*K, I1, I2));
+                      gmm::add(M, gmm::sub_matrix(*K, I1, I2));		      
                     }
                     vars_mat_done.insert(p);
                   }
@@ -6132,7 +7963,7 @@ namespace getfem {
     }
   }
 
-  void ga_workspace::clear_expressions(void) {
+  void ga_workspace::clear_expressions() {
     trees.clear();
     macro_trees.clear();
   }
@@ -6149,6 +7980,8 @@ namespace getfem {
 
   void ga_workspace::tree_description::copy(const tree_description& td) {
     order = td.order;
+    interpolation = td.interpolation;
+    varname_interpolation = td.varname_interpolation;
     name_test1 = td.name_test1;
     name_test2 = td.name_test2;
     interpolate_name_test1 = td.interpolate_name_test1;
@@ -6157,7 +7990,6 @@ namespace getfem {
     m = td.m;
     rg = td.rg;
     ptree = 0;
-    elem = td.elem;
     if (td.ptree) ptree = new ga_tree(*(td.ptree));
   }
 
@@ -6174,14 +8006,14 @@ namespace getfem {
   static scalar_type ga_hash_code(const std::string &s) {
     scalar_type c(0);
     for (size_type i = 0; i < s.size(); ++i)
-      c += sin(M_E+scalar_type(s[i])+M_PI*scalar_type(i+1));
+      c += sin(M_E+scalar_type(s[i]))+M_PI*M_E*scalar_type(i+1);
     return c;
   }
 
   static scalar_type ga_hash_code(const base_tensor &t) {
     scalar_type c(0);
     for (size_type i = 0; i < t.size(); ++i)
-      c += sin(M_E+t[i]+M_E*M_E*scalar_type(i+1));
+      c += sin(M_E+t[i]+M_E*M_E*scalar_type(i+1))+scalar_type(i+1)*M_PI;
     return c;
   }
 
@@ -6194,7 +8026,7 @@ namespace getfem {
 
     switch (pnode->node_type) {
     case GA_NODE_CONSTANT: case GA_NODE_ZERO:
-      c += ga_hash_code(pnode->t);
+      c += ga_hash_code(pnode->tensor());
       if (pnode->test_function_type & 1)
         c += 34.731 * ga_hash_code(pnode->name_test1);
       if (pnode->test_function_type & 2)
@@ -6211,7 +8043,7 @@ namespace getfem {
 
     case GA_NODE_INTERPOLATE_FILTER:
       c += 1.73*ga_hash_code(pnode->interpolate_name)
-        + 0.84*M_PI*scalar_type(pnode->nbc1);
+	+ 2.486*double(pnode->nbc1 + 1);
       break;
     case GA_NODE_INTERPOLATE_DERIVATIVE:
       c += 2.321*ga_hash_code(pnode->interpolate_name_der);
@@ -6410,7 +8242,7 @@ namespace getfem {
     case GA_NODE_VAL:
       if (eval_fixed_size && !(workspace.associated_mf(pnode->name))
           && !(workspace.associated_im_data(pnode->name))) {
-        gmm::copy(workspace.value(pnode->name), pnode->t.as_vector());
+        gmm::copy(workspace.value(pnode->name), pnode->tensor().as_vector());
         pnode->node_type = GA_NODE_CONSTANT;
       }
       break;
@@ -6472,14 +8304,14 @@ namespace getfem {
             ga_throw_error(expr, pnode->pos, "Invalid null size of variable");
           if (n == 1) {
             pnode->init_vector_tensor(1);
-            pnode->t[0] = scalar_type(1);
+            pnode->tensor()[0] = scalar_type(1);
             pnode->test_function_type = t_type;
           } else {
             pnode->init_matrix_tensor(n,n);
             pnode->test_function_type = t_type;
             for (size_type i = 0; i < n; ++i)
               for (size_type j = 0; j < n; ++j)
-                pnode->t(i,j) = (i == j) ? scalar_type(1) : scalar_type(0);
+                pnode->tensor()(i,j) = (i==j) ? scalar_type(1) : scalar_type(0);
           }
         }
       }
@@ -6501,15 +8333,16 @@ namespace getfem {
     case GA_NODE_XFEM_PLUS:
     case GA_NODE_XFEM_MINUS:
       {
-        int ndt = (pnode->node_type == GA_NODE_INTERPOLATE) ? 1 : 0
-          + (pnode->node_type == GA_NODE_ELEMENTARY) ? 2 : 0
-          + (pnode->node_type == GA_NODE_XFEM_PLUS) ? 3 : 0
-          + (pnode->node_type == GA_NODE_XFEM_MINUS) ? 4 : 0;
+        int ndt = ((pnode->node_type == GA_NODE_INTERPOLATE) ? 1 : 0)
+          + ((pnode->node_type == GA_NODE_ELEMENTARY) ? 2 : 0)
+          + ((pnode->node_type == GA_NODE_XFEM_PLUS) ? 3 : 0)
+	  + ((pnode->node_type == GA_NODE_XFEM_MINUS) ? 4 : 0);
         std::string op__name =
           (pnode->node_type == GA_NODE_INTERPOLATE) ? "Interpolation" : ""
-          + (pnode->node_type == GA_NODE_ELEMENTARY) ? "Elementary transformation" : ""
+          + (pnode->node_type == GA_NODE_ELEMENTARY) ?
+	     "Elementary transformation" : ""
           + (pnode->node_type == GA_NODE_XFEM_PLUS) ? "Xfem_plus" : ""
-          + (pnode->node_type == GA_NODE_XFEM_MINUS) ? "Xfem_minus" : "";
+	  + (pnode->node_type == GA_NODE_XFEM_MINUS) ? "Xfem_minus" : "";
 
         std::string name = pnode->name;
         size_type prefix_id = ga_parse_prefix_operator(name);
@@ -6693,7 +8526,7 @@ namespace getfem {
       {
         if (pnode->children.size() == 2) {
           bool valid = (child1->node_type == GA_NODE_CONSTANT);
-          int n = valid ? int(round(child1->t[0])) : -1;
+          int n = valid ? int(round(child1->tensor()[0])) : -1;
           if (n < 0 || n > 100 || child1->tensor_order() > 0)
             ga_throw_error(expr, pnode->pos, "The third argument of "
                            "Interpolate_filter should be a (small) "
@@ -6765,11 +8598,11 @@ namespace getfem {
           if (all_cte) {
             pnode->node_type = GA_NODE_CONSTANT;
             pnode->test_function_type = 0;
-            pnode->t = pnode->children[0]->t;
+            pnode->tensor() = pnode->children[0]->tensor();
             if (pnode->op_type == GA_MINUS)
-              pnode->t -= pnode->children[1]->t;
+              pnode->tensor() -= pnode->children[1]->tensor();
             else
-              pnode->t += pnode->children[1]->t;
+              pnode->tensor() += pnode->children[1]->tensor();
             tree.clear_children(pnode);
           } else {
             pnode->t = child0->t;
@@ -6874,19 +8707,19 @@ namespace getfem {
             pnode->node_type = GA_NODE_CONSTANT;
             pnode->test_function_type = 0;
             if (pnode->op_type == GA_DOTMULT) {
-              for (size_type i = 0; i < child0->t.size(); ++i)
-                pnode->t[i] = child0->t[i] * child1->t[i];
+              for (size_type i = 0; i < child0->tensor().size(); ++i)
+                pnode->tensor()[i] = child0->tensor()[i] * child1->tensor()[i];
             } else {
-              for (size_type i = 0; i < child0->t.size(); ++i) {
-                if (child1->t[i] == scalar_type(0))
+              for (size_type i = 0; i < child0->tensor().size(); ++i) {
+                if (child1->tensor()[i] == scalar_type(0))
                   ga_throw_error(expr, pnode->pos, "Division by zero.");
-                pnode->t[i] = child0->t[i] / child1->t[i];
+                pnode->tensor()[i] = child0->tensor()[i] / child1->tensor()[i];
               }
             }
             tree.clear_children(pnode);
           } else {
             if (child0->tensor_is_zero() || child1->tensor_is_zero()) {
-              gmm::clear(pnode->t.as_vector());
+              gmm::clear(pnode->tensor().as_vector());
               pnode->node_type = GA_NODE_ZERO;
               tree.clear_children(pnode);
             }
@@ -6908,7 +8741,7 @@ namespace getfem {
         if (all_cte) {
           pnode->node_type = GA_NODE_CONSTANT;
           pnode->test_function_type = 0;
-          gmm::scale(pnode->t.as_vector(), scalar_type(-1));
+          gmm::scale(pnode->tensor().as_vector(), scalar_type(-1));
           tree.clear_children(pnode);
         } else if (child0->node_type == GA_NODE_ZERO) {
           tree.replace_node_by_child(pnode, 0);
@@ -6940,21 +8773,22 @@ namespace getfem {
           if (dim0 == 2) {
             for (size_type i = 0; i < mi.back(); ++i)
               for (size_type j = 0; j < mi[size0.size()-2]; ++j)
-                pnode->t(j, i) = child0->t(i,j);
+                pnode->tensor()(j, i) = child0->tensor()(i,j);
           } else if (dim0 == 1) {
             for (size_type i = 0; i < mi.back(); ++i)
-              pnode->t(0, i) = child0->t[i];
+              pnode->tensor()(0, i) = child0->tensor()[i];
           }
           tree.clear_children(pnode);
         } else if (child0->node_type == GA_NODE_ZERO) {
           pnode->node_type = GA_NODE_ZERO;
-          gmm::clear(pnode->t.as_vector());
+          gmm::clear(pnode->tensor().as_vector());
           tree.clear_children(pnode);
         }
         break;
 
       case GA_SYM: case GA_SKEW:
-        if (dim0 != 2 || size0.back() != size0[size0.size()-2])
+        if (child0->tensor_proper_size() != 1 &&
+            (dim0 != 2 || size0.back() != size0[size0.size()-2]))
           ga_throw_error(expr, pnode->pos, "Sym and Skew operators are for "
                          "square matrices only.");
         mi = size0;
@@ -6963,7 +8797,7 @@ namespace getfem {
             { tree.replace_node_by_child(pnode, 0); pnode = child0; break; }
           else {
             pnode->node_type = GA_NODE_ZERO;
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             tree.clear_children(pnode);
             break;
           }
@@ -6983,13 +8817,15 @@ namespace getfem {
           for (size_type i = 0; i < mi.back(); ++i)
             for (size_type j = 0; j < mi.back(); ++j)
               if (pnode->op_type == GA_SYM)
-                pnode->t(j, i) = 0.5*(child0->t(j,i) + child0->t(i,j));
+                pnode->tensor()(j, i) = 0.5*(child0->tensor()(j,i)
+					     + child0->tensor()(i,j));
               else
-                pnode->t(j, i) = 0.5*(child0->t(j,i) - child0->t(i,j));
+                pnode->tensor()(j, i) = 0.5*(child0->tensor()(j,i)
+					     - child0->tensor()(i,j));
           tree.clear_children(pnode);
         } else if (child0->node_type == GA_NODE_ZERO) {
           pnode->node_type = GA_NODE_ZERO;
-          gmm::clear(pnode->t.as_vector());
+          gmm::clear(pnode->tensor().as_vector());
           tree.clear_children(pnode);
         }
         break;
@@ -7020,16 +8856,16 @@ namespace getfem {
             pnode->node_type = GA_NODE_CONSTANT;
             pnode->test_function_type = 0;
             if (dim0 == 2) {
-              pnode->t[0] = scalar_type(0);
+              pnode->tensor()[0] = scalar_type(0);
               for (size_type i = 0; i < N; ++i)
-                pnode->t[0] += child0->t(i,i);
+                pnode->tensor()[0] += child0->tensor()(i,i);
             } else {
-              pnode->t[0] += child0->t[0];
+              pnode->tensor()[0] += child0->tensor()[0];
             }
             tree.clear_children(pnode);
           } else if (child0->node_type == GA_NODE_ZERO) {
             pnode->node_type = GA_NODE_ZERO;
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             tree.clear_children(pnode);
           }
         }
@@ -7047,7 +8883,7 @@ namespace getfem {
 
           if (child0->tensor_proper_size() == 1) {
             pnode->node_type = GA_NODE_ZERO;
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             tree.clear_children(pnode);
             break;
           }
@@ -7065,18 +8901,19 @@ namespace getfem {
             pnode->test_function_type = 0;
             if (dim0 == 2) {
               scalar_type tr(0);
-              gmm::copy(child0->t.as_vector(), pnode->t.as_vector());
+              gmm::copy(child0->tensor().as_vector(),
+			pnode->tensor().as_vector());
               for (size_type i = 0; i < N; ++i)
-                tr += child0->t(i,i);
+                tr += child0->tensor()(i,i);
               for (size_type i = 0; i < N; ++i)
-                pnode->t(i,i) -= tr / scalar_type(N);
+                pnode->tensor()(i,i) -= tr / scalar_type(N);
             } else {
-              pnode->t[0] = scalar_type(0);
+              pnode->tensor()[0] = scalar_type(0);
             }
             tree.clear_children(pnode);
           } else if (child0->node_type == GA_NODE_ZERO) {
             pnode->node_type = GA_NODE_ZERO;
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             tree.clear_children(pnode);
           }
         }
@@ -7095,13 +8932,13 @@ namespace getfem {
           if (all_cte) {
             pnode->node_type = GA_NODE_CONSTANT;
             cout << "Print constant term "; ga_print_node(child0, cout);
-            cout << ": " << pnode->t << endl;
+            cout << ": " << pnode->tensor() << endl;
             tree.clear_children(pnode);
           } else if (child0->node_type == GA_NODE_ZERO) {
             pnode->node_type = GA_NODE_ZERO;
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             cout << "Print zero term "; ga_print_node(child0, cout);
-            cout << ": " << pnode->t << endl;
+            cout << ": " << pnode->tensor() << endl;
             tree.clear_children(pnode);
           }
         }
@@ -7128,17 +8965,17 @@ namespace getfem {
 
           if (all_cte) {
             pnode->node_type = GA_NODE_CONSTANT;
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             size_type k = 0;
-            for (size_type i = 0, j = 0; i < child0->t.size(); ++i) {
-             pnode->t[j] += child0->t[i] * child1->t[k];
-             ++j; if (j == pnode->t.size()) { j = 0; ++k; }
+            for (size_type i = 0, j = 0; i < child0->tensor().size(); ++i) {
+             pnode->tensor()[j] += child0->tensor()[i] * child1->tensor()[k];
+             ++j; if (j == pnode->tensor().size()) { j = 0; ++k; }
             }
-            GMM_ASSERT1(k == child1->t.size(), "Internal error");
+            GMM_ASSERT1(k == child1->tensor().size(), "Internal error");
             tree.clear_children(pnode);
           } else {
             if (child0->tensor_is_zero() || child1->tensor_is_zero()) {
-              gmm::clear(pnode->t.as_vector());
+              gmm::clear(pnode->tensor().as_vector());
               pnode->node_type = GA_NODE_ZERO;
               tree.clear_children(pnode);
             }
@@ -7172,17 +9009,17 @@ namespace getfem {
           }
           if (all_cte) {
             pnode->node_type = GA_NODE_CONSTANT;
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             size_type k = 0;
-            for (size_type i = 0, j = 0; i < child0->t.size(); ++i) {
-             pnode->t[j] += child0->t[i] * child1->t[k];
-             ++j; if (j == pnode->t.size()) { j = 0; ++k; }
+            for (size_type i = 0, j = 0; i < child0->tensor().size(); ++i) {
+             pnode->tensor()[j] += child0->tensor()[i] * child1->tensor()[k];
+             ++j; if (j == pnode->tensor().size()) { j = 0; ++k; }
             }
-            GMM_ASSERT1(k == child1->t.size(), "Internal error");
+            GMM_ASSERT1(k == child1->tensor().size(), "Internal error");
             tree.clear_children(pnode);
           } else {
             if (child0->tensor_is_zero() || child1->tensor_is_zero()) {
-              gmm::clear(pnode->t.as_vector());
+              gmm::clear(pnode->tensor().as_vector());
               pnode->node_type = GA_NODE_ZERO;
               tree.clear_children(pnode);
             }
@@ -7194,29 +9031,31 @@ namespace getfem {
         if (all_cte) {
           pnode->node_type = GA_NODE_CONSTANT;
           pnode->test_function_type = 0;
-          if (child0->t.size() == 1 && child1->t.size() == 1) {
+          if (child0->tensor().size() == 1 && child1->tensor().size() == 1) {
             pnode->init_scalar_tensor
-              (child0->t[0] * child1->t[0]);
-          } else if (child0->t.size() == 1) {
+              (child0->tensor()[0] * child1->tensor()[0]);
+          } else if (child0->tensor().size() == 1) {
             pnode->t = child1->t;
-            gmm::scale(pnode->t.as_vector(), scalar_type(child0->t[0]));
-          } else if (child1->t.size() == 1) {
+            gmm::scale(pnode->tensor().as_vector(),
+		       scalar_type(child0->tensor()[0]));
+          } else if (child1->tensor().size() == 1) {
             pnode->t = child0->t;
-            gmm::scale(pnode->t.as_vector(), scalar_type(child1->t[0]));
+            gmm::scale(pnode->tensor().as_vector(),
+		       scalar_type(child1->tensor()[0]));
           } else {
             if (dim0+dim1 > 6)
               ga_throw_error(expr, pnode->pos, "Unauthorized "
                               "tensor multiplication.");
             for (size_type i = 0; i < dim0; ++i)
-              mi.push_back(child0->t.size(i));
+              mi.push_back(child0->tensor().size(i));
             for (size_type i = 0; i < dim1; ++i)
-              mi.push_back(child1->t.size(i));
+              mi.push_back(child1->tensor().size(i));
             pnode->t.adjust_sizes(mi);
-            size_type n0 = child0->t.size();
-            size_type n1 = child1->t.size();
+            size_type n0 = child0->tensor().size();
+            size_type n1 = child1->tensor().size();
             for (size_type i = 0; i < n0; ++i)
               for (size_type j = 0; j < n1; ++j)
-                pnode->t[i+j*n0] = child0->t[i] * child1->t[j];
+                pnode->tensor()[i+j*n0]=child0->tensor()[i]*child1->tensor()[j];
           }
           tree.clear_children(pnode);
         } else {
@@ -7227,7 +9066,7 @@ namespace getfem {
             if (child0->tensor_proper_size() == 1) {
               for (size_type i = 0; i < dim1; ++i)
                 mi.push_back(child1->tensor_proper_size(i));
-            } else if (child1->t.size() == 1) {
+            } else if (child1->tensor().size() == 1) {
               for (size_type i = 0; i < dim0; ++i)
                 mi.push_back(child0->tensor_proper_size(i));
             } else {
@@ -7242,7 +9081,7 @@ namespace getfem {
             pnode->t.adjust_sizes(mi);
           }
           if (child0->tensor_is_zero() || child1->tensor_is_zero()) {
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             pnode->node_type = GA_NODE_ZERO;
             tree.clear_children(pnode);
           }
@@ -7255,57 +9094,59 @@ namespace getfem {
           pnode->test_function_type = 0;
           if (child0->tensor_proper_size() == 1 &&
               child1->tensor_proper_size() == 1) {
-            pnode->init_scalar_tensor(child0->t[0]*child1->t[0]);
+            pnode->init_scalar_tensor(child0->tensor()[0]*child1->tensor()[0]);
           } else if (child0->tensor_proper_size() == 1) {
             pnode->t = child1->t;
-            gmm::scale(pnode->t.as_vector(), child0->t[0]);
+            gmm::scale(pnode->tensor().as_vector(), child0->tensor()[0]);
           } else if (child1->tensor_proper_size() == 1) {
             pnode->t = child0->t;
-            gmm::scale(pnode->t.as_vector(), child1->t[0]);
+            gmm::scale(pnode->tensor().as_vector(), child1->tensor()[0]);
           } else if (dim0 == 2 && dim1 == 1) {
-            size_type m = child0->t.size(0), n = child0->t.size(1);
-            if (n != child1->t.size(0))
+            size_type m=child0->tensor().size(0), n=child0->tensor().size(1);
+            if (n != child1->tensor().size(0))
               ga_throw_error(expr, pnode->pos,
                              "Incompatible sizes in matrix-vector "
                              "multiplication (" << n << " != "
-                             << child1->t.size(0) << ").");
+                             << child1->tensor().size(0) << ").");
             pnode->init_vector_tensor(m);
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             for (size_type i = 0; i < m; ++i)
               for (size_type j = 0; j < n; ++j)
-                pnode->t[i] += child0->t(i,j) * child1->t[j];
+                pnode->tensor()[i] += child0->tensor()(i,j)*child1->tensor()[j];
           } else if (dim0 == 2 && dim1 == 2) {
-            size_type m = child0->t.size(0);
-            size_type n = child0->t.size(1);
-            size_type p = child1->t.size(1);
-            if (n != child1->t.size(0))
+            size_type m = child0->tensor().size(0);
+            size_type n = child0->tensor().size(1);
+            size_type p = child1->tensor().size(1);
+            if (n != child1->tensor().size(0))
               ga_throw_error(expr, pnode->pos,
                              "Incompatible sizes in matrix-matrix "
                              "multiplication (" << n << " != "
-                             << child1->t.size(0) << ").");
+                             << child1->tensor().size(0) << ").");
             pnode->init_matrix_tensor(m,p);
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             for (size_type i = 0; i < m; ++i)
               for (size_type j = 0; j < n; ++j)
                 for (size_type k = 0; k < p; ++k)
-                  pnode->t(i,k) += child0->t(i,j) * child1->t(j,k);
+                  pnode->tensor()(i,k) += child0->tensor()(i,j)
+		    * child1->tensor()(j,k);
           }
           else if (dim0 == 4 && dim1 == 2) {
-            size_type m = child0->t.size(0), n = child0->t.size(1);
-            size_type o = child0->t.size(2), p = child0->t.size(3);
-            if (o != child1->t.size(0) || p != child1->t.size(1))
+            size_type m=child0->tensor().size(0), n=child0->tensor().size(1);
+            size_type o=child0->tensor().size(2), p=child0->tensor().size(3);
+            if (o != child1->tensor().size(0) || p != child1->tensor().size(1))
               ga_throw_error(expr, pnode->pos,
                              "Incompatible sizes in tensor-matrix "
                              "multiplication (" << o << "," << p << " != "
-                             << child1->t.size(0) << "," << child1->t.size(1)
-                             << ").");
+                             << child1->tensor().size(0) << ","
+			     << child1->tensor().size(1) << ").");
             pnode->init_matrix_tensor(m,n);
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             for (size_type i = 0; i < m; ++i)
               for (size_type j = 0; j < n; ++j)
                 for (size_type k = 0; k < o; ++k)
                   for (size_type l = 0; l < p; ++l)
-                    pnode->t(i,j) += child0->t(i,j,k,l) * child1->t(k,l);
+                    pnode->tensor()(i,j) += child0->tensor()(i,j,k,l)
+		      * child1->tensor()(k,l);
           } else ga_throw_error(expr, pnode->pos,
                                  "Unauthorized multiplication.");
           tree.clear_children(pnode);
@@ -7365,15 +9206,17 @@ namespace getfem {
           pnode->t.adjust_sizes(mi);
           // Simplifications
           if (child0->tensor_is_zero() || child1->tensor_is_zero()) {
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             pnode->node_type = GA_NODE_ZERO;
             tree.clear_children(pnode);
           } else if (child0->node_type == GA_NODE_CONSTANT &&
-                     child0->t.size() == 1 && child0->t[0] == scalar_type(1)) {
+                     child0->tensor().size() == 1 &&
+		     child0->tensor()[0] == scalar_type(1)) {
             tree.replace_node_by_child(pnode, 1);
             pnode = child1;
           } else if (child1->node_type == GA_NODE_CONSTANT &&
-                     child1->t.size() == 1 && child1->t[0] == scalar_type(1)) {
+                     child1->tensor().size() == 1 &&
+		     child1->tensor()[0] == scalar_type(1)) {
             tree.replace_node_by_child(pnode, 0);
             pnode = child0;
           }
@@ -7389,7 +9232,7 @@ namespace getfem {
           ga_throw_error(expr, pnode->pos,
                          "Division by test functions is not allowed.");
         if (child1->node_type == GA_NODE_CONSTANT &&
-            child1->t[0] == scalar_type(0))
+            child1->tensor()[0] == scalar_type(0))
           ga_throw_error(expr, pnode->children[1]->pos, "Division by zero");
 
         pnode->t = child0->t;
@@ -7405,15 +9248,16 @@ namespace getfem {
           pnode->node_type = GA_NODE_CONSTANT;
           pnode->t = pnode->children[0]->t;
           pnode->test_function_type = 0;
-          gmm::scale(pnode->t.as_vector(),
-                     scalar_type(1) / pnode->children[1]->t[0]);
+          gmm::scale(pnode->tensor().as_vector(),
+                     scalar_type(1) / pnode->children[1]->tensor()[0]);
           tree.clear_children(pnode);
         } else if (child0->tensor_is_zero()) {
-          gmm::clear(pnode->t.as_vector());
+          gmm::clear(pnode->tensor().as_vector());
           pnode->node_type = GA_NODE_ZERO;
           tree.clear_children(pnode);
         } else if (child1->node_type == GA_NODE_CONSTANT &&
-                   child1->t.size() == 1 && child1->t[0] == scalar_type(1)) {
+                   child1->tensor().size() == 1 &&
+		   child1->tensor()[0] == scalar_type(1)) {
           tree.replace_node_by_child(pnode, 0);
           pnode = child0;
         }
@@ -7465,7 +9309,7 @@ namespace getfem {
         if (pnode->test_function_type >= 3) mi.push_back(2);
         if (nbc1 == 1 && nbc2 == 1 && nbc3 == 1 && nbl == 1) {
           pnode->t.adjust_sizes(mi);
-          if (all_cte) pnode->t[0] = child0->t[0];
+          if (all_cte) pnode->tensor()[0] = child0->tensor()[0];
         } else {
           mi.push_back(nbl);
           if (nbc3 != 1) mi.push_back(nbc3);
@@ -7476,22 +9320,23 @@ namespace getfem {
             size_type n = 0;
             if (nbc1 == 1 && nbc2 == 1 && nbc3 == 1)
               for (size_type i = 0; i < nbl; ++i)
-                pnode->t[i] = pnode->children[i]->t[0];
+                pnode->tensor()[i] = pnode->children[i]->tensor()[0];
             else if (nbc2 == 1 && nbc3 == 1) // TODO: verify order
               for (size_type i = 0; i < nbl; ++i)
                 for (size_type j = 0; j < nbc1; ++j)
-                  pnode->t(i,j) = pnode->children[n++]->t[0];
+                  pnode->tensor()(i,j) = pnode->children[n++]->tensor()[0];
             else if (nbc3 == 1) // TODO: verify order
               for (size_type i = 0; i < nbl; ++i)
                 for (size_type j = 0; j < nbc2; ++j)
                   for (size_type k = 0; k < nbc1; ++k)
-                    pnode->t(i,j,k) = pnode->children[n++]->t[0];
+                    pnode->tensor()(i,j,k) = pnode->children[n++]->tensor()[0];
             else // TODO: verify order
               for (size_type i = 0; i < nbl; ++i)
                 for (size_type j = 0; j < nbc3; ++j)
                   for (size_type k = 0; k < nbc2; ++k)
                     for (size_type l = 0; l < nbc1; ++l)
-                      pnode->t(i,j,k,l) = pnode->children[n++]->t[0];
+                      pnode->tensor()(i,j,k,l)
+			= pnode->children[n++]->tensor()[0];
           }
         }
         if (all_cte) tree.clear_children(pnode);
@@ -7590,9 +9435,9 @@ namespace getfem {
             pnode->node_type = GA_NODE_CONSTANT;
             pnode->init_scalar_tensor(scalar_type(meshdim));
           } else if (!name.compare("timestep")) {
-	    pnode->node_type = GA_NODE_CONSTANT;
+            pnode->node_type = GA_NODE_CONSTANT;
             pnode->init_scalar_tensor(scalar_type(workspace.get_time_step()));
-	  }
+          }
         } else if (PREDEF_OPERATORS.tab.find(name)
                    != PREDEF_OPERATORS.tab.end()) {
           // Nonlinear operator found
@@ -7683,7 +9528,7 @@ namespace getfem {
             if (n == 1) {
               if (test) {
                 pnode->init_vector_tensor(1);
-                pnode->t[0]=scalar_type(1);
+                pnode->tensor()[0]=scalar_type(1);
               }
               else pnode->init_scalar_tensor(workspace.value(name)[0]);
             } else {
@@ -7691,10 +9536,11 @@ namespace getfem {
                 pnode->init_matrix_tensor(n,n);
                 for (size_type i = 0; i < n; ++i)
                   for (size_type j = 0; j < n; ++j)
-                    pnode->t(i,j) = (i == j) ? scalar_type(1) : scalar_type(0);
+                    pnode->tensor()(i,j)
+		      = ((i == j) ? scalar_type(1) : scalar_type(0));
               } else {
-                pnode->init_vector_tensor(n);
-                gmm::copy(workspace.value(name), pnode->t.as_vector());
+                pnode->t.adjust_sizes(workspace.qdims(name));
+                gmm::copy(workspace.value(name), pnode->tensor().as_vector());
               }
             }
           } else if (!test && imd) {
@@ -7780,10 +9626,11 @@ namespace getfem {
         if (pnode->children.size() != 2)
           ga_throw_error(expr, child1->pos, "X stands for the coordinates on "
                          "the real elements. It accepts only one index.");
-        if (!(child1->node_type == GA_NODE_CONSTANT) || child1->t.size() != 1)
+        if (!(child1->node_type == GA_NODE_CONSTANT) ||
+	    child1->tensor().size() != 1)
           ga_throw_error(expr, child1->pos, "Index for X has to be constant "
                          "and of size 1.");
-        child0->nbc1 = size_type(round(child1->t[0]));
+        child0->nbc1 = size_type(round(child1->tensor()[0]));
         if (child0->nbc1 == 0 || child0->nbc1 > meshdim)
           ga_throw_error(expr, child1->pos, "Index for X not convenient. "
                          "Found " << child0->nbc1 << " with meshdim = "
@@ -7814,7 +9661,7 @@ namespace getfem {
           if (pnode->children[i]->node_type != GA_NODE_CONSTANT)
             ga_throw_error(expr, pnode->children[i]->pos, "Reshape sizes "
                            "should be constant positive integers.");
-          mi.push_back(size_type(round(pnode->children[i]->t[0])));
+          mi.push_back(size_type(round(pnode->children[i]->tensor()[0])));
           if (mi.back() == 0)
             ga_throw_error(expr, pnode->children[i]->pos, "Wrong zero size "
                            "for Reshape.");
@@ -7822,7 +9669,7 @@ namespace getfem {
         size_type total_size(1);
         for (size_type i = 0; i < mi.size(); ++i)
           total_size *= mi[i];
-        if (total_size != pnode->t.size())
+        if (total_size != pnode->tensor().size())
            ga_throw_error(expr, pnode->pos, "Invalid sizes for reshape.");
         pnode->t.adjust_sizes(mi);
 
@@ -7859,8 +9706,8 @@ namespace getfem {
         if (child1->tensor_order() > 2 || child2->tensor_order() > 2)
           ga_throw_error(expr, pnode->pos, "Sorry, function can be applied "
                          "to scalar, vector and matrices only.");
-        size_type s1 = child1->t.size();
-        size_type s2 = (nbargs == 2) ? child2->t.size() : s1;
+        size_type s1 = child1->tensor().size();
+        size_type s2 = (nbargs == 2) ? child2->tensor().size() : s1;
         if (s1 != s2 && (s1 != 1 || s2 != 1))
           ga_throw_error(expr, pnode->pos,
                          "Invalid argument size for a scalar function. "
@@ -7885,17 +9732,20 @@ namespace getfem {
           pnode->node_type = GA_NODE_CONSTANT;
           if (nbargs == 1) {
             for (size_type i = 0; i < s1; ++i)
-              pnode->t[i] = F(child1->t[i]);
+              pnode->tensor()[i] = F(child1->tensor()[i]);
           } else {
             if (s1 == s2) {
               for (size_type i = 0; i < s1; ++i)
-                pnode->t[i] = F(child1->t[i], child2->t[i]);
+                pnode->tensor()[i] = F(child1->tensor()[i],
+				       child2->tensor()[i]);
             } else if (s1 == 1) {
               for (size_type i = 0; i < s2; ++i)
-                pnode->t[i] = F(child1->t[0], child2->t[i]);
+                pnode->tensor()[i] = F(child1->tensor()[0],
+				       child2->tensor()[i]);
             } else {
               for (size_type i = 0; i < s1; ++i)
-                pnode->t[i] = F(child1->t[i], child2->t[0]);
+                pnode->tensor()[i] = F(child1->tensor()[i],
+				       child2->tensor()[0]);
             }
           }
           tree.clear_children(pnode);
@@ -7917,7 +9767,7 @@ namespace getfem {
                            "function can only be a variable name.");
           pnode->node_type = GA_NODE_CONSTANT;
           pnode->init_scalar_tensor(scalar_type(workspace.qdim(child1->name)));
-          if (pnode->t[0] <= 0)
+          if (pnode->tensor()[0] <= 0)
             ga_throw_error(expr, pnode->pos,
                            "Invalid null size of variable");
         } else if (!(child0->name.compare("qdims"))) {
@@ -7937,11 +9787,11 @@ namespace getfem {
           if (mii.size() >= 1) {
             pnode->init_vector_tensor(mii.size());
             for (size_type i = 0; i < mii.size(); ++i)
-              pnode->t[i] = scalar_type(mii[i]);
+              pnode->tensor()[i] = scalar_type(mii[i]);
           }
         } else if (!(child0->name.compare("Id"))) {
           bool valid = (child1->node_type == GA_NODE_CONSTANT);
-          int n = valid ? int(round(child1->t[0])) : -1;
+          int n = valid ? int(round(child1->tensor()[0])) : -1;
           if (n <= 0 || n > 100 || child1->tensor_order() > 0)
             ga_throw_error(expr, pnode->pos, "The argument of Id "
                            "should be a (small) positive integer.");
@@ -7950,7 +9800,7 @@ namespace getfem {
             pnode->init_scalar_tensor(scalar_type(1));
           else {
             pnode->init_matrix_tensor(n,n);
-            for (int i = 0; i < n; ++i) pnode->t(i,i) = scalar_type(1);
+            for (int i = 0; i < n; ++i) pnode->tensor()(i,i) = scalar_type(1);
           }
         } else ga_throw_error(expr, pnode->children[0]->pos,
                               "Unknown special function.");
@@ -7966,7 +9816,7 @@ namespace getfem {
         for (size_type i = 1; i < pnode->children.size(); ++i) {
           all_cte = all_cte
             && (pnode->children[i]->node_type == GA_NODE_CONSTANT);
-          args.push_back(&(pnode->children[i]->t));
+          args.push_back(&(pnode->children[i]->tensor()));
           if (pnode->children[i]->node_type == GA_NODE_ALLINDICES)
             ga_throw_error(expr, pnode->children[i]->pos,
                            "Colon operator is not allowed in nonlinear "
@@ -8000,7 +9850,7 @@ namespace getfem {
           pnode->t.adjust_sizes(mi);
           if (all_cte) {
             pnode->node_type = GA_NODE_CONSTANT;
-            OP.derivative(args, child0->der1, pnode->t);
+            OP.derivative(args, child0->der1, pnode->tensor());
             tree.clear_children(pnode);
           }
         } else if (child0->der1 && child0->der2) {
@@ -8012,14 +9862,14 @@ namespace getfem {
           if (all_cte) {
             pnode->node_type = GA_NODE_CONSTANT;
             OP.second_derivative(args, child0->der1, child0->der2,
-                                          pnode->t);
+				 pnode->tensor());
             tree.clear_children(pnode);
           }
         } else {
           pnode->t.adjust_sizes(mi);
           if (all_cte) {
             pnode->node_type = GA_NODE_CONSTANT;
-            OP.value(args, pnode->t);
+            OP.value(args, pnode->tensor());
             tree.clear_children(pnode);
           }
         }
@@ -8028,13 +9878,14 @@ namespace getfem {
         // Access to components of a tensor
         all_cte = (child0->node_type == GA_NODE_CONSTANT);
         // cout << "child0->tensor_order() = " << child0->tensor_order();
-        // cout << endl << "child0->t.sizes() = " << child0->t.sizes() << endl;
+        // cout << endl << "child0->t.sizes() = "
+	//      << child0->t.sizes() << endl;
         if (pnode->children.size() != child0->tensor_order() + 1)
           ga_throw_error(expr, pnode->pos, "Bad number of indices.");
         for (size_type i = 1; i < pnode->children.size(); ++i)
           if (pnode->children[i]->node_type != GA_NODE_ALLINDICES &&
               (pnode->children[i]->node_type != GA_NODE_CONSTANT ||
-               pnode->children[i]->t.size() != 1))
+               pnode->children[i]->tensor().size() != 1))
             ga_throw_error(expr, pnode->children[i]->pos,
                             "Indices should be constant integers or colon.");
 
@@ -8045,7 +9896,7 @@ namespace getfem {
             indices.push_back(i);
             mi1[i] = 0;
           } else {
-            mi1[i] = size_type(round(pnode->children[i+1]->t[0])-1);
+            mi1[i] = size_type(round(pnode->children[i+1]->tensor()[0])-1);
             if (mi1[i] >= child0->tensor_proper_size(i))
               ga_throw_error(expr, pnode->children[i+1]->pos,
                              "Index out of range, " << mi1[i]+1
@@ -8073,12 +9924,12 @@ namespace getfem {
             for (size_type j = 0; j < mi2.size(); ++j) {
               mi1[indices[j]] = mi3[j];
             }
-            pnode->t(mi3) = pnode->children[0]->t(mi1);
+            pnode->tensor()(mi3) = pnode->children[0]->tensor()(mi1);
           }
           tree.clear_children(pnode);
         } else {
           if (child0->tensor_is_zero() || child1->tensor_is_zero()) {
-            gmm::clear(pnode->t.as_vector());
+            gmm::clear(pnode->tensor().as_vector());
             pnode->node_type = GA_NODE_ZERO;
             tree.clear_children(pnode);
           }
@@ -8391,7 +10242,7 @@ namespace getfem {
   // Extract the order zero term
   //=========================================================================
 
-  std::string ga_workspace::extract_order0_term(void) {
+  std::string ga_workspace::extract_order0_term() {
     std::string term;
     for (size_type i = 0; i < trees.size(); ++i) {
       ga_workspace::tree_description &td =  trees[i];
@@ -9012,7 +10863,8 @@ namespace getfem {
       case GA_DIV: case GA_DOTDIV:
         if (mark1) {
           if (pnode->children[0]->node_type == GA_NODE_CONSTANT)
-            gmm::scale(pnode->children[0]->t.as_vector(), scalar_type(-1));
+            gmm::scale(pnode->children[0]->tensor().as_vector(),
+		       scalar_type(-1));
           else {
             if (mark0) {
               tree.duplicate_with_subtraction(pnode);
@@ -9077,7 +10929,7 @@ namespace getfem {
           switch (F.dtype()) {
           case 0:
             GMM_ASSERT1(false, "Cannot derive function " << child0->name
-                        << ". No derivative provided or not derivable function.");
+                     << ". No derivative provided or not derivable function.");
           case 1:
             child0->name = F.derivative1();
             break;
@@ -9088,13 +10940,14 @@ namespace getfem {
                 if (F.dtype() == 2)
                   ga_define_function(child0->name, 1, F.derivative1());
                 else {
-                  std::string expr = ga_derivative_scalar_function(F.expr(),"t");
+                  std::string expr=ga_derivative_scalar_function(F.expr(),"t");
                   ga_define_function(child0->name, 1, expr);
                 }
               }
               // Inline extension if the derivative is affine (for instance
               // for sqr)
-              ga_predef_function_tab::const_iterator itp = PREDEF_FUNCTIONS.find(child0->name);
+              ga_predef_function_tab::const_iterator
+		itp = PREDEF_FUNCTIONS.find(child0->name);
               const ga_predef_function &Fp = itp->second;
               if (Fp.is_affine("t")) {
                 scalar_type b = Fp(scalar_type(0));
@@ -9102,7 +10955,8 @@ namespace getfem {
                 pnode->node_type = GA_NODE_OP;
                 pnode->op_type = GA_MULT;
                 child0->init_scalar_tensor(a);
-                child0->node_type = (a == scalar_type(0)) ? GA_NODE_ZERO : GA_NODE_CONSTANT;
+                child0->node_type = ((a == scalar_type(0)) ?
+				     GA_NODE_ZERO : GA_NODE_CONSTANT);
                 if (b != scalar_type(0)) {
                   tree.insert_node(pnode, GA_NODE_OP);
                   pnode->parent->op_type = (b > 0) ? GA_PLUS : GA_MINUS;
@@ -9110,7 +10964,8 @@ namespace getfem {
                   pga_tree_node pnode_cte = pnode->parent->children[1];
                   pnode_cte->node_type = GA_NODE_CONSTANT;
                   pnode_cte->t = pnode->t;
-                  std::fill(pnode_cte->t.begin(), pnode_cte->t.end(), gmm::abs(b));
+                  std::fill(pnode_cte->tensor().begin(),
+			    pnode_cte->tensor().end(), gmm::abs(b));
                   pnode = pnode->parent;
                 }
               }
@@ -9434,7 +11289,8 @@ namespace getfem {
     } else if (gis.extended_vars.find(varname)==gis.extended_vars.end()) {
       const mesh_fem *mf = workspace.associated_mf(varname);
       if (mf->is_reduced()) {
-        base_vector U(mf->nb_basic_dof());
+        auto n = (mf->get_qdim() == 1) ? workspace.qdim(varname) : 1;
+        base_vector U(mf->nb_basic_dof() * n);
         mf->extend_vector(workspace.value(varname), U);
         gis.really_extended_vars[varname] = U;
         gis.extended_vars[varname] = &(gis.really_extended_vars[varname]);
@@ -9468,7 +11324,6 @@ namespace getfem {
         pnode->node_type == GA_NODE_SPEC_FUNC ||
         pnode->node_type == GA_NODE_CONSTANT ||
         pnode->node_type == GA_NODE_ALLINDICES ||
-        // pnode->node_type == GA_NODE_ZERO ||   // zero nodes can still have test functions
         pnode->node_type == GA_NODE_RESHAPE) return;
 
     // cout << "compiling "; ga_print_node(pnode, cout); cout << endl;
@@ -9480,6 +11335,7 @@ namespace getfem {
     const mesh_fem *mf1 = 0, *mf2 = 0;
     const mesh_fem **mfg1 = 0, **mfg2 = 0;
     fem_interpolation_context *pctx1 = 0, *pctx2 = 0;
+    bool tensor_to_clear = false;
 
     if (pnode->test_function_type) {
       if (pnode->name_test1.size())
@@ -9514,29 +11370,47 @@ namespace getfem {
       }
     }
 
+    // Produce a resize instruction which is stored if no equivalent node is
+    // detected and is the mesh is not uniform.
+    pnode->t.set_to_original(); pnode->t.set_sparsity(0, 0);
+    bool is_uniform = false;
     if (pnode->test_function_type == 1) {
       if (mf1 || mfg1)
         pgai = std::make_shared<ga_instruction_first_ind_tensor>
-          (pnode->t, *pctx1, pnode->qdim1, mf1, mfg1);
+          (pnode->tensor(), *pctx1, pnode->qdim1, mf1, mfg1);
+      if (mf1 && mf1->is_uniform())
+        { is_uniform = true; pctx1->invalid_convex_num(); }
     } else if (pnode->test_function_type == 2) {
       if (mf2 || mfg2)
         pgai = std::make_shared<ga_instruction_first_ind_tensor>
-          (pnode->t, *pctx2, pnode->qdim2, mf2, mfg2);
+          (pnode->tensor(), *pctx2, pnode->qdim2, mf2, mfg2);
+      if (mf2 && mf2->is_uniform())
+        { is_uniform = true; pctx2->invalid_convex_num(); }
     } else if (pnode->test_function_type == 3) {
-      if ((mf1 || mfg1) && (mf2 || mfg2))
+      if ((mf1 || mfg1) && (mf2 || mfg2)) {
         pgai = std::make_shared<ga_instruction_two_first_ind_tensor>
-          (pnode->t, *pctx1, *pctx2, pnode->qdim1, mf1, mfg1,
+          (pnode->tensor(), *pctx1, *pctx2, pnode->qdim1, mf1, mfg1,
            pnode->qdim2, mf2, mfg2);
-      else if (mf1 || mfg1)
+        if (mf1 && mf1->is_uniform() && mf2 && mf2->is_uniform()) {
+          is_uniform = true;
+          pctx1->invalid_convex_num();
+          pctx2->invalid_convex_num();
+        } 
+      } else if (mf1 || mfg1) {
         pgai = std::make_shared<ga_instruction_first_ind_tensor>
-          (pnode->t, *pctx1, pnode->qdim1, mf1, mfg1);
-      else if (mf2 || mfg2)
+          (pnode->tensor(), *pctx1, pnode->qdim1, mf1, mfg1);
+        if (mf1 && mf1->is_uniform())
+          { is_uniform = true; pctx1->invalid_convex_num(); }
+      } else if (mf2 || mfg2) {
         pgai = std::make_shared<ga_instruction_second_ind_tensor>
-          (pnode->t, *pctx2, pnode->qdim2, mf2, mfg2);
+          (pnode->tensor(), *pctx2, pnode->qdim2, mf2, mfg2);
+        if (mf2 && mf2->is_uniform())
+          { is_uniform = true; pctx2->invalid_convex_num(); }
+      }
     }
-    if (pgai) rmi.instructions.push_back(std::move(pgai));
 
-    // Optimization: detect if an equivalent node has already been compiled
+    // Optimization: detects if an equivalent node has already been compiled
+    pnode->t.set_to_original();
     if (rmi.node_list.find(pnode->hash_value) != rmi.node_list.end()) {
       std::list<pga_tree_node> &node_list = rmi.node_list[pnode->hash_value];
       for (std::list<pga_tree_node>::iterator it = node_list.begin();
@@ -9545,33 +11419,41 @@ namespace getfem {
         // ga_print_node(pnode, cout);
         // cout << " and "; ga_print_node(*it, cout); cout << endl;
         if (sub_tree_are_equal(pnode, *it, workspace, 1)) {
-          // cout << "confirmed no transpose" << endl;
-          if (pnode->t.size() == 1) {
-            pgai = std::make_shared<ga_instruction_copy_scalar>
-              (pnode->t[0], (*it)->t[0]);
-          } else {
-            pgai = std::make_shared<ga_instruction_copy_tensor>
-              (pnode->t, (*it)->t);
-          }
-          rmi.instructions.push_back(std::move(pgai));
+	  pnode->t.set_to_copy((*it)->t);
           return;
         }
         if (sub_tree_are_equal(pnode, *it, workspace, 2)) {
           // cout << "confirmed with transpose" << endl;
           if (pnode->nb_test_functions() == 2) {
+	    if (pgai) { // resize instruction if needed
+	      if (is_uniform)
+		{ pgai->exec(); }
+	      else { rmi.instructions.push_back(std::move(pgai)); }
+	    }
             pgai = std::make_shared<ga_instruction_transpose_test>
-              (pnode->t, (*it)->t);
+              (pnode->tensor(), (*it)->tensor());
+	    rmi.instructions.push_back(std::move(pgai));
           } else {
-            pgai = std::make_shared<ga_instruction_copy_tensor>
-              (pnode->t, (*it)->t);
+	    pnode->t.set_to_copy((*it)->t);
           }
-          rmi.instructions.push_back(std::move(pgai));
           return;
         }
-        cerr << "Detected wrong equivalent nodes: ";
-        ga_print_node(pnode, cerr);
-        cerr << " and "; ga_print_node(*it, cout);
-        cerr << " (no problem, but hash code would be adapted) " << endl;
+        std::stringstream ss;
+        ss << "Detected wrong equivalent nodes: ";
+        ga_print_node(pnode, ss);
+        ss << " and "; ga_print_node(*it, ss);
+        ss << " (no problem, but hash code would be adapted) " << endl;
+        GMM_TRACE2(ss.str());
+      }
+    }
+
+    if (pgai) { // resize instruction if needed and no equivalent node detected
+      if (is_uniform) { pgai->exec(); }
+      else {
+	if (mfg1 || mfg2)
+	  rmi.instructions.push_back(std::move(pgai));
+	else
+	  rmi.elt_instructions.push_back(std::move(pgai));
       }
     }
 
@@ -9592,11 +11474,11 @@ namespace getfem {
       const std::string &intn = pnode->interpolate_name;
       ga_instruction_set::interpolate_info &inin = rmi.interpolate_infos[intn];
       pgai = std::make_shared<ga_instruction_interpolate_filter>
-        (pnode->t, inin, pnode->nbc1,
+        (pnode->tensor(), inin, pnode->nbc1,
          int(rmi.instructions.size() - interpolate_filter_inst));
       rmi.instructions[interpolate_filter_inst].swap(pgai);
       pgai = std::make_shared<ga_instruction_copy_tensor>
-        (pnode->t, pnode->children[0]->t);
+        (pnode->tensor(), pnode->children[0]->tensor());
       rmi.instructions.push_back(std::move(pgai));
       ga_clear_node_list(pnode->children[0], rmi.node_list);
     }
@@ -9622,15 +11504,15 @@ namespace getfem {
       GMM_ASSERT1(!function_case,
                   "No use of X is allowed in scalar functions");
       if (pnode->nbc1) {
-        GA_DEBUG_ASSERT(pnode->t.size() == 1, "dimensions mismatch");
+        GA_DEBUG_ASSERT(pnode->tensor().size() == 1, "dimensions mismatch");
         GMM_ASSERT1(pnode->nbc1 <= m.dim(),
                     "Bad index for X in expression");
         pgai = std::make_shared<ga_instruction_X_component>
-            (pnode->t[0], gis.ctx, pnode->nbc1-1);
+            (pnode->tensor()[0], gis.ctx, pnode->nbc1-1);
       } else {
-        if (pnode->t.size() != m.dim())
+        if (pnode->tensor().size() != m.dim())
           pnode->init_vector_tensor(m.dim());
-        pgai = std::make_shared<ga_instruction_X>(pnode->t, gis.ctx);
+        pgai = std::make_shared<ga_instruction_X>(pnode->tensor(), gis.ctx);
       }
       rmi.instructions.push_back(std::move(pgai));
       break;
@@ -9638,9 +11520,9 @@ namespace getfem {
     case GA_NODE_ELT_SIZE:
       GMM_ASSERT1(!function_case,
                   "No use of element_size is allowed in functions");
-      if (pnode->t.size() != 1) pnode->init_scalar_tensor(0);
+      if (pnode->tensor().size() != 1) pnode->init_scalar_tensor(0);
       pgai = std::make_shared<ga_instruction_element_size>
-        (pnode->t, gis.elt_size);
+        (pnode->tensor(), gis.elt_size);
       gis.need_elt_size = true;
       rmi.instructions.push_back(std::move(pgai));
       break;
@@ -9648,24 +11530,26 @@ namespace getfem {
     case GA_NODE_ELT_K:
       GMM_ASSERT1(!function_case,
                   "No use of element_K is allowed in functions");
-      pgai = std::make_shared<ga_instruction_element_K>(pnode->t, gis.ctx);
+      pgai = std::make_shared<ga_instruction_element_K>(pnode->tensor(),
+							gis.ctx);
       rmi.instructions.push_back(std::move(pgai));
       break;
 
     case GA_NODE_ELT_B:
       GMM_ASSERT1(!function_case,
                   "No use of element_B is allowed in functions");
-      pgai = std::make_shared<ga_instruction_element_B>(pnode->t, gis.ctx);
+      pgai = std::make_shared<ga_instruction_element_B>(pnode->tensor(),
+							gis.ctx);
       rmi.instructions.push_back(std::move(pgai));
       break;
 
     case GA_NODE_NORMAL:
       GMM_ASSERT1(!function_case,
                   "No use of Normal is allowed in functions");
-      if (pnode->t.size() != m.dim())
+      if (pnode->tensor().size() != m.dim())
         pnode->init_vector_tensor(m.dim());
       pgai = std::make_shared<ga_instruction_copy_Normal>
-             (pnode->t, gis.Normal);
+             (pnode->tensor(), gis.Normal);
       rmi.instructions.push_back(std::move(pgai));
       break;
 
@@ -9673,15 +11557,15 @@ namespace getfem {
     case GA_NODE_INTERPOLATE_NORMAL:
       GMM_ASSERT1(!function_case,
                   "No use of Interpolate is allowed in functions");
-      if (pnode->t.size() != m.dim())
+      if (pnode->tensor().size() != m.dim())
         pnode->init_vector_tensor(m.dim());
       if (pnode->node_type == GA_NODE_INTERPOLATE_X)
         pgai = std::make_shared<ga_instruction_copy_small_vect>
-               (pnode->t,
+               (pnode->tensor(),
                 rmi.interpolate_infos[pnode->interpolate_name].pt_y);
       else if (pnode->node_type == GA_NODE_INTERPOLATE_NORMAL)
         pgai = std::make_shared<ga_instruction_copy_Normal>
-               (pnode->t,
+               (pnode->tensor(),
                 rmi.interpolate_infos[pnode->interpolate_name].Normal);
       rmi.instructions.push_back(std::move(pgai));
       break;
@@ -9717,10 +11601,10 @@ namespace getfem {
                     "function expression");
         if (gmm::vect_size(workspace.value(pnode->name)) == 1)
           pgai = std::make_shared<ga_instruction_copy_scalar>
-            (pnode->t[0], (workspace.value(pnode->name))[0]);
+            (pnode->tensor()[0], (workspace.value(pnode->name))[0]);
         else
           pgai = std::make_shared<ga_instruction_copy_vect>
-            (pnode->t.as_vector(), workspace.value(pnode->name));
+            (pnode->tensor().as_vector(), workspace.value(pnode->name));
         rmi.instructions.push_back(std::move(pgai));
       } else {
         const mesh_fem *mf = workspace.associated_mf(pnode->name);
@@ -9728,11 +11612,10 @@ namespace getfem {
 
         if (imd) {
           pgai = std::make_shared<ga_instruction_extract_local_im_data>
-            (pnode->t, *imd, workspace.value(pnode->name), gis.pai, gis.ctx,
-             workspace.qdim(pnode->name));
+            (pnode->tensor(), *imd, workspace.value(pnode->name),
+	     gis.pai, gis.ctx, workspace.qdim(pnode->name));
           rmi.instructions.push_back(std::move(pgai));
         } else {
-
           GMM_ASSERT1(mf, "Internal error");
 
           GMM_ASSERT1(&(mf->linked_mesh()) == &(m),
@@ -9741,31 +11624,31 @@ namespace getfem {
                       "integration method used");
 
           // An instruction for extracting local dofs of the variable.
-          if (rmi.local_dofs.count(pnode->name) == 0 ||
-              !(if_hierarchy.is_compatible
-                (rmi.local_dofs_hierarchy[pnode->name]))) {
+          if (rmi.local_dofs.count(pnode->name) == 0) {
             rmi.local_dofs[pnode->name] = base_vector(1);
-            rmi.local_dofs_hierarchy[pnode->name].push_back(if_hierarchy);
             extend_variable_in_gis(workspace, pnode->name, gis);
             // cout << "local dof of " << pnode->name << endl;
+	    size_type qmult2 = mf->get_qdim();
+	    if (qmult2 > 1 && !(mf->is_uniformly_vectorized()))
+	      qmult2 = size_type(-1);
             pgai = std::make_shared<ga_instruction_slice_local_dofs>
               (*mf, *(gis.extended_vars[pnode->name]), gis.ctx,
-               rmi.local_dofs[pnode->name]);
-            rmi.instructions.push_back(std::move(pgai));
+               rmi.local_dofs[pnode->name],
+	       workspace.qdim(pnode->name) / mf->get_qdim(), qmult2);
+            rmi.elt_instructions.push_back(std::move(pgai));
           }
 
           // An instruction for pfp update
-          if (rmi.pfps.count(mf) == 0 ||
-              !(if_hierarchy.is_compatible(rmi.pfps_hierarchy[mf]))) {
+          if (rmi.pfps.count(mf) == 0) {
             rmi.pfps[mf] = 0;
-            rmi.pfps_hierarchy[mf].push_back(if_hierarchy);
             pgai = std::make_shared<ga_instruction_update_pfp>
               (*mf, rmi.pfps[mf], gis.ctx, gis.fp_pool);
-            rmi.instructions.push_back(std::move(pgai));
+	    if (mf->is_uniform())
+	      rmi.begin_instructions.push_back(std::move(pgai));
+	    else
+              rmi.instructions.push_back(std::move(pgai));
           }
 
-          // At this level Xfem needs some particular storage ...
-
           // An instruction for the base value
           pgai = pga_instruction();
           switch (pnode->node_type) {
@@ -9851,70 +11734,71 @@ namespace getfem {
           switch (pnode->node_type) {
           case GA_NODE_VAL: // --> t(target_dim*Qmult)
             pgai = std::make_shared<ga_instruction_val>
-              (pnode->t, rmi.base[mf],
-               rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
+	      (pnode->tensor(), rmi.base[mf], rmi.local_dofs[pnode->name],
+	       workspace.qdim(pnode->name));
             break;
           case GA_NODE_GRAD: // --> t(target_dim*Qmult,N)
             pgai = std::make_shared<ga_instruction_grad>
-              (pnode->t, rmi.grad[mf],
+              (pnode->tensor(), rmi.grad[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_HESS: // --> t(target_dim*Qmult,N,N)
             pgai = std::make_shared<ga_instruction_hess>
-              (pnode->t, rmi.hess[mf],
+              (pnode->tensor(), rmi.hess[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_DIVERG: // --> t(1)
             pgai = std::make_shared<ga_instruction_diverg>
-              (pnode->t, rmi.grad[mf],
+              (pnode->tensor(), rmi.grad[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_XFEM_PLUS_VAL: // --> t(target_dim*Qmult)
             pgai = std::make_shared<ga_instruction_val>
-              (pnode->t, rmi.xfem_plus_base[mf],
+              (pnode->tensor(), rmi.xfem_plus_base[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_XFEM_PLUS_GRAD: // --> t(target_dim*Qmult,N)
             pgai = std::make_shared<ga_instruction_grad>
-              (pnode->t, rmi.xfem_plus_grad[mf],
+              (pnode->tensor(), rmi.xfem_plus_grad[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_XFEM_PLUS_HESS: // --> t(target_dim*Qmult,N,N)
             pgai = std::make_shared<ga_instruction_hess>
-              (pnode->t, rmi.xfem_plus_hess[mf],
+              (pnode->tensor(), rmi.xfem_plus_hess[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_XFEM_PLUS_DIVERG: // --> t(1)
             pgai = std::make_shared<ga_instruction_diverg>
-              (pnode->t, rmi.xfem_plus_grad[mf],
+              (pnode->tensor(), rmi.xfem_plus_grad[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_XFEM_MINUS_VAL: // --> t(target_dim*Qmult)
             pgai = std::make_shared<ga_instruction_val>
-              (pnode->t, rmi.xfem_minus_base[mf],
+              (pnode->tensor(), rmi.xfem_minus_base[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_XFEM_MINUS_GRAD: // --> t(target_dim*Qmult,N)
             pgai = std::make_shared<ga_instruction_grad>
-              (pnode->t, rmi.xfem_minus_grad[mf],
+              (pnode->tensor(), rmi.xfem_minus_grad[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_XFEM_MINUS_HESS: // --> t(target_dim*Qmult,N,N)
             pgai = std::make_shared<ga_instruction_hess>
-              (pnode->t, rmi.xfem_minus_hess[mf],
+              (pnode->tensor(), rmi.xfem_minus_hess[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_XFEM_MINUS_DIVERG: // --> t(1)
             pgai = std::make_shared<ga_instruction_diverg>
-              (pnode->t, rmi.xfem_minus_grad[mf],
+              (pnode->tensor(), rmi.xfem_minus_grad[mf],
                rmi.local_dofs[pnode->name], workspace.qdim(pnode->name));
             break;
           case GA_NODE_ELEMENTARY_VAL:
             { // --> t(target_dim*Qmult)
               ga_instruction_set::elementary_trans_info &eti
                 = rmi.elementary_trans_infos[pnode->elementary_name];
-              pgai = std::make_shared<ga_instruction_elementary_transformation_val>
-                (pnode->t, rmi.base[mf],
+              pgai =
+		std::make_shared<ga_instruction_elementary_transformation_val>
+                (pnode->tensor(), rmi.base[mf],
                  rmi.local_dofs[pnode->name], workspace.qdim(pnode->name),
                  workspace.elementary_transformation(pnode->elementary_name),
                  *mf, gis.ctx, eti.M, &(eti.mf), eti.icv);
@@ -9924,8 +11808,9 @@ namespace getfem {
             { // --> t(target_dim*Qmult,N)
               ga_instruction_set::elementary_trans_info &eti
                 = rmi.elementary_trans_infos[pnode->elementary_name];
-              pgai = std::make_shared<ga_instruction_elementary_transformation_grad>
-                (pnode->t, rmi.grad[mf],
+              pgai =
+		std::make_shared<ga_instruction_elementary_transformation_grad>
+                (pnode->tensor(), rmi.grad[mf],
                  rmi.local_dofs[pnode->name], workspace.qdim(pnode->name),
                  workspace.elementary_transformation(pnode->elementary_name),
                  *mf, gis.ctx, eti.M, &(eti.mf), eti.icv);
@@ -9935,8 +11820,9 @@ namespace getfem {
             { // --> t(target_dim*Qmult,N,N)
               ga_instruction_set::elementary_trans_info &eti
                 = rmi.elementary_trans_infos[pnode->elementary_name];
-              pgai = std::make_shared<ga_instruction_elementary_transformation_hess>
-                (pnode->t, rmi.hess[mf],
+              pgai =
+		std::make_shared<ga_instruction_elementary_transformation_hess>
+                (pnode->tensor(), rmi.hess[mf],
                  rmi.local_dofs[pnode->name], workspace.qdim(pnode->name),
                  workspace.elementary_transformation(pnode->elementary_name),
                  *mf, gis.ctx, eti.M, &(eti.mf), eti.icv);
@@ -9946,8 +11832,9 @@ namespace getfem {
             { // --> t(1)
               ga_instruction_set::elementary_trans_info &eti
                 = rmi.elementary_trans_infos[pnode->elementary_name];
-              pgai = std::make_shared<ga_instruction_elementary_transformation_diverg>
-                (pnode->t, rmi.grad[mf],
+              pgai =
+	       std::make_shared<ga_instruction_elementary_transformation_diverg>
+                (pnode->tensor(), rmi.grad[mf],
                  rmi.local_dofs[pnode->name], workspace.qdim(pnode->name),
                  workspace.elementary_transformation(pnode->elementary_name),
                  *mf, gis.ctx, eti.M, &(eti.mf), eti.icv);
@@ -9977,20 +11864,27 @@ namespace getfem {
         }
 
         if (pnode->node_type == GA_NODE_INTERPOLATE_VAL) {
-          pgai = std::make_shared<ga_instruction_interpolate_val> // --> t(target_dim*Qmult)
-            (pnode->t, m2, mfn, mfg, Un, Ug, *pctx, workspace.qdim(pnode->name),
+	  // --> t(target_dim*Qmult)
+          pgai = std::make_shared<ga_instruction_interpolate_val>
+            (pnode->tensor(), m2, mfn, mfg, Un, Ug, *pctx,
+	     workspace.qdim(pnode->name),
              gis.ipt, gis.fp_pool, rmi.interpolate_infos[intn]);
         } else if (pnode->node_type == GA_NODE_INTERPOLATE_GRAD) {
-          pgai = std::make_shared<ga_instruction_interpolate_grad> // --> t(target_dim*Qmult,N)
-            (pnode->t, m2, mfn, mfg, Un, Ug, *pctx, workspace.qdim(pnode->name),
+	  // --> t(target_dim*Qmult,N)
+          pgai = std::make_shared<ga_instruction_interpolate_grad>
+            (pnode->tensor(), m2, mfn, mfg, Un, Ug, *pctx,
+	     workspace.qdim(pnode->name),
              gis.ipt, gis.fp_pool, rmi.interpolate_infos[intn]);
         } else if (pnode->node_type == GA_NODE_INTERPOLATE_HESS) {
-          pgai = std::make_shared<ga_instruction_interpolate_hess> // --> t(target_dim*Qmult,N,N)
-            (pnode->t, m2, mfn, mfg, Un, Ug, *pctx, workspace.qdim(pnode->name),
+	  // --> t(target_dim*Qmult,N,N)
+          pgai = std::make_shared<ga_instruction_interpolate_hess>
+            (pnode->tensor(), m2, mfn, mfg, Un, Ug, *pctx,
+	     workspace.qdim(pnode->name),
              gis.ipt, gis.fp_pool, rmi.interpolate_infos[intn]);
         } else { // --> t(1)
           pgai = std::make_shared<ga_instruction_interpolate_diverg>
-            (pnode->t, m2, mfn, mfg, Un, Ug, *pctx, workspace.qdim(pnode->name),
+            (pnode->tensor(), m2, mfn, mfg, Un, Ug, *pctx,
+	     workspace.qdim(pnode->name),
              gis.ipt, gis.fp_pool, rmi.interpolate_infos[intn]);
         }
         rmi.instructions.push_back(std::move(pgai));
@@ -10001,7 +11895,7 @@ namespace getfem {
       GMM_ASSERT1(!function_case,
                   "No use of Interpolate is allowed in functions");
       pgai = std::make_shared<ga_instruction_copy_tensor_possibly_void>
-        (pnode->t,
+        (pnode->tensor(),
          rmi.interpolate_infos[pnode->interpolate_name_der]
          .derivatives[var_trans_pair(pnode->name, pnode->interpolate_name)]);
       rmi.instructions.push_back(std::move(pgai));
@@ -10026,13 +11920,14 @@ namespace getfem {
                       " defined on the same mesh");
 
           // An instruction for pfp update
-          if (rmi.pfps.count(mf) == 0 ||
-              !(if_hierarchy.is_compatible(rmi.pfps_hierarchy[mf]))) {
+          if (rmi.pfps.count(mf) == 0) {
             rmi.pfps[mf] = 0;
-            rmi.pfps_hierarchy[mf].push_back(if_hierarchy);
             pgai = std::make_shared<ga_instruction_update_pfp>
               (*mf, rmi.pfps[mf], gis.ctx, gis.fp_pool);
-            rmi.instructions.push_back(std::move(pgai));
+            if (is_uniform)
+              rmi.begin_instructions.push_back(std::move(pgai));
+            else
+              rmi.instructions.push_back(std::move(pgai));
           }
 
           // An instruction for the base value
@@ -10099,7 +11994,8 @@ namespace getfem {
             break;
           case GA_NODE_XFEM_PLUS_HESS_TEST:
             if (rmi.xfem_plus_hess.count(mf) == 0 ||
-                !(if_hierarchy.is_compatible(rmi.xfem_plus_hess_hierarchy[mf]))) {
+                !(if_hierarchy.is_compatible(rmi.xfem_plus_hess_hierarchy[mf]))
+		) {
               rmi.xfem_plus_hess_hierarchy[mf].push_back(if_hierarchy);
               pgai = std::make_shared<ga_instruction_xfem_plus_hess_base>
                 (rmi.xfem_plus_hess[mf], gis.ctx, *mf, rmi.pfps[mf]);
@@ -10120,60 +12016,101 @@ namespace getfem {
 
           // The copy of the real_base_value
           switch(pnode->node_type) {
-          case GA_NODE_VAL_TEST: // --> t(Qmult*ndof,Qmult*target_dim)
-            pgai = std::make_shared<ga_instruction_copy_val_base>
-              (pnode->t, rmi.base[mf], mf->get_qdim());
-            break;
-          case GA_NODE_GRAD_TEST: // --> t(Qmult*ndof,Qmult*target_dim,N)
-            pgai = std::make_shared<ga_instruction_copy_grad_base>
-              (pnode->t, rmi.grad[mf], mf->get_qdim());
+          case GA_NODE_VAL_TEST:
+	    // --> t(Qmult*ndof,Qmult*target_dim)
+	    if (mf->get_qdim() > 1 && mf->is_uniformly_vectorized()) {
+	      pnode->t.set_sparsity(1, mf->get_qdim());
+	      tensor_to_clear = true;
+	      pgai = std::make_shared<ga_instruction_copy_vect_val_base>
+		(pnode->tensor(), rmi.base[mf], mf->get_qdim());
+	    } else {
+	      pgai = std::make_shared<ga_instruction_copy_val_base>
+		(pnode->tensor(), rmi.base[mf], mf->get_qdim());
+	    }
             break;
-          case GA_NODE_HESS_TEST: // --> t(Qmult*ndof,Qmult*target_dim,N,N)
-            pgai = std::make_shared<ga_instruction_copy_hess_base>
-              (pnode->t, rmi.hess[mf], mf->get_qdim());
+          case GA_NODE_GRAD_TEST:
+	    // --> t(Qmult*ndof,Qmult*target_dim,N)
+	    if (mf->get_qdim() > 1 && mf->is_uniformly_vectorized()) {
+	      pnode->t.set_sparsity(2, mf->get_qdim());
+	      tensor_to_clear = true;
+	      pgai = std::make_shared<ga_instruction_copy_vect_grad_base>
+		(pnode->tensor(), rmi.grad[mf], mf->get_qdim());
+	    } else {
+	      pgai = std::make_shared<ga_instruction_copy_grad_base>
+		(pnode->tensor(), rmi.grad[mf], mf->get_qdim());
+	    }
+	    break;
+          case GA_NODE_HESS_TEST:
+	    // --> t(Qmult*ndof,Qmult*target_dim,N,N)
+	    pgai = std::make_shared<ga_instruction_copy_hess_base>
+	      (pnode->tensor(), rmi.hess[mf], mf->get_qdim());
+	    if (mf->get_qdim() > 1 && mf->is_uniformly_vectorized())
+	      pnode->t.set_sparsity(3, mf->get_qdim());
             break;
-          case GA_NODE_DIVERG_TEST: // --> t(Qmult*ndof)
+          case GA_NODE_DIVERG_TEST:
+	    // --> t(Qmult*ndof)
             pgai = std::make_shared<ga_instruction_copy_diverg_base>
-              (pnode->t, rmi.grad[mf], mf->get_qdim());
+              (pnode->tensor(), rmi.grad[mf], mf->get_qdim());
             break;
-          case GA_NODE_XFEM_PLUS_VAL_TEST: // -->t(Qmult*ndof,Qmult*target_dim)
+          case GA_NODE_XFEM_PLUS_VAL_TEST:
+	    // -->t(Qmult*ndof,Qmult*target_dim)
             pgai = std::make_shared<ga_instruction_copy_val_base>
-              (pnode->t, rmi.xfem_plus_base[mf], mf->get_qdim());
+              (pnode->tensor(), rmi.xfem_plus_base[mf], mf->get_qdim());
+	    if (mf->get_qdim() > 1 && mf->is_uniformly_vectorized())
+	      pnode->t.set_sparsity(1, mf->get_qdim());
             break;
-          case GA_NODE_XFEM_PLUS_GRAD_TEST: // --> t(Qmult*ndof,Qmult*target_dim,N)
+          case GA_NODE_XFEM_PLUS_GRAD_TEST:
+	    // --> t(Qmult*ndof,Qmult*target_dim,N)
             pgai = std::make_shared<ga_instruction_copy_grad_base>
-              (pnode->t, rmi.xfem_plus_grad[mf], mf->get_qdim());
+              (pnode->tensor(), rmi.xfem_plus_grad[mf], mf->get_qdim());
+	    if (mf->get_qdim() > 1 && mf->is_uniformly_vectorized())
+	      pnode->t.set_sparsity(2, mf->get_qdim());
             break;
-          case GA_NODE_XFEM_PLUS_HESS_TEST: // --> t(Qmult*ndof,Qmult*target_dim,N,N)
+          case GA_NODE_XFEM_PLUS_HESS_TEST:
+	    // --> t(Qmult*ndof,Qmult*target_dim,N,N)
             pgai = std::make_shared<ga_instruction_copy_hess_base>
-              (pnode->t, rmi.xfem_plus_hess[mf], mf->get_qdim());
+              (pnode->tensor(), rmi.xfem_plus_hess[mf], mf->get_qdim());
+	    if (mf->get_qdim() > 1 && mf->is_uniformly_vectorized())
+	      pnode->t.set_sparsity(3, mf->get_qdim());
             break;
-          case GA_NODE_XFEM_PLUS_DIVERG_TEST: // --> t(Qmult*ndof)
+          case GA_NODE_XFEM_PLUS_DIVERG_TEST:
+	    // --> t(Qmult*ndof)
             pgai = std::make_shared<ga_instruction_copy_diverg_base>
-              (pnode->t, rmi.xfem_plus_grad[mf], mf->get_qdim());
+              (pnode->tensor(), rmi.xfem_plus_grad[mf], mf->get_qdim());
             break;
-          case GA_NODE_XFEM_MINUS_VAL_TEST: // -->t(Qmult*ndof,Qmult*target_dim)
+          case GA_NODE_XFEM_MINUS_VAL_TEST:
+	    // -->t(Qmult*ndof,Qmult*target_dim)
             pgai = std::make_shared<ga_instruction_copy_val_base>
-              (pnode->t, rmi.xfem_minus_base[mf], mf->get_qdim());
+              (pnode->tensor(), rmi.xfem_minus_base[mf], mf->get_qdim());
+	    if (mf->get_qdim() > 1 && mf->is_uniformly_vectorized())
+	      pnode->t.set_sparsity(1, mf->get_qdim());
             break;
-          case GA_NODE_XFEM_MINUS_GRAD_TEST: // --> t(Qmult*ndof,Qmult*target_dim,N)
+          case GA_NODE_XFEM_MINUS_GRAD_TEST:
+	    // --> t(Qmult*ndof,Qmult*target_dim,N)
             pgai = std::make_shared<ga_instruction_copy_grad_base>
-              (pnode->t, rmi.xfem_minus_grad[mf], mf->get_qdim());
+              (pnode->tensor(), rmi.xfem_minus_grad[mf], mf->get_qdim());
+	    if (mf->get_qdim() > 1 && mf->is_uniformly_vectorized())
+	      pnode->t.set_sparsity(2, mf->get_qdim());
             break;
-          case GA_NODE_XFEM_MINUS_HESS_TEST: // --> t(Qmult*ndof,Qmult*target_dim,N,N)
+          case GA_NODE_XFEM_MINUS_HESS_TEST:
+	    // --> t(Qmult*ndof,Qmult*target_dim,N,N)
             pgai = std::make_shared<ga_instruction_copy_hess_base>
-              (pnode->t, rmi.xfem_minus_hess[mf], mf->get_qdim());
+              (pnode->tensor(), rmi.xfem_minus_hess[mf], mf->get_qdim());
+	    if (mf->get_qdim() > 1 && mf->is_uniformly_vectorized())
+	      pnode->t.set_sparsity(3, mf->get_qdim());
             break;
-          case GA_NODE_XFEM_MINUS_DIVERG_TEST: // --> t(Qmult*ndof)
+          case GA_NODE_XFEM_MINUS_DIVERG_TEST:
+	    // --> t(Qmult*ndof)
             pgai = std::make_shared<ga_instruction_copy_diverg_base>
-              (pnode->t, rmi.xfem_minus_grad[mf], mf->get_qdim());
+              (pnode->tensor(), rmi.xfem_minus_grad[mf], mf->get_qdim());
             break;
           case GA_NODE_ELEMENTARY_VAL_TEST:
             { // --> t(Qmult*ndof,Qmult*target_dim)
               ga_instruction_set::elementary_trans_info &eti
                 = rmi.elementary_trans_infos[pnode->elementary_name];
-              pgai = std::make_shared<ga_instruction_elementary_transformation_val_base>
-                (pnode->t, rmi.base[mf], mf->get_qdim(),
+              pgai =
+	     std::make_shared<ga_instruction_elementary_transformation_val_base>
+                (pnode->tensor(), rmi.base[mf], mf->get_qdim(),
                  workspace.elementary_transformation(pnode->elementary_name),
                  *mf, gis.ctx, eti.M, &(eti.mf), eti.icv);
             }
@@ -10182,8 +12119,9 @@ namespace getfem {
             { // --> t(Qmult*ndof,Qmult*target_dim,N)
               ga_instruction_set::elementary_trans_info &eti
                 = rmi.elementary_trans_infos[pnode->elementary_name];
-              pgai = std::make_shared<ga_instruction_elementary_transformation_grad_base>
-                (pnode->t, rmi.grad[mf], mf->get_qdim(),
+              pgai =
+	    std::make_shared<ga_instruction_elementary_transformation_grad_base>
+                (pnode->tensor(), rmi.grad[mf], mf->get_qdim(),
                  workspace.elementary_transformation(pnode->elementary_name),
                  *mf, gis.ctx, eti.M, &(eti.mf), eti.icv);
             }
@@ -10192,8 +12130,9 @@ namespace getfem {
             { // --> t(Qmult*ndof,Qmult*target_dim,N,N)
               ga_instruction_set::elementary_trans_info &eti
                 = rmi.elementary_trans_infos[pnode->elementary_name];
-              pgai = std::make_shared<ga_instruction_elementary_transformation_hess_base>
-                (pnode->t, rmi.hess[mf], mf->get_qdim(),
+              pgai =
+	    std::make_shared<ga_instruction_elementary_transformation_hess_base>
+                (pnode->tensor(), rmi.hess[mf], mf->get_qdim(),
                  workspace.elementary_transformation(pnode->elementary_name),
                  *mf, gis.ctx, eti.M, &(eti.mf), eti.icv);
             }
@@ -10202,15 +12141,16 @@ namespace getfem {
             { // --> t(Qmult*ndof)
               ga_instruction_set::elementary_trans_info &eti
                 = rmi.elementary_trans_infos[pnode->elementary_name];
-              pgai = std::make_shared<ga_instruction_elementary_transformation_diverg_base>
-                (pnode->t, rmi.grad[mf], mf->get_qdim(),
+              pgai =
+	  std::make_shared<ga_instruction_elementary_transformation_diverg_base>
+                (pnode->tensor(), rmi.grad[mf], mf->get_qdim(),
                  workspace.elementary_transformation(pnode->elementary_name),
                  *mf, gis.ctx, eti.M, &(eti.mf), eti.icv);
             }
             break;
           default: break;
           }
-          rmi.instructions.push_back(std::move(pgai));
+          if (pgai) rmi.instructions.push_back(std::move(pgai));
         }
         add_interval_to_gis(workspace, pnode->name, gis);
         gis.max_dof = std::max
@@ -10233,22 +12173,26 @@ namespace getfem {
         if (pnode->node_type == GA_NODE_INTERPOLATE_VAL_TEST) {
           // --> t(Qmult*ndof,Qmult*target_dim)
           pgai = std::make_shared<ga_instruction_interpolate_val_base>
-            (pnode->t, m2, mfn, mfg, gis.ipt, workspace.qdim(pnode->name),
-             rmi.interpolate_infos[intn], gis.fp_pool);
+            (pnode->tensor(), m2, mfn, mfg, gis.ipt,
+	     workspace.qdim(pnode->name), rmi.interpolate_infos[intn],
+	     gis.fp_pool);
         } else if (pnode->node_type == GA_NODE_INTERPOLATE_GRAD_TEST) {
            // --> t(Qmult*ndof,Qmult*target_dim,N)
           pgai = std::make_shared<ga_instruction_interpolate_grad_base>
-            (pnode->t, m2, mfn, mfg, gis.ipt, workspace.qdim(pnode->name),
+            (pnode->tensor(), m2, mfn, mfg, gis.ipt,
+	     workspace.qdim(pnode->name),
              rmi.interpolate_infos[intn], gis.fp_pool);
         } else if (pnode->node_type == GA_NODE_INTERPOLATE_HESS_TEST) {
            // --> t(Qmult*ndof,Qmult*target_dim,N,N)
           pgai = std::make_shared<ga_instruction_interpolate_hess_base>
-            (pnode->t, m2, mfn, mfg, gis.ipt, workspace.qdim(pnode->name),
+            (pnode->tensor(), m2, mfn, mfg, gis.ipt,
+	     workspace.qdim(pnode->name),
              rmi.interpolate_infos[intn], gis.fp_pool);
         } else { // if (pnode->node_type == GA_NODE_INTERPOLATE_DIVERG_TEST) {
            // --> t(Qmult*ndof)
           pgai = std::make_shared<ga_instruction_interpolate_diverg_base>
-            (pnode->t, m2, mfn, mfg, gis.ipt, workspace.qdim(pnode->name),
+            (pnode->tensor(), m2, mfn, mfg, gis.ipt,
+	     workspace.qdim(pnode->name),
              rmi.interpolate_infos[intn], gis.fp_pool);
         }
         rmi.instructions.push_back(std::move(pgai));
@@ -10259,117 +12203,154 @@ namespace getfem {
        switch(pnode->op_type) {
 
        case GA_PLUS:
-         if (pnode->t.size() == 1) {
-           GA_DEBUG_ASSERT(child0->t.size() == 1,
+         if (pnode->tensor().size() == 1) {
+           GA_DEBUG_ASSERT(child0->tensor().size() == 1,
                            "Internal error: child0 not scalar");
-           GA_DEBUG_ASSERT(child1->t.size() == 1,
+           GA_DEBUG_ASSERT(child1->tensor().size() == 1,
                            "Internal error: child1 not scalar");
            pgai = std::make_shared<ga_instruction_scalar_add>
-             (pnode->t[0], child0->t[0], child1->t[0]);
+             (pnode->tensor()[0], child0->tensor()[0], child1->tensor()[0]);
          } else {
            pgai = std::make_shared<ga_instruction_add>
-             (pnode->t, child0->t, child1->t);
+             (pnode->tensor(), child0->tensor(), child1->tensor());
          }
+	 if (child0->t.sparsity() == child1->t.sparsity()
+	     && child0->t.qdim() == child1->t.qdim())
+	   pnode->t.set_sparsity(child0->t.sparsity(), child0->t.qdim());
          rmi.instructions.push_back(std::move(pgai));
          break;
 
        case GA_MINUS:
-         if (pnode->t.size() == 1) {
-           // GA_DEBUG_ASSERT(pnode->nb_test_functions() == 0,
-           //              "Internal error: non zero number of test functions");
-           GA_DEBUG_ASSERT(child0->t.size() == 1,
+         if (pnode->tensor().size() == 1) {
+           GA_DEBUG_ASSERT(child0->tensor().size() == 1,
                            "Internal error: child0 not scalar");
-           GA_DEBUG_ASSERT(child1->t.size() == 1,
+           GA_DEBUG_ASSERT(child1->tensor().size() == 1,
                            "Internal error: child1 not scalar");
            pgai = std::make_shared<ga_instruction_scalar_sub>
-             (pnode->t[0], child0->t[0], child1->t[0]);
+             (pnode->tensor()[0], child0->tensor()[0], child1->tensor()[0]);
          } else {
            pgai = std::make_shared<ga_instruction_sub>
-             (pnode->t, child0->t, child1->t);
+             (pnode->tensor(), child0->tensor(), child1->tensor());
          }
+	 if (child0->t.sparsity() == child1->t.sparsity()
+	     && child0->t.qdim() == child1->t.qdim())
+	   pnode->t.set_sparsity(child0->t.sparsity(), child0->t.qdim());
          rmi.instructions.push_back(std::move(pgai));
          break;
 
        case GA_UNARY_MINUS:
-         if (pnode->t.size() == 1) {
-           GA_DEBUG_ASSERT(child0->t.size() == 1, "Internal error");
+         if (pnode->tensor().size() == 1) {
+           GA_DEBUG_ASSERT(child0->tensor().size() == 1, "Internal error");
            pgai = std::make_shared<ga_instruction_scalar_scalar_mult>
-             (pnode->t[0], child0->t[0], minus);
+             (pnode->tensor()[0], child0->tensor()[0], minus);
          } else {
            pgai = std::make_shared<ga_instruction_scalar_mult>
-             (pnode->t, child0->t, minus);
+             (pnode->tensor(), child0->tensor(), minus);
          }
+	 pnode->t.set_sparsity(child0->t.sparsity(), child0->t.qdim());
          rmi.instructions.push_back(std::move(pgai));
          break;
 
 
        case GA_DOT: case GA_COLON: case GA_MULT:
          {
-           size_type s1 = (child0->t.size()*child1->t.size())/pnode->t.size();
+           size_type tps1 = child0->tensor_proper_size();
+           size_type tps2 = child1->tensor_proper_size();
+           size_type s1 = (tps1 * tps2) / pnode->tensor_proper_size();
            size_type s2 = size_type(round(sqrt(scalar_type(s1))));
 
            pgai = pga_instruction();
            if (pnode->op_type == GA_DOT || pnode->op_type == GA_COLON ||
                (pnode->op_type == GA_MULT && dim0 == 4) ||
                (pnode->op_type == GA_MULT && dim1 <= 1) ||
-               child0->t.size() == 1 || child1->t.size() == 1) {
+               child0->tensor().size() == 1 || child1->tensor().size() == 1) {
 
-             if (child0->t.size() == 1 && child1->t.size() == 1) {
+             if (child0->tensor().size() == 1 && child1->tensor().size() == 1) {
                pgai = std::make_shared<ga_instruction_scalar_scalar_mult>
-                 (pnode->t[0], child0->t[0], child1->t[0]);
+                 (pnode->tensor()[0], child0->tensor()[0], child1->tensor()[0]);
              }
-             else if (child0->t.size() == 1)
+             else if (child0->tensor().size() == 1) {
+	       pnode->t.set_sparsity(child1->t.sparsity(), child1->t.qdim());
                pgai = std::make_shared<ga_instruction_scalar_mult>
-                 (pnode->t, child1->t, child0->t[0]);
-             else if (child1->t.size() == 1)
+                 (pnode->tensor(), child1->tensor(), child0->tensor()[0]);
+	     }
+             else if (child1->tensor().size() == 1) {
+	       pnode->t.set_sparsity(child0->t.sparsity(), child0->t.qdim());
                pgai = std::make_shared<ga_instruction_scalar_mult>
-                 (pnode->t, child0->t, child1->t[0]);
+                 (pnode->tensor(), child0->tensor(), child1->tensor()[0]);
+	     }
              else if (pnode->test_function_type < 3) {
-               if (child0->tensor_proper_size() == 1)
-                 pgai = std::make_shared<ga_instruction_simple_tmult>
-                   (pnode->t, child0->t, child1->t);
-               else {
-                 if (s2 == 2) // Unroll loop test ... to be extended
-                   pgai = std::make_shared<ga_instruction_reduction_2>
-                     (pnode->t, child0->t, child1->t);
+               if (child0->tensor_proper_size() == 1) {
+                 if (is_uniform) // Unrolled instruction
+                   pgai = ga_uniform_instruction_simple_tmult
+                     (pnode->tensor(), child0->tensor(), child1->tensor());
                  else
-                   pgai = std::make_shared<ga_instruction_reduction>
-                     (pnode->t, child0->t, child1->t, s2);
+                   pgai = std::make_shared<ga_instruction_simple_tmult>
+                     (pnode->tensor(), child0->tensor(), child1->tensor());
+               } else {
+                 if (tps1 == 1) {
+                   if (is_uniform) // Unrolled instruction
+                     pgai = ga_uniform_instruction_simple_tmult
+                       (pnode->tensor(), child1->tensor(), child0->tensor());
+                   else
+                     pgai = std::make_shared<ga_instruction_simple_tmult>
+                       (pnode->tensor(), child1->tensor(), child0->tensor());
+                 } else if (is_uniform) // Unrolled instruction
+                   pgai = ga_uniform_instruction_reduction_switch
+                     (pnode->t, child0->t, child1->t, s2, tensor_to_clear);
+                 else // Unrolled instruction
+                   pgai = ga_instruction_reduction_switch
+                     (pnode->t, child0->t, child1->t, s2, tensor_to_clear);
                }
              } else {
                if (child1->test_function_type == 1 ||
                    child1->test_function_type == 3) {
                  if (child1->test_function_type == 3 ||
                      child1->tensor_proper_size() <= s2) {
-                   if (s2 == 2) // Unroll loop test ... to be extended
-                     pgai = std::make_shared<ga_instruction_reduction_2>
-                       (pnode->t, child0->t, child1->t);
-                   else
-                     pgai = std::make_shared<ga_instruction_reduction>
-                       (pnode->t, child0->t, child1->t, s2);
-                 } else {
+                   if (tps1 == 1) {
+                     if (is_uniform) { // Unrolled instruction
+                       pgai = ga_uniform_instruction_simple_tmult
+                         (pnode->tensor(), child1->tensor(), child0->tensor());
+                     } else
+                       pgai = std::make_shared<ga_instruction_simple_tmult>
+                         (pnode->tensor(), child1->tensor(), child0->tensor());
+                   } else if (is_uniform) // Unrolled instruction
+                     pgai = ga_uniform_instruction_reduction_switch
+                       (pnode->t, child0->t, child1->t, s2, tensor_to_clear);
+                   else // Unrolled instruction
+                     pgai = ga_instruction_reduction_switch
+                       (pnode->t, child0->t, child1->t, s2, tensor_to_clear);
+                 } else
                    pgai = std::make_shared<ga_instruction_spec_reduction>
-                     (pnode->t, child1->t, child0->t, s2);
-                 }
+                     (pnode->tensor(), child1->tensor(), child0->tensor(), s2);
                } else if (child1->test_function_type == 0 ||
                           (child0->tensor_proper_size() == s2 &&
                            child1->tensor_proper_size() == s2)) {
-                 if (s2 == 2) // Unroll loop test ... to be extended
-                   pgai = std::make_shared<ga_instruction_reduction_2>
-                     (pnode->t, child1->t, child0->t);
-                 else
-                   pgai = std::make_shared<ga_instruction_reduction>
-                     (pnode->t, child1->t, child0->t, s2);
+                 if (tps1 == 1) {
+                   if (is_uniform) { // Unrolled instruction
+                     pgai = ga_uniform_instruction_simple_tmult
+                       (pnode->tensor(), child0->tensor(), child1->tensor());
+                   } else
+                     pgai = std::make_shared<ga_instruction_simple_tmult>
+                       (pnode->tensor(), child0->tensor(), child1->tensor());
+                 } else {
+		   if (is_uniform) // Unrolled instruction
+		     pgai = ga_uniform_instruction_reduction_switch
+		       (pnode->t, child1->t, child0->t, s2, tensor_to_clear);
+		   else // Unrolled instruction
+		     pgai = ga_instruction_reduction_switch
+		       (pnode->t, child1->t, child0->t, s2, tensor_to_clear);
+		 }
                } else {
                  if (child0->tensor_proper_size() == s2)
-                   pgai = std::make_shared<ga_instruction_reduction>
-                     (pnode->t, child1->t, child0->t, s2);
+                   pgai = ga_uniform_instruction_reduction_switch
+                     (pnode->t, child1->t, child0->t, s2, tensor_to_clear);
                  else if (child1->tensor_proper_size() == s2)
                    pgai = std::make_shared<ga_instruction_spec_reduction>
-                     (pnode->t, child0->t, child1->t, s2);
+                     (pnode->tensor(), child0->tensor(), child1->tensor(), s2);
                  else
                    pgai = std::make_shared<ga_instruction_spec2_reduction>
-                     (pnode->t, child0->t, child1->t, s2);
+                     (pnode->tensor(), child0->tensor(), child1->tensor(), s2);
                }
              }
 
@@ -10377,45 +12358,61 @@ namespace getfem {
            } else { // GA_MULT
 
              if (pnode->test_function_type < 3) {
-               if (child1->tensor_proper_size() == 1)
-                 pgai = std::make_shared<ga_instruction_simple_tmult>
-                   (pnode->t, child1->t, child0->t);
-               else if (child0->tensor_proper_size() == 1)
-                 pgai = std::make_shared<ga_instruction_simple_tmult>
-                   (pnode->t, child0->t, child1->t);
-               else {
+               if (child1->tensor_proper_size() == 1) {
+                 if (is_uniform) // Unrolled instruction
+                   pgai = ga_uniform_instruction_simple_tmult
+                     (pnode->tensor(), child1->tensor(), child0->tensor());
+                 else
+                   pgai = std::make_shared<ga_instruction_simple_tmult>
+                     (pnode->tensor(), child1->tensor(), child0->tensor());
+               } else if (child0->tensor_proper_size() == 1) {
+                 if (is_uniform) // Unrolled instruction
+                   pgai = ga_uniform_instruction_simple_tmult
+                     (pnode->tensor(), child0->tensor(), child1->tensor());
+                 else
+                   pgai = std::make_shared<ga_instruction_simple_tmult>
+                     (pnode->tensor(), child0->tensor(), child1->tensor());
+               } else {
                  if (dim0 == 2)
                    pgai = std::make_shared<ga_instruction_matrix_mult>
-                     (pnode->t, child0->t, child1->t);
+                     (pnode->tensor(), child0->tensor(), child1->tensor());
                }
              } else {
                if (child1->tensor_proper_size() == 1) {
                  if (child1->test_function_type == 0 ||
-                     child1->test_function_type == 1)
-                   pgai = std::make_shared<ga_instruction_simple_tmult>
-                     (pnode->t, child1->t, child0->t);
-                 else
+                     child1->test_function_type == 1) {
+                   if (is_uniform) // Unrolled instruction
+                     pgai = ga_uniform_instruction_simple_tmult
+                       (pnode->tensor(), child1->tensor(), child0->tensor());
+                   else
+                     pgai = std::make_shared<ga_instruction_simple_tmult>
+                       (pnode->tensor(), child1->tensor(), child0->tensor());
+                 } else
                    pgai = std::make_shared<ga_instruction_spec_tmult>
-                     (pnode->t, child0->t, child1->t,
+                     (pnode->tensor(), child0->tensor(), child1->tensor(),
                       child0->tensor_proper_size(),
                       child1->tensor_proper_size());
                } else if (child0->tensor_proper_size() == 1) {
                  if (child0->test_function_type == 0 ||
-                     child0->test_function_type == 1)
-                   pgai = std::make_shared<ga_instruction_simple_tmult>
-                     (pnode->t, child0->t, child1->t);
-                 else
+                     child0->test_function_type == 1) {
+                   if (is_uniform) // Unrolled instruction
+                     pgai = ga_uniform_instruction_simple_tmult
+                       (pnode->tensor(), child0->tensor(), child1->tensor());
+                   else
+                     pgai = std::make_shared<ga_instruction_simple_tmult>
+                       (pnode->tensor(), child0->tensor(), child1->tensor());
+                 } else
                    pgai = std::make_shared<ga_instruction_spec_tmult>
-                     (pnode->t, child1->t, child0->t,
+                     (pnode->tensor(), child1->tensor(), child0->tensor(),
                       child1->tensor_proper_size(),
                       child0->tensor_proper_size());
                } else if (dim0 == 2) {
                  if (child1->test_function_type != 2)
                    pgai = std::make_shared<ga_instruction_matrix_mult>
-                     (pnode->t, child0->t, child1->t);
+                     (pnode->tensor(), child0->tensor(), child1->tensor());
                  else
                    pgai = std::make_shared<ga_instruction_matrix_mult_spec>
-                     (pnode->t, child0->t, child1->t);
+                     (pnode->tensor(), child0->tensor(), child1->tensor());
                }
              }
            }
@@ -10425,53 +12422,48 @@ namespace getfem {
          break;
 
        case GA_DIV:
-         if (child0->t.size() == 1 && child1->t.size() == 1) {
+         if (child0->tensor().size() == 1 && child1->tensor().size() == 1) {
            pgai = std::make_shared<ga_instruction_scalar_scalar_div>
-             (pnode->t[0], child0->t[0], child1->t[0]);
-         } else if (child1->t.size() == 1) {
+             (pnode->tensor()[0], child0->tensor()[0], child1->tensor()[0]);
+         } else if (child1->tensor().size() == 1) {
+	   pnode->t.set_sparsity(child0->t.sparsity(), child0->t.qdim());
            pgai = std::make_shared<ga_instruction_scalar_div>
-             (pnode->t, child0->t, child1->t[0]);
+             (pnode->tensor(), child0->tensor(), child1->tensor()[0]);
          } else GMM_ASSERT1(false, "Internal error");
          rmi.instructions.push_back(std::move(pgai));
          break;
 
        case GA_PRINT:
-         pgai = std::make_shared<ga_instruction_copy_tensor>
-           (pnode->t, child0->t);
-         rmi.instructions.push_back(std::move(pgai));
+	 pnode->t.set_to_copy(child0->t);
          pgai = std::make_shared<ga_instruction_print_tensor>
-           (pnode->t, child0, gis.ctx, gis.nbpt, gis.ipt);
+           (pnode->tensor(), child0, gis.ctx, gis.nbpt, gis.ipt);
          rmi.instructions.push_back(std::move(pgai));
          break;
 
        case GA_QUOTE:
          if (pnode->tensor_proper_size() != 1) {
            pgai = std::make_shared<ga_instruction_transpose>
-             (pnode->t, child0->t);
+             (pnode->tensor(), child0->tensor());
            rmi.instructions.push_back(std::move(pgai));
          } else {
-           pgai = std::make_shared<ga_instruction_copy_tensor>
-             (pnode->t, child0->t);
-           rmi.instructions.push_back(std::move(pgai));
+	   pnode->t.set_to_copy(child0->t);
          }
          break;
 
        case GA_SYM:
          if (pnode->tensor_proper_size() != 1) {
            pgai = std::make_shared<ga_instruction_sym>
-             (pnode->t, child0->t);
+             (pnode->tensor(), child0->tensor());
            rmi.instructions.push_back(std::move(pgai));
          } else {
-           pgai = std::make_shared<ga_instruction_copy_tensor>
-             (pnode->t, child0->t);
-           rmi.instructions.push_back(std::move(pgai));
+	   pnode->t.set_to_copy(child0->t);
          }
          break;
 
        case GA_SKEW:
          {
            pgai = std::make_shared<ga_instruction_skew>
-             (pnode->t, child0->t);
+             (pnode->tensor(), child0->tensor());
            rmi.instructions.push_back(std::move(pgai));
          }
          break;
@@ -10479,9 +12471,13 @@ namespace getfem {
        case GA_TRACE:
          {
            size_type N = (child0->tensor_proper_size() == 1) ? 1:size0.back();
-           pgai = std::make_shared<ga_instruction_trace>
-             (pnode->t, child0->t, N);
-           rmi.instructions.push_back(std::move(pgai));
+	   if (N == 1) {
+	     pnode->t.set_to_copy(child0->t);
+	   } else { 
+	     pgai = std::make_shared<ga_instruction_trace>
+	       (pnode->tensor(), child0->tensor(), N);
+	     rmi.instructions.push_back(std::move(pgai));
+	   }
          }
          break;
 
@@ -10489,73 +12485,86 @@ namespace getfem {
          {
            size_type N = (child0->tensor_proper_size() == 1) ? 1:size0.back();
            pgai = std::make_shared<ga_instruction_deviator>
-             (pnode->t, child0->t, N);
+             (pnode->tensor(), child0->tensor(), N);
            rmi.instructions.push_back(std::move(pgai));
          }
          break;
 
        case GA_DOTMULT:
 
-         if (child0->t.size() == 1 && child1->t.size() == 1) {
+         if (child0->tensor().size() == 1 && child1->tensor().size() == 1) {
            pgai = std::make_shared<ga_instruction_scalar_scalar_mult>
-             (pnode->t[0], child0->t[0], child1->t[0]);
-         } else if (child0->t.size() == 1)
+             (pnode->tensor()[0], child0->tensor()[0], child1->tensor()[0]);
+         } else if (child0->tensor().size() == 1) {
+	   pnode->t.set_sparsity(child1->t.sparsity(), child1->t.qdim());
            pgai = std::make_shared<ga_instruction_scalar_mult>
-             (pnode->t, child1->t, child0->t[0]);
-         else if (child1->t.size() == 1)
+             (pnode->tensor(), child1->tensor(), child0->tensor()[0]);
+	 }
+         else if (child1->tensor().size() == 1) {
+	   pnode->t.set_sparsity(child0->t.sparsity(), child0->t.qdim());
            pgai = std::make_shared<ga_instruction_scalar_mult>
-             (pnode->t, child0->t, child1->t[0]);
+             (pnode->tensor(), child0->tensor(), child1->tensor()[0]);
+	 }
          else if (child1->test_function_type == 0)
            pgai = std::make_shared<ga_instruction_dotmult>
-             (pnode->t, child0->t, child1->t);
+             (pnode->tensor(), child0->tensor(), child1->tensor());
          else if (child0->test_function_type == 0)
            pgai = std::make_shared<ga_instruction_dotmult>
-             (pnode->t, child1->t, child0->t);
+             (pnode->tensor(), child1->tensor(), child0->tensor());
          else if (child0->test_function_type == 1)
            pgai = std::make_shared<ga_instruction_dotmult_spec>
-             (pnode->t, child0->t, child1->t);
+             (pnode->tensor(), child0->tensor(), child1->tensor());
          else
            pgai = std::make_shared<ga_instruction_dotmult_spec>
-             (pnode->t, child1->t, child0->t);
+             (pnode->tensor(), child1->tensor(), child0->tensor());
 
          rmi.instructions.push_back(std::move(pgai));
          break;
 
 
        case GA_DOTDIV:
-         if (child0->t.size() == 1 && child1->t.size() == 1) {
+         if (child0->tensor().size() == 1 && child1->tensor().size() == 1) {
            pgai = std::make_shared<ga_instruction_scalar_scalar_div>
-             (pnode->t[0], child0->t[0], child1->t[0]);
-         } else if (child1->t.size() == 1) {
+             (pnode->tensor()[0], child0->tensor()[0], child1->tensor()[0]);
+         } else if (child1->tensor().size() == 1) {
+	   pnode->t.set_sparsity(child0->t.sparsity(), child0->t.qdim());
            pgai = std::make_shared<ga_instruction_scalar_div>
-             (pnode->t, child0->t, child1->t[0]);
+             (pnode->tensor(), child0->tensor(), child1->tensor()[0]);
          } else if (child1->test_function_type == 0) {
            pgai = std::make_shared<ga_instruction_dotdiv>
-             (pnode->t, child0->t, child1->t);
+             (pnode->tensor(), child0->tensor(), child1->tensor());
          } else GMM_ASSERT1(false, "Internal error");
          rmi.instructions.push_back(std::move(pgai));
          break;
 
 
        case GA_TMULT:
-         if (child0->t.size() == 1 && child1->t.size() == 1) {
+         if (child0->tensor().size() == 1 && child1->tensor().size() == 1) {
            pgai = std::make_shared<ga_instruction_scalar_scalar_mult>
-             (pnode->t[0], child0->t[0], child1->t[0]);
-         } else if (child0->t.size() == 1)
+             (pnode->tensor()[0], child0->tensor()[0], child1->tensor()[0]);
+         } else if (child0->tensor().size() == 1) {
+	   pnode->t.set_sparsity(child1->t.sparsity(), child1->t.qdim());
            pgai = std::make_shared<ga_instruction_scalar_mult>
-             (pnode->t, child1->t, child0->t[0]);
-         else if (child1->t.size() == 1)
+             (pnode->tensor(), child1->tensor(), child0->tensor()[0]);
+	 }
+         else if (child1->tensor().size() == 1) {
+	   pnode->t.set_sparsity(child0->t.sparsity(), child0->t.qdim());
            pgai = std::make_shared<ga_instruction_scalar_mult>
-             (pnode->t, child0->t, child1->t[0]);
-         else if (child1->test_function_type == 0)
-           pgai = std::make_shared<ga_instruction_simple_tmult>
-             (pnode->t, child0->t, child1->t);
-         else if (child1->tensor_proper_size() == 1)
+             (pnode->tensor(), child0->tensor(), child1->tensor()[0]);
+	 }
+         else if (child1->test_function_type == 0) {
+           if (is_uniform) // Unrolled instruction
+             pgai = ga_uniform_instruction_simple_tmult
+               (pnode->tensor(), child0->tensor(), child1->tensor());
+           else
+             pgai = std::make_shared<ga_instruction_simple_tmult>
+               (pnode->tensor(), child0->tensor(), child1->tensor());
+         } else if (child1->tensor_proper_size() == 1)
            pgai = std::make_shared<ga_instruction_spec2_tmult>
-             (pnode->t, child0->t, child1->t);
+             (pnode->tensor(), child0->tensor(), child1->tensor());
          else
            pgai = std::make_shared<ga_instruction_spec_tmult>
-             (pnode->t, child0->t, child1->t,
+             (pnode->tensor(), child0->tensor(), child1->tensor(),
               child0->tensor_proper_size(),
               child1->tensor_proper_size());
 
@@ -10575,11 +12584,11 @@ namespace getfem {
 
           if (nbc1 == 1 && nbc2 == 1 && nbc3 == 1) {
             for (size_type i = 0; i < pnode->children.size(); ++i)
-              components[i]  = &(pnode->children[i]->t);
+              components[i]  = &(pnode->children[i]->tensor());
           } else if (nbc2 == 1 && nbc3 == 1) {
             for (size_type i = 0; i < nbl; ++i)
               for (size_type j = 0; j < nbc1; ++j)
-                components[i+j*nbl] = &(pnode->children[i*nbc1+j]->t);
+                components[i+j*nbl] = &(pnode->children[i*nbc1+j]->tensor());
           } else {
             size_type n = 0;
             for (size_type i = 0; i < nbl; ++i)
@@ -10587,19 +12596,19 @@ namespace getfem {
                 for (size_type k = 0; k < nbc2; ++k)
                   for (size_type l = 0; l < nbc1; ++l)
                     components[i+j*nbl+k*nbl*nbc3+l*nbc2*nbc3*nbl]
-                      = &(pnode->children[n++]->t);
+                      = &(pnode->children[n++]->tensor());
           }
           pgai = std::make_shared<ga_instruction_c_matrix_with_tests>
-            (pnode->t, components);
+            (pnode->tensor(), components);
         } else {
           std::vector<scalar_type *> components(pnode->children.size());
           if (nbc1 == 1 && nbc2 == 1 && nbc3 == 1) {
             for (size_type i = 0; i < pnode->children.size(); ++i)
-              components[i]  = &(pnode->children[i]->t[0]);
+              components[i]  = &(pnode->children[i]->tensor()[0]);
           } else if (nbc2 == 1 && nbc3 == 1) {
             for (size_type i = 0; i < nbl; ++i)
               for (size_type j = 0; j < nbc1; ++j)
-                components[i+j*nbl] = &(pnode->children[i*nbc1+j]->t[0]);
+                components[i+j*nbl] = &(pnode->children[i*nbc1+j]->tensor()[0]);
           } else {
             size_type n = 0;
             for (size_type i = 0; i < nbl; ++i)
@@ -10607,9 +12616,10 @@ namespace getfem {
                 for (size_type k = 0; k < nbc2; ++k)
                   for (size_type l = 0; l < nbc1; ++l)
                     components[i+j*nbl+k*nbl*nbc3+l*nbc2*nbc3*nbl]
-                      = &(pnode->children[n++]->t[0]);
+                      = &(pnode->children[n++]->tensor()[0]);
           }
-          pgai = std::make_shared<ga_instruction_simple_c_matrix>(pnode->t, components);
+          pgai = std::make_shared<ga_instruction_simple_c_matrix>
+	    (pnode->tensor(), components);
         }
         rmi.instructions.push_back(std::move(pgai));
       }
@@ -10617,7 +12627,8 @@ namespace getfem {
 
     case GA_NODE_PARAMS:
       if (child0->node_type == GA_NODE_RESHAPE) {
-        pgai = std::make_shared<ga_instruction_copy_tensor>(pnode->t, child1->t);
+        pgai = std::make_shared<ga_instruction_copy_tensor>(pnode->tensor(),
+							    child1->tensor());
         rmi.instructions.push_back(std::move(pgai));
       } else if (child0->node_type == GA_NODE_PREDEF_FUNC) {
 
@@ -10630,50 +12641,56 @@ namespace getfem {
         pga_tree_node child2 = (nbargs == 2) ? pnode->children[2] : child1;
 
         if (nbargs == 1) {
-          if (child1->t.size() == 1) {
+          if (child1->tensor().size() == 1) {
             if (F.ftype() == 0)
               pgai = std::make_shared<ga_instruction_eval_func_1arg_1res>
-                (pnode->t[0], child1->t[0], F.f1());
+                (pnode->tensor()[0], child1->tensor()[0], F.f1());
             else
               pgai = std::make_shared<ga_instruction_eval_func_1arg_1res_expr>
-                (pnode->t[0], child1->t[0], F);
+                (pnode->tensor()[0], child1->tensor()[0], F);
           } else {
             if (F.ftype() == 0)
               pgai = std::make_shared<ga_instruction_eval_func_1arg>
-                (pnode->t, child1->t, F.f1());
+                (pnode->tensor(), child1->tensor(), F.f1());
             else
               pgai = std::make_shared<ga_instruction_eval_func_1arg_expr>
-                (pnode->t, child1->t, F);
+                (pnode->tensor(), child1->tensor(), F);
           }
         } else {
-          if (child1->t.size() == 1 && child2->t.size() == 1) {
+          if (child1->tensor().size() == 1 && child2->tensor().size() == 1) {
             if (F.ftype() == 0)
               pgai = std::make_shared<ga_instruction_eval_func_2arg_1res>
-                (pnode->t[0], child1->t[0], child2->t[0], F.f2());
+                (pnode->tensor()[0], child1->tensor()[0], child2->tensor()[0],
+		 F.f2());
             else
               pgai = std::make_shared<ga_instruction_eval_func_2arg_1res_expr>
-                (pnode->t[0], child1->t[0], child2->t[0], F);
-          } else if (child1->t.size() == 1) {
+                (pnode->tensor()[0], child1->tensor()[0], child2->tensor()[0],
+		 F);
+          } else if (child1->tensor().size() == 1) {
             if (F.ftype() == 0)
-              pgai = std::make_shared<ga_instruction_eval_func_2arg_first_scalar>
-                (pnode->t, child1->t, child2->t, F.f2());
+              pgai =
+		std::make_shared<ga_instruction_eval_func_2arg_first_scalar>
+                (pnode->tensor(), child1->tensor(), child2->tensor(), F.f2());
             else
-              pgai = std::make_shared<ga_instruction_eval_func_2arg_first_scalar_expr>
-                (pnode->t, child1->t, child2->t, F);
-          } else if (child2->t.size() == 1) {
+              pgai =
+	      std::make_shared<ga_instruction_eval_func_2arg_first_scalar_expr>
+                (pnode->tensor(), child1->tensor(), child2->tensor(), F);
+          } else if (child2->tensor().size() == 1) {
             if (F.ftype() == 0)
-              pgai = std::make_shared<ga_instruction_eval_func_2arg_second_scalar>
-                (pnode->t, child1->t, child2->t, F.f2());
+              pgai =
+		std::make_shared<ga_instruction_eval_func_2arg_second_scalar>
+                (pnode->tensor(), child1->tensor(), child2->tensor(), F.f2());
             else
-              pgai = std::make_shared<ga_instruction_eval_func_2arg_second_scalar_expr>
-                (pnode->t, child1->t, child2->t, F);
+              pgai =
+	      std::make_shared<ga_instruction_eval_func_2arg_second_scalar_expr>
+                (pnode->tensor(), child1->tensor(), child2->tensor(), F);
           } else {
             if (F.ftype() == 0)
               pgai = std::make_shared<ga_instruction_eval_func_2arg>
-                (pnode->t, child1->t, child2->t, F.f2());
+                (pnode->tensor(), child1->tensor(), child2->tensor(), F.f2());
             else
               pgai = std::make_shared<ga_instruction_eval_func_2arg_expr>
-                (pnode->t, child1->t, child2->t, F);
+                (pnode->tensor(), child1->tensor(), child2->tensor(), F);
           }
         }
         rmi.instructions.push_back(std::move(pgai));
@@ -10691,37 +12708,39 @@ namespace getfem {
         const ga_nonlinear_operator &OP = *(it->second);
         ga_nonlinear_operator::arg_list args;
         for (size_type i = 1; i < pnode->children.size(); ++i)
-          args.push_back(&(pnode->children[i]->t));
+          args.push_back(&(pnode->children[i]->tensor()));
 
         if (child0->der1 && child0->der2 == 0) {
           pgai = std::make_shared<ga_instruction_eval_derivative_OP>
-             (pnode->t, OP, args, child0->der1);
+             (pnode->tensor(), OP, args, child0->der1);
         } else if (child0->der1 && child0->der2) {
           pgai = std::make_shared<ga_instruction_eval_second_derivative_OP>
-             (pnode->t, OP, args, child0->der1, child0->der2);
+             (pnode->tensor(), OP, args, child0->der1, child0->der2);
         } else {
-          pgai = std::make_shared<ga_instruction_eval_OP>(pnode->t, OP, args);
+          pgai = std::make_shared<ga_instruction_eval_OP>(pnode->tensor(),
+							  OP, args);
         }
         rmi.instructions.push_back(std::move(pgai));
 
       } else { // Access to a component of the tensor
         bgeot::multi_index mi1(size0.size()), indices;
-        if (pnode->t.size() == 1) {
+        if (pnode->tensor().size() == 1) {
           for (size_type i = 0; i < child0->tensor_order(); ++i)
-            mi1[i] = size_type(round(pnode->children[i+1]->t[0])-1);
+            mi1[i] = size_type(round(pnode->children[i+1]->tensor()[0])-1);
           pgai = std::make_shared<ga_instruction_copy_scalar>
-            (pnode->t[0], child0->t(mi1));
+            (pnode->tensor()[0], child0->tensor()(mi1));
         } else {
           size_type nb_test = pnode->nb_test_functions();
           for (size_type i = 0; i < nb_test; ++i) indices.push_back(i);
           for (size_type i = 0; i < child0->tensor_order(); ++i) {
             if (pnode->children[i+1]->node_type != GA_NODE_ALLINDICES)
-              mi1[i+nb_test] = size_type(round(pnode->children[i+1]->t[0])-1);
+              mi1[i+nb_test]
+		= size_type(round(pnode->children[i+1]->tensor()[0])- 1);
             else
               indices.push_back(i+nb_test);
           }
           pgai = std::make_shared<ga_instruction_tensor_slice>
-            (pnode->t, child0->t, mi1, indices);
+            (pnode->tensor(), child0->tensor(), mi1, indices);
         }
         rmi.instructions.push_back(std::move(pgai));
       }
@@ -10731,7 +12750,15 @@ namespace getfem {
     default:GMM_ASSERT1(false, "Unexpected node type " << pnode->node_type
                         << " in compilation. Internal error.");
     }
+    if (tensor_to_clear) {
+      gmm::clear(pnode->tensor().as_vector());
+      if (!is_uniform) {
+	pgai = std::make_shared<ga_instruction_clear_tensor>(pnode->tensor());
+	rmi.elt_instructions.push_back(std::move(pgai));
+      } 
+    }
     rmi.node_list[pnode->hash_value].push_back(pnode);
+    
   }
 
   static void ga_compile_function(ga_workspace &workspace,
@@ -10742,7 +12769,7 @@ namespace getfem {
       gis.trees.push_back(*(td.ptree));
       pga_tree_node root = gis.trees.back().root;
       if (root) {
-        GMM_ASSERT1(!scalar || (root->t.size() == 1),
+        GMM_ASSERT1(!scalar || (root->tensor().size() == 1),
                     "The result of the given expression is not a scalar");
         ga_instruction_set::region_mim rm(td.mim, td.rg);
         gis.whole_instructions[rm].m = td.m;
@@ -10754,12 +12781,12 @@ namespace getfem {
         pga_instruction pgai;
         if (scalar) {
           pgai = std::make_shared<ga_instruction_scalar_assembly>
-            (root->t, workspace.assembled_potential(), gis.coeff);
+            (root->tensor(), workspace.assembled_potential(), gis.coeff);
 
         } else {
-          workspace.assembled_tensor() = root->t;
+          workspace.assembled_tensor() = root->tensor();
           pgai = std::make_shared<ga_instruction_add_to>
-            (workspace.assembled_tensor(), root->t);
+            (workspace.assembled_tensor(), root->tensor());
         }
         gis.whole_instructions[rm].instructions.push_back(std::move(pgai));
       }
@@ -10800,7 +12827,7 @@ namespace getfem {
     for (size_type i = 0; i < pnode->children.size(); ++i)
       found = ga_node_used_interpolates(pnode->children[i], workspace,
                                         interpolates, interpolates_der)
-        || found;
+	|| found;
     return found;
   }
 
@@ -10842,7 +12869,8 @@ namespace getfem {
       for (const std::string &nodename : transformation.second) {
         if (rmi.transformations[transname].count(nodename) == 0) {
           auto&& inin = rmi.interpolate_infos[transname];
-          pga_instruction pgai = std::make_shared<ga_instruction_update_group_info>
+          pga_instruction pgai =
+	    std::make_shared<ga_instruction_update_group_info>
             (workspace, gis, inin, nodename, inin.groups_info[nodename]);
           rmi.instructions.push_back(std::move(pgai));
           rmi.transformations[transname].insert(nodename);
@@ -10857,7 +12885,7 @@ namespace getfem {
     gis.whole_instructions.clear();
     for (size_type i = 0; i < workspace.nb_trees(); ++i) {
       const ga_workspace::tree_description &td = workspace.tree_info(i);
-      if (td.order == 0) {
+      if (td.interpolation > 0) {
         gis.trees.push_back(*(td.ptree));
 
         // Semantic analysis mainly to evaluate fixed size variables and data
@@ -10878,9 +12906,9 @@ namespace getfem {
                           rmi.current_hierarchy);
 
           // After compile tree
-          workspace.assembled_tensor() = root->t;
+          workspace.assembled_tensor() = root->tensor();
           pga_instruction pgai = std::make_shared<ga_instruction_add_to>
-            (workspace.assembled_tensor(), root->t);
+            (workspace.assembled_tensor(), root->tensor());
           rmi.instructions.push_back(std::move(pgai));
         }
       }
@@ -10891,140 +12919,203 @@ namespace getfem {
                          ga_instruction_set &gis, size_type order) {
     gis.transformations.clear();
     gis.whole_instructions.clear();
-    for (size_type i = 0; i < workspace.nb_trees(); ++i) {
-      ga_workspace::tree_description &td = workspace.tree_info(i);
-      if (td.order == order) {
-        gis.trees.push_back(*(td.ptree));
-
-        // Semantic analysis mainly to evaluate fixed size variables and data
-        ga_semantic_analysis("", gis.trees.back(), workspace,
-                             td.mim->linked_mesh().dim(),
-                             ref_elt_dim_of_mesh(td.mim->linked_mesh()),
-                             true, false);
-        pga_tree_node root = gis.trees.back().root;
-        if (root) {
-          // Compiling tree
-          // cout << "Will compile "; ga_print_node(root, cout); cout << endl;
-
-          ga_instruction_set::region_mim rm(td.mim, td.rg);
-          ga_instruction_set::region_mim_instructions &rmi
-            = gis.whole_instructions[rm];
-          rmi.m = td.m;
-          // rmi.interpolate_infos.clear();
-          ga_compile_interpolate_trans(root, workspace, gis, rmi, *(td.m));
-          ga_compile_node(root, workspace, gis, rmi, *(td.m), false,
-                          rmi.current_hierarchy);
-          // cout << "compilation finished "; ga_print_node(root, cout);
-          // cout << endl;
-
-          // Addition of an assembly instruction
-          pga_instruction pgai;
-          switch(order) {
-          case 0:
-            pgai = std::make_shared<ga_instruction_scalar_assembly>
-              (root->t, workspace.assembled_potential(), gis.coeff);
-            break;
-          case 1:
-            {
-              const mesh_fem *mf = workspace.associated_mf(root->name_test1);
-              const mesh_fem **mfg = 0;
-              add_interval_to_gis(workspace, root->name_test1, gis);
-
-              if (mf) {
-                const std::string &intn1 = root->interpolate_name_test1;
-                const gmm::sub_interval *Ir = 0, *In = 0;
-                if (intn1.size() &&
-                    workspace.variable_group_exists(root->name_test1)) {
-                  ga_instruction_set::variable_group_info &vgi =
-                    rmi.interpolate_infos[intn1].groups_info[root->name_test1];
-                  Ir = &(vgi.Ir);
-                  In = &(vgi.In);
-                  mfg = &(vgi.mf);
-                  mf = 0;
-                } else {
-                  Ir = &(gis.var_intervals[root->name_test1]);
-                  In = &(workspace.interval_of_variable(root->name_test1));
-                }
-                fem_interpolation_context &ctx
-                  = intn1.size() ? rmi.interpolate_infos[intn1].ctx
-                                 : gis.ctx;
-                pgai = std::make_shared<ga_instruction_fem_vector_assembly>
-                  (root->t, workspace.unreduced_vector(),
-                   workspace.assembled_vector(), ctx, *Ir, *In, mf, mfg,
-                   gis.coeff);
-              } else {
-                pgai = std::make_shared<ga_instruction_vector_assembly>
-                    (root->t, workspace.assembled_vector(),
-                     workspace.interval_of_variable(root->name_test1),
-                     gis.coeff);
-              }
-            }
-            break;
-          case 2:
-            {
-              const mesh_fem *mf1 = workspace.associated_mf(root->name_test1);
-              const mesh_fem *mf2 = workspace.associated_mf(root->name_test2);
-              const mesh_fem **mfg1 = 0, **mfg2 = 0;
-              const std::string &intn1 = root->interpolate_name_test1;
-              const std::string &intn2 = root->interpolate_name_test2;
-              fem_interpolation_context &ctx1
-                = intn1.empty() ? gis.ctx
-                                : rmi.interpolate_infos[intn1].ctx;
-              fem_interpolation_context &ctx2
-                = intn2.empty() ? gis.ctx
-                                : rmi.interpolate_infos[intn2].ctx;
-              bool interpolate
-                = (!intn1.empty() && intn1.compare("neighbour_elt")!=0)
-                || (!intn2.empty() && intn2.compare("neighbour_elt")!=0);
-
-              add_interval_to_gis(workspace, root->name_test1, gis);
-              add_interval_to_gis(workspace, root->name_test2, gis);
-
-              const gmm::sub_interval *Ir1 = 0, *In1 = 0, *Ir2 = 0, *In2 = 0;
-              const scalar_type *alpha1 = 0, *alpha2 = 0;
-
-              if (!intn1.empty() &&
-                  workspace.variable_group_exists(root->name_test1)) {
-                ga_instruction_set::variable_group_info &vgi =
-                  rmi.interpolate_infos[intn1].groups_info[root->name_test1];
-                Ir1 = &(vgi.Ir);
-                In1 = &(vgi.In);
-                mfg1 = &(vgi.mf);
-                mf1 = 0;
-                alpha1 = &(vgi.alpha);
-              } else {
-                alpha1 = &(workspace.factor_of_variable(root->name_test1));
-                Ir1 = &(gis.var_intervals[root->name_test1]);
-                In1 = &(workspace.interval_of_variable(root->name_test1));
-              }
-
-              if (!intn2.empty() &&
-                  workspace.variable_group_exists(root->name_test2)) {
-                ga_instruction_set::variable_group_info &vgi =
-                  rmi.interpolate_infos[intn2].groups_info[root->name_test2];
-                Ir2 = &(vgi.Ir);
-                In2 = &(vgi.In);
-                mfg2 = &(vgi.mf);
-                mf2 = 0;
-                alpha2 = &(vgi.alpha);
-              } else {
-                alpha2 = &(workspace.factor_of_variable(root->name_test2));
-                Ir2 = &(gis.var_intervals[root->name_test2]);
-                In2 = &(workspace.interval_of_variable(root->name_test2));
-              }
+    for (size_type version : std::array<size_type, 3>{1, 0, 2}) {
+      for (size_type i = 0; i < workspace.nb_trees(); ++i) {
+	ga_workspace::tree_description &td = workspace.tree_info(i);
+	
+	if ((version == td.interpolation) &&
+	    ((version == 0 && td.order == order) || // Assembly
+	     ((version > 0 && (td.order == size_type(-1) || // Assignment
+				td.order == size_type(-2) - order))))) {
+	  ga_tree *added_tree = 0;
+	  if (td.interpolation) {
+	    gis.interpolation_trees.push_back(*(td.ptree));
+	    added_tree = &(gis.interpolation_trees.back());
+	  } else {
+	    gis.trees.push_back(*(td.ptree));
+	    added_tree = &(gis.trees.back());
+	  }
 
-              pgai = std::make_shared< ga_instruction_matrix_assembly<> >
-                (root->t, workspace.unreduced_matrix(),
-                 workspace.assembled_matrix(), ctx1, ctx2,
-                 *Ir1, *In1, *Ir2, *In2, mf1, mfg1, mf2, mfg2,
-                 gis.coeff, *alpha1, *alpha2, gis.nbpt, gis.ipt,
-                 td.elem, interpolate);
-              break;
-            }
-          }
-          if (pgai)
-            gis.whole_instructions[rm].instructions.push_back(std::move(pgai));
-        }
+	  // Semantic analysis mainly to evaluate fixed size variables and data
+	  ga_semantic_analysis("", *added_tree, workspace,
+			       td.mim->linked_mesh().dim(),
+			       ref_elt_dim_of_mesh(td.mim->linked_mesh()),
+			       true, false);
+	  pga_tree_node root = added_tree->root;
+	  if (root) {
+	    // Compile tree
+	    // cout << "Will compile "; ga_print_node(root, cout); cout << endl;
+
+	    ga_instruction_set::region_mim rm(td.mim, td.rg);
+	    ga_instruction_set::region_mim_instructions &rmi
+	      = gis.whole_instructions[rm];
+	    rmi.m = td.m;
+	    // rmi.interpolate_infos.clear();
+	    ga_compile_interpolate_trans(root, workspace, gis, rmi, *(td.m));
+	    ga_compile_node(root, workspace, gis, rmi, *(td.m), false,
+			    rmi.current_hierarchy);
+	    // cout << "compilation finished "; ga_print_node(root, cout);
+	    // cout << endl;
+
+	    if (version > 0) { // Assignment OR interpolation
+	      if(td.varname_interpolation.size() != 0) {// assignment
+	        auto *imd
+		  = workspace.associated_im_data(td.varname_interpolation);
+	        auto &V = const_cast<model_real_plain_vector &>
+            (workspace.value(td.varname_interpolation));
+	        GMM_ASSERT1(imd, "Internal error");
+	        auto pgai = std::make_shared<ga_instruction_assignment>
+            (root->tensor(), V, gis.ctx, imd);
+	        rmi.instructions.push_back(std::move(pgai));
+        }
+	    } else { // assembly
+	      // Addition of an assembly instruction
+	      pga_instruction pgai;
+	      switch(order) {
+	      case 0:
+		pgai = std::make_shared<ga_instruction_scalar_assembly>
+		  (root->tensor(), workspace.assembled_potential(), gis.coeff);
+		break;
+	      case 1:
+		{
+		  const mesh_fem *mf=workspace.associated_mf(root->name_test1);
+		  const mesh_fem **mfg = 0;
+		  add_interval_to_gis(workspace, root->name_test1, gis);
+		  
+		  if (mf) {
+		    const std::string &intn1 = root->interpolate_name_test1;
+		    const gmm::sub_interval *Ir = 0, *In = 0;
+		    if (intn1.size() &&
+			workspace.variable_group_exists(root->name_test1)) {
+		      ga_instruction_set::variable_group_info &vgi =
+			rmi.interpolate_infos[intn1]
+			.groups_info[root->name_test1];
+		      Ir = &(vgi.Ir);
+		      In = &(vgi.In);
+		      mfg = &(vgi.mf);
+		      mf = 0;
+		    } else {
+		      Ir = &(gis.var_intervals[root->name_test1]);
+		      In = &(workspace.interval_of_variable(root->name_test1));
+		    }
+		    fem_interpolation_context &ctx
+		      = intn1.size() ? rmi.interpolate_infos[intn1].ctx
+		      : gis.ctx;
+		    bool interpolate
+		      = (!intn1.empty() && intn1.compare("neighbour_elt")!=0);
+		    pgai = std::make_shared<ga_instruction_fem_vector_assembly>
+		      (root->tensor(), workspace.unreduced_vector(),
+		       workspace.assembled_vector(), ctx, *Ir, *In, mf, mfg,
+		       gis.coeff, gis.nbpt, gis.ipt, interpolate);
+		  } else {
+		    pgai = std::make_shared<ga_instruction_vector_assembly>
+		      (root->tensor(), workspace.assembled_vector(),
+		       workspace.interval_of_variable(root->name_test1),
+		       gis.coeff);
+		  }
+		}
+		break;
+	      case 2:
+		{
+		  const mesh_fem *mf1=workspace.associated_mf(root->name_test1);
+		  const mesh_fem *mf2=workspace.associated_mf(root->name_test2);
+		  const mesh_fem **mfg1 = 0, **mfg2 = 0;
+		  const std::string &intn1 = root->interpolate_name_test1;
+		  const std::string &intn2 = root->interpolate_name_test2;
+		  fem_interpolation_context &ctx1
+		    = intn1.empty() ? gis.ctx
+		    : rmi.interpolate_infos[intn1].ctx;
+		  fem_interpolation_context &ctx2
+		    = intn2.empty() ? gis.ctx
+		    : rmi.interpolate_infos[intn2].ctx;
+		  bool interpolate
+		    = (!intn1.empty() && intn1.compare("neighbour_elt")!=0)
+		    || (!intn2.empty() && intn2.compare("neighbour_elt")!=0);
+		  
+		  add_interval_to_gis(workspace, root->name_test1, gis);
+		  add_interval_to_gis(workspace, root->name_test2, gis);
+		  
+		  const gmm::sub_interval *Ir1 = 0, *In1 = 0, *Ir2 = 0, *In2=0;
+		  const scalar_type *alpha1 = 0, *alpha2 = 0;
+		  
+		  if (!intn1.empty() &&
+		      workspace.variable_group_exists(root->name_test1)) {
+		    ga_instruction_set::variable_group_info &vgi =
+		      rmi.interpolate_infos[intn1]
+		      .groups_info[root->name_test1];
+		    Ir1 = &(vgi.Ir);
+		    In1 = &(vgi.In);
+		    mfg1 = &(vgi.mf);
+		    mf1 = 0;
+		    alpha1 = &(vgi.alpha);
+		  } else {
+		    alpha1 = &(workspace.factor_of_variable(root->name_test1));
+		    Ir1 = &(gis.var_intervals[root->name_test1]);
+		    In1 = &(workspace.interval_of_variable(root->name_test1));
+		  }
+		  
+		  if (!intn2.empty() &&
+		      workspace.variable_group_exists(root->name_test2)) {
+		    ga_instruction_set::variable_group_info &vgi =
+		      rmi.interpolate_infos[intn2]
+		      .groups_info[root->name_test2];
+		    Ir2 = &(vgi.Ir);
+		    In2 = &(vgi.In);
+		    mfg2 = &(vgi.mf);
+		    mf2 = 0;
+		    alpha2 = &(vgi.alpha);
+		  } else {
+		    alpha2 = &(workspace.factor_of_variable(root->name_test2));
+		    Ir2 = &(gis.var_intervals[root->name_test2]);
+		    In2 = &(workspace.interval_of_variable(root->name_test2));
+		  }
+		  
+		  if (!interpolate && mfg1 == 0 && mfg2 == 0 && mf1 && mf2
+		      && mf1->get_qdim() == 1 && mf2->get_qdim() == 1
+		      && !(mf1->is_reduced()) && !(mf2->is_reduced())) {
+		    pgai = std::make_shared
+		      <ga_instruction_matrix_assembly_standard_scalar<>>
+		      (root->tensor(), workspace.assembled_matrix(), ctx1, ctx2,
+		       *In1, *In2, mf1, mf2,
+		       gis.coeff, *alpha1, *alpha2, gis.nbpt, gis.ipt);
+		  } else if (!interpolate && mfg1 == 0 && mfg2==0 && mf1 && mf2
+			     && !(mf1->is_reduced()) && !(mf2->is_reduced())) {
+		    if (root->sparsity() == 10 && root->t.qdim()==2)
+		      pgai = std::make_shared
+			<ga_instruction_matrix_assembly_standard_vector_opt10_2>
+			(root->tensor(), workspace.assembled_matrix(),ctx1,ctx2,
+			 *In1, *In2, mf1, mf2,
+			 gis.coeff, *alpha1, *alpha2, gis.nbpt, gis.ipt);
+		    else if (root->sparsity() == 10 && root->t.qdim()==3)
+		      pgai = std::make_shared
+			<ga_instruction_matrix_assembly_standard_vector_opt10_3>
+			(root->tensor(), workspace.assembled_matrix(),ctx1,ctx2,
+			 *In1, *In2, mf1, mf2,
+			 gis.coeff, *alpha1, *alpha2, gis.nbpt, gis.ipt);
+		    else
+		      pgai = std::make_shared
+			<ga_instruction_matrix_assembly_standard_vector<>>
+			(root->tensor(), workspace.assembled_matrix(),ctx1,ctx2,
+			 *In1, *In2, mf1, mf2,
+			 gis.coeff, *alpha1, *alpha2, gis.nbpt, gis.ipt);
+		    
+		  } else {
+		    pgai = std::make_shared<ga_instruction_matrix_assembly<>>
+		      (root->tensor(), workspace.unreduced_matrix(),
+		       workspace.assembled_matrix(), ctx1, ctx2,
+		       *Ir1, *In1, *Ir2, *In2, mf1, mfg1, mf2, mfg2,
+		       gis.coeff, *alpha1, *alpha2, gis.nbpt, gis.ipt,
+		       interpolate);
+		  }
+		  break;
+		}
+	      }
+	      if (pgai)
+		gis.whole_instructions[rm].instructions.push_back
+		  (std::move(pgai));
+	    }
+	  }
+	}
       }
     }
   }
@@ -11063,13 +13154,13 @@ namespace getfem {
       const getfem::mesh &m = *(it->second.m);
       GMM_ASSERT1(&m == &(gic.linked_mesh()),
                   "Incompatibility of meshes in interpolation");
+      ga_instruction_list &gilb = it->second.begin_instructions;
+      ga_instruction_list &gile = it->second.elt_instructions;
       ga_instruction_list &gil = it->second.instructions;
 
       // iteration on elements (or faces of elements)
       std::vector<size_type> ind;
-      mesh_region rg(region);
-      m.intersect_with_mpi_region(rg);
-      for (getfem::mr_visitor v(rg, m); !v.finished(); ++v) {
+      for (getfem::mr_visitor v(region, m, true); !v.finished(); ++v) {
         if (gic.use_mim()) {
           if (!mim.convex_index().is_in(v.cv())) continue;
           gis.pai = mim.int_method_of_element(v.cv())->approx_method();
@@ -11081,22 +13172,18 @@ namespace getfem {
           = gic.ppoints_for_element(v.cv(), v.f(), ind);
 
         if (pspt.get() && ind.size() && pspt->size()) {
-          bgeot::vectors_to_base_matrix(G, m.points_of_convex(v.cv()));
+          m.points_of_convex(v.cv(), G);
           bgeot::pgeometric_trans pgt = m.trans_of_convex(v.cv());
           up.resize(G.nrows());
           un.resize(pgt->dim());
 
           if (gis.ctx.have_pgp() && gis.ctx.pgt() == pgt) {
-            gis.ctx = fem_interpolation_context(gis.ctx.pgp(), 0, 0, G,
-                                                v.cv(), v.f());
+            gis.ctx.change(gis.ctx.pgp(), 0, 0, G, v.cv(), v.f());
           } else {
             if (!(gic.use_pgp(v.cv()))) {
-              gis.ctx = fem_interpolation_context(pgt, 0, (*pspt)[0], G,
-                                                  v.cv(), v.f());
+              gis.ctx.change(pgt, 0, (*pspt)[0], G, v.cv(), v.f());
             } else {
-              bgeot::pgeotrans_precomp pgp = gis.gp_pool(pgt, pspt);
-              gis.ctx = fem_interpolation_context(pgp, 0, 0, G,
-                                                  v.cv(), v.f());
+              gis.ctx.change(gis.gp_pool(pgt, pspt), 0, 0, G, v.cv(), v.f());
             }
           }
 
@@ -11106,8 +13193,8 @@ namespace getfem {
           // iterations on interpolation points
           gis.nbpt = pspt->size();
           for (size_type ii = 0; ii < ind.size(); ++ii) {
-            gis.ipt = ind[ii];
-            if (gis.ctx.have_pgp()) gis.ctx.set_ii(gis.ipt);
+            gis.ipt = ii;
+            if (gis.ctx.have_pgp()) gis.ctx.set_ii(ind[ii]);
             else gis.ctx.set_xref((*pspt)[gis.ipt]);
 
             if (ii == 0 || !(pgt->is_linear())) {
@@ -11118,12 +13205,17 @@ namespace getfem {
                 gmm::mult(B, un, up);
                 scalar_type nup = gmm::vect_norm2(up);
                 gmm::scale(up,1.0/nup);
+                gmm::clean(up, 1e-13);
                 gis.Normal = up;
               } else gis.Normal.resize(0);
             }
             gmm::clear(workspace.assembled_tensor().as_vector());
+            if (ii == 0) {
+              for (size_type j = 0; j < gilb.size(); ++j) j += gilb[j]->exec();
+	      for (size_type j = 0; j < gile.size(); ++j) j += gile[j]->exec();
+	    }
             for (size_type j = 0; j < gil.size(); ++j) j += gil[j]->exec();
-            gic.store_result(v.cv(), gis.ipt, workspace.assembled_tensor());
+            gic.store_result(v.cv(), ind[ii], workspace.assembled_tensor());
           }
         }
       }
@@ -11151,6 +13243,10 @@ namespace getfem {
       const getfem::mesh &m = *(it->second.m);
       GMM_ASSERT1(&m == &interp_mesh,
                   "Incompatibility of meshes in interpolation");
+      ga_instruction_list &gilb = it->second.begin_instructions;
+      for (size_type j = 0; j < gilb.size(); ++j) j += gilb[j]->exec();
+      ga_instruction_list &gile = it->second.elt_instructions;
+      for (size_type j = 0; j < gile.size(); ++j) j+=gile[j]->exec();
       ga_instruction_list &gil = it->second.instructions;
       for (size_type j = 0; j < gil.size(); ++j) j += gil[j]->exec();
     }
@@ -11158,7 +13254,7 @@ namespace getfem {
 
   static void ga_exec(ga_instruction_set &gis, ga_workspace &workspace) {
     base_matrix G;
-    base_small_vector un, up;
+    base_small_vector un;
     scalar_type J(0);
 
     for (const std::string &t : gis.transformations)
@@ -11168,84 +13264,100 @@ namespace getfem {
       const getfem::mesh_im &mim = *(instr.first.mim());
       const getfem::mesh &m = *(instr.second.m);
       GMM_ASSERT1(&m == &(mim.linked_mesh()), "Incompatibility of meshes");
+      const ga_instruction_list &gilb = instr.second.begin_instructions;
+      const ga_instruction_list &gile = instr.second.elt_instructions;
       const ga_instruction_list &gil = instr.second.instructions;
+#if 0
+      if (gilb.size()) cout << "Begin instructions\n";
+      for (size_type j = 0; j < gilb.size(); ++j)
+	cout << typeid(*(gilb[j])).name() << endl;
+      if (gile.size()) cout << "\nElement instructions\n";
+      for (size_type j = 0; j < gile.size(); ++j)
+	cout << typeid(*(gile[j])).name() << endl;
+      cout << "\nGauss pt instructions\n";
+      for (size_type j = 0; j < gil.size(); ++j)
+	cout << typeid(*(gil[j])).name() << endl;
+#endif
       const mesh_region &region = *(instr.first.region());
 
       // iteration on elements (or faces of elements)
-      mesh_region rg(region);
-      m.intersect_with_mpi_region(rg);
       size_type old_cv = size_type(-1);
-      bgeot::pgeometric_trans pgt = 0;
+      bgeot::pgeometric_trans pgt = 0, pgt_old = 0;
       pintegration_method pim = 0;
-      bgeot::pstored_point_tab pspt = 0;
-      for (getfem::mr_visitor v(rg, m); !v.finished(); ++v) {
-        if (mim.convex_index().is_in(v.cv())) {
-          // cout << "proceed with element " << v.cv() << endl;
+      papprox_integration pai = 0;
+      bgeot::pstored_point_tab pspt = 0, old_pspt = 0;
+      bgeot::pgeotrans_precomp pgp = 0;
+      bool first_gp = true;
+      for (getfem::mr_visitor v(region, m, true); !v.finished(); ++v) {
+	if (mim.convex_index().is_in(v.cv())) {
+          // cout << "proceed with elt " << v.cv() << " face " << v.f() << endl;
           if (v.cv() != old_cv) {
-            bgeot::vectors_to_base_matrix(G, m.points_of_convex(v.cv()));
             pgt = m.trans_of_convex(v.cv());
-            up.resize(G.nrows());
-            un.resize(pgt->dim());
-            pim = mim.int_method_of_element(v.cv());
-            if (pim->type() == IM_NONE)
-              continue;
-            // cout << "pim->type() = " << int(pim->type()) <<  " : " << int(IM_APPROX) << endl;
+	    pim = mim.int_method_of_element(v.cv());
+	    m.points_of_convex(v.cv(), G);
+
+            if (pim->type() == IM_NONE) continue;
             GMM_ASSERT1(pim->type() == IM_APPROX, "Sorry, exact methods cannot "
                         "be used in high level generic assembly");
-            // cout << "passed ..." << endl;
-
-            pspt = pim->approx_method()->pintegration_points();
-
+            pai = pim->approx_method();
+            pspt = pai->pintegration_points();
             if (pspt->size()) {
-              if (gis.ctx.have_pgp() && gis.pai == pim->approx_method() &&
-                  gis.ctx.pgt() == pgt) {
-                gis.ctx = fem_interpolation_context(gis.ctx.pgp(), 0, 0, G,
-                                                    v.cv(), v.f());
+              if (pgp && gis.pai == pai && pgt_old == pgt) {
+		gis.ctx.change(pgp, 0, 0, G, v.cv(), v.f());
               } else {
-                if (pim->approx_method()->is_built_on_the_fly()) {
-                  gis.ctx = fem_interpolation_context(pgt, 0, (*pspt)[0], G,
-                                                      v.cv(), v.f());
+                if (pai->is_built_on_the_fly()) {
+                  gis.ctx.change(pgt, 0, (*pspt)[0], G, v.cv(), v.f());
+		  pgp = 0;
                 } else {
-                  bgeot::pgeotrans_precomp pgp = gis.gp_pool(pgt, pspt);
-                  gis.ctx = fem_interpolation_context(pgp, 0, 0, G,
-                                                      v.cv(), v.f());
+		  pgp = gis.gp_pool(pgt, pspt);
+                  gis.ctx.change(pgp, 0, 0, G, v.cv(), v.f());
                 }
+		pgt_old = pgt; gis.pai = pai;
               }
-              gis.pai = pim->approx_method();
-              if (gis.need_elt_size)
-                gis.elt_size = m.convex_radius_estimate(v.cv())*scalar_type(2);
+              if (gis.need_elt_size) 
+                gis.elt_size = convex_radius_estimate(pgt, G)*scalar_type(2);
             }
             old_cv = v.cv();
           } else {
-            if (pim->type() == IM_NONE)
-              continue;
+            if (pim->type() == IM_NONE) continue;
             gis.ctx.set_face_num(v.f());
           }
+          if (pspt != old_pspt) { first_gp = true; old_pspt = pspt; }
           if (pspt->size()) {
             // iterations on Gauss points
-            gis.nbpt = gis.pai->nb_points_on_convex();
+            gis.nbpt = pai->nb_points_on_convex();
             size_type first_ind = 0;
             if (v.f() != short_type(-1)) {
-              gis.nbpt = gis.pai->nb_points_on_face(v.f());
-              first_ind = gis.pai->ind_first_point_on_face(v.f());
+              gis.nbpt = pai->nb_points_on_face(v.f());
+              first_ind = pai->ind_first_point_on_face(v.f());
             }
             for (gis.ipt = 0; gis.ipt < gis.nbpt; ++(gis.ipt)) {
-              if (gis.ctx.have_pgp()) gis.ctx.set_ii(first_ind+gis.ipt);
+	      if (pgp) gis.ctx.set_ii(first_ind+gis.ipt);
               else gis.ctx.set_xref((*pspt)[first_ind+gis.ipt]);
               if (gis.ipt == 0 || !(pgt->is_linear())) {
                 J = gis.ctx.J();
                 // Computation of unit normal vector in case of a boundary
                 if (v.f() != short_type(-1)) {
-                  gmm::copy(pgt->normals()[v.f()], un);
-                  gmm::mult(gis.ctx.B(), un, up);
-                  scalar_type nup = gmm::vect_norm2(up);
+		  gis.Normal.resize(G.nrows());
+		  un.resize(pgt->dim());
+		  gmm::copy(pgt->normals()[v.f()], un);
+                  gmm::mult(gis.ctx.B(), un, gis.Normal);
+                  scalar_type nup = gmm::vect_norm2(gis.Normal);
                   J *= nup;
-                  gmm::scale(up,1.0/nup);
-                  gis.Normal = up;
+                  gmm::scale(gis.Normal, 1.0/nup);
+                  gmm::clean(gis.Normal, 1e-13);
                 } else gis.Normal.resize(0);
               }
-              gis.coeff = J * gis.pai->coeff(first_ind+gis.ipt);
-              for (size_type j = 0; j < gil.size(); ++j) j += gil[j]->exec();
+              gis.coeff = J * pai->coeff(first_ind+gis.ipt);
+              if (first_gp) {
+                for (size_type j = 0; j < gilb.size(); ++j) j+=gilb[j]->exec();
+                first_gp = false;
+              }
+	      if (gis.ipt == 0) {
+		for (size_type j = 0; j < gile.size(); ++j) j+=gile[j]->exec();
+	      }
+              for (size_type j = 0; j < gil.size(); ++j) j+=gil[j]->exec();
+              GA_DEBUG_INFO("");
             }
           }
         }
@@ -11274,7 +13386,7 @@ namespace getfem {
     : local_workspace(gaf.local_workspace), expr(gaf.expr), gis(0)
   { if (gaf.gis) compile(); }
 
-  void ga_function::compile(void) const {
+  void ga_function::compile() const {
     if (gis) delete gis;
     gis = new ga_instruction_set;
     local_workspace.clear_expressions();
@@ -11283,7 +13395,8 @@ namespace getfem {
   }
 
   ga_function &ga_function::operator =(const ga_function &gaf) {
-    if (gis) delete gis; gis = 0;
+    if (gis) delete gis;
+    gis = 0;
     local_workspace = gaf.local_workspace;
     expr = gaf.expr;
     if (gaf.gis) compile();
@@ -11292,7 +13405,7 @@ namespace getfem {
 
   ga_function::~ga_function() { if (gis) delete gis; gis = 0; }
 
-  const base_tensor &ga_function::eval(void) const {
+  const base_tensor &ga_function::eval() const {
     GMM_ASSERT1(gis, "Uncompiled function");
     gmm::clear(local_workspace.assembled_tensor().as_vector());
     ga_function_exec(*gis);
@@ -11315,7 +13428,8 @@ namespace getfem {
       }
       expr = ga_tree_to_string(tree);
     }
-    if (gis) delete gis; gis = 0;
+    if (gis) delete gis;
+    gis = 0;
     compile();
   }
 
@@ -11363,7 +13477,7 @@ namespace getfem {
     }
 
     virtual bool use_pgp(size_type) const { return true; }
-    virtual bool use_mim(void) const { return false; }
+    virtual bool use_mim() const { return false; }
 
     void init_(size_type si, size_type q, size_type qmult) {
       s = si;
@@ -11403,7 +13517,7 @@ namespace getfem {
       (dof_count[idof/q])++;
     }
 
-    virtual void finalize(void) {
+    virtual void finalize() {
       std::vector<size_type> data(3);
       data[0] = initialized ? result.size() : 0;
       data[1] = initialized ? dof_count.size() : 0;
@@ -11412,13 +13526,11 @@ namespace getfem {
       if (!initialized) {
         if (data[0]) {
           gmm::resize(result, data[0]);
-          gmm::clear(result);
           gmm::resize(dof_count, data[1]);
           gmm::clear(dof_count);
           s = data[2];
-        } else {
-          gmm::clear(result);
         }
+        gmm::clear(result);
       }
       if (initialized)
         GMM_ASSERT1(gmm::vect_size(result) == data[0] &&  s == data[2] &&
@@ -11431,13 +13543,17 @@ namespace getfem {
                      scalar_type(1) / scalar_type(dof_count[i]));
     }
 
-    virtual const mesh &linked_mesh(void) { return mf.linked_mesh(); }
+    virtual const mesh &linked_mesh() { return mf.linked_mesh(); }
 
     ga_interpolation_context_fem_same_mesh(const mesh_fem &mf_, base_vector &r)
       : result(r), mf(mf_), initialized(false), is_torus(false) {
       GMM_ASSERT1(!(mf.is_reduced()),
                   "Interpolation on reduced fem is not allowed");
-      if (dynamic_cast<const torus_mesh_fem*>(&mf)) is_torus = true;
+      if (dynamic_cast<const torus_mesh_fem*>(&mf)){
+        auto first_cv = mf.first_convex_of_basic_dof(0);
+        auto target_dim = mf.fem_of_element(first_cv)->target_dim();
+        if (target_dim == 3) is_torus = true;
+      }
     }
   };
 
@@ -11478,7 +13594,7 @@ namespace getfem {
     }
 
     virtual bool use_pgp(size_type) const { return false; }
-    virtual bool use_mim(void) const { return false; }
+    virtual bool use_mim() const { return false; }
 
     virtual void store_result(size_type cv, size_type i, base_tensor &t) {
       size_type si = t.size();
@@ -11495,7 +13611,7 @@ namespace getfem {
                gmm::sub_vector(result, gmm::sub_interval(s*dof_t, s)));
     }
 
-    virtual void finalize(void) {
+    virtual void finalize() {
       std::vector<size_type> data(2);
       data[0] = initialized ? result.size() : 0;
       data[1] = initialized ? s : 0;
@@ -11503,11 +13619,9 @@ namespace getfem {
       if (!initialized) {
         if (data[0]) {
           gmm::resize(result, data[0]);
-          gmm::clear(result);
           s = data[1];
-        } else {
-           gmm::clear(result);
         }
+        gmm::clear(result);
       }
       if (initialized)
         GMM_ASSERT1(gmm::vect_size(result) == data[0] &&  s == data[1],
@@ -11515,7 +13629,7 @@ namespace getfem {
       MPI_SUM_VECTOR(result);
     }
 
-    virtual const mesh &linked_mesh(void) { return mti.linked_mesh(); }
+    virtual const mesh &linked_mesh() { return mti.linked_mesh(); }
 
     ga_interpolation_context_mti(const mesh_trans_inv &mti_, base_vector &r,
                                  size_type nbdof_ = size_type(-1))
@@ -11572,7 +13686,7 @@ namespace getfem {
                   "be used in high level generic assembly");
       return !(pim->approx_method()->is_built_on_the_fly());
     }
-    virtual bool use_mim(void) const { return true; }
+    virtual bool use_mim() const { return true; }
 
     virtual void store_result(size_type cv, size_type i, base_tensor &t) {
       size_type si = t.size();
@@ -11597,7 +13711,7 @@ namespace getfem {
                gmm::sub_vector(result, gmm::sub_interval(s*ipt, s)));
     }
 
-    virtual void finalize(void) {
+    virtual void finalize() {
       std::vector<size_type> data(2);
       data[0] = initialized ? result.size() : 0;
       data[1] = initialized ? s : 0;
@@ -11608,38 +13722,120 @@ namespace getfem {
       } else {
         if (data[0]) {
           gmm::resize(result, data[0]);
-          gmm::clear(result);
           s = data[1];
-        } else {
-           gmm::clear(result);
         }
+        gmm::clear(result);
       }
       MPI_SUM_VECTOR(result);
     }
 
-    virtual const mesh &linked_mesh(void)
-    { return imd.linked_mesh_im().linked_mesh(); }
+    virtual const mesh &linked_mesh() { return imd.linked_mesh(); }
 
     ga_interpolation_context_im_data(const im_data &imd_, base_vector &r)
       : result(r), imd(imd_), initialized(false) { }
   };
 
   void ga_interpolation_im_data
+  (ga_workspace &workspace, const im_data &imd, base_vector &result) {
+    ga_interpolation_context_im_data gic(imd, result);
+    ga_interpolation(workspace, gic);
+  }
+
+  void ga_interpolation_im_data
   (const getfem::model &md, const std::string &expr, const im_data &imd,
    base_vector &result, const mesh_region &rg) {
     ga_workspace workspace(md);
     workspace.add_interpolation_expression
       (expr, imd.linked_mesh_im(), rg);
 
-    ga_interpolation_im_data(workspace, imd, result, rg);
+    ga_interpolation_im_data(workspace, imd, result);
   }
 
-  void ga_interpolation_im_data
-  (ga_workspace &workspace, const im_data &imd, base_vector &result, const mesh_region &/* rg */) {
-    ga_interpolation_context_im_data gic(imd, result);
+
+  // Interpolation on a stored_mesh_slice
+  struct ga_interpolation_context_mesh_slice
+    : public ga_interpolation_context {
+    base_vector &result;
+    const stored_mesh_slice &sl;
+    bool initialized;
+    size_type s;
+    std::vector<size_type> first_node;
+
+    virtual bgeot::pstored_point_tab
+    ppoints_for_element(size_type cv, short_type f,
+                        std::vector<size_type> &ind) const {
+      GMM_ASSERT1(f == short_type(-1), "No support for interpolation on faces"
+                                       " for a stored_mesh_slice yet.");
+      size_type ic = sl.convex_pos(cv);
+      mesh_slicer::cs_nodes_ct nodes = sl.nodes(ic);
+      std::vector<base_node> pt_tab(nodes.size());
+      for (size_type i=0; i < nodes.size(); ++i) {
+        pt_tab[i] = nodes[i].pt_ref;
+        ind.push_back(i);
+      }
+      return store_point_tab(pt_tab);
+    }
+
+    virtual bool use_pgp(size_type /* cv */) const { return false; } // why not?
+    virtual bool use_mim() const { return false; }
+
+    virtual void store_result(size_type cv, size_type i, base_tensor &t) {
+      size_type si = t.size();
+      if (!initialized) {
+        s = si;
+        gmm::resize(result, s * sl.nb_points());
+        gmm::clear(result);
+        initialized = true;
+        first_node.resize(sl.nb_convex());
+        for (size_type ic=0; ic < sl.nb_convex()-1; ++ic)
+          first_node[ic+1] = first_node[ic] + sl.nodes(ic).size();
+      }
+      GMM_ASSERT1(s == si && result.size() == s * sl.nb_points(), "Internal error");
+      size_type ic = sl.convex_pos(cv);
+      size_type ipt = first_node[ic] + i;
+      gmm::add(t.as_vector(),
+               gmm::sub_vector(result, gmm::sub_interval(s*ipt, s)));
+    }
+
+    virtual void finalize() {
+      std::vector<size_type> data(2);
+      data[0] = initialized ? result.size() : 0;
+      data[1] = initialized ? s : 0;
+      MPI_MAX_VECTOR(data);
+      if (initialized) {
+        GMM_ASSERT1(gmm::vect_size(result) == data[0] &&  s == data[1],
+                    "Incompatible sizes");
+      } else {
+        if (data[0]) {
+          gmm::resize(result, data[0]);
+          s = data[1];
+        }
+        gmm::clear(result);
+      }
+      MPI_SUM_VECTOR(result);
+    }
+
+    virtual const mesh &linked_mesh() { return sl.linked_mesh(); }
+
+    ga_interpolation_context_mesh_slice(const stored_mesh_slice &sl_, base_vector &r)
+      : result(r), sl(sl_), initialized(false) { }
+  };
+
+  void ga_interpolation_mesh_slice
+  (ga_workspace &workspace, const stored_mesh_slice &sl, base_vector &result) {
+    ga_interpolation_context_mesh_slice gic(sl, result);
     ga_interpolation(workspace, gic);
   }
 
+  void ga_interpolation_mesh_slice
+  (const getfem::model &md, const std::string &expr, const stored_mesh_slice &sl,
+   base_vector &result, const mesh_region &rg) {
+    ga_workspace workspace(md);
+    workspace.add_interpolation_expression(expr, sl.linked_mesh(), rg);
+    ga_interpolation_mesh_slice(workspace, sl, result);
+  }
+
+
   //=========================================================================
   // Local projection functions
   //=========================================================================
@@ -11671,18 +13867,17 @@ namespace getfem {
     gmm::resize(result, mf.nb_dof());
     gmm::copy(gmm::sub_vector(residual, I), F);
 
-    mesh_region rg(region);
-    mf.linked_mesh().intersect_with_mpi_region(rg);
-
     getfem::base_matrix loc_M;
     getfem::base_vector loc_U;
-    for (mr_visitor v(rg); !v.finished(); v.next()) {
-      size_type nd = mf.nb_basic_dof_of_element(v.cv());
-      gmm::resize(loc_M, nd, nd); gmm::resize(loc_U, nd);
-      gmm::sub_index J(mf.ind_basic_dof_of_element(v.cv()));
-      gmm::copy(gmm::sub_matrix(M, J, J), loc_M);
-      gmm::lu_solve(loc_M, loc_U, gmm::sub_vector(F, J));
-      gmm::copy(loc_U, gmm::sub_vector(result, J));
+    for (mr_visitor v(region, mf.linked_mesh(), true); !v.finished(); ++v) {
+      if (mf.convex_index().is_in(v.cv())) {
+	size_type nd = mf.nb_basic_dof_of_element(v.cv());
+	loc_M.base_resize(nd, nd); gmm::resize(loc_U, nd);
+	gmm::sub_index J(mf.ind_basic_dof_of_element(v.cv()));
+	gmm::copy(gmm::sub_matrix(M, J, J), loc_M);
+	gmm::lu_solve(loc_M, loc_U, gmm::sub_vector(F, J));
+	gmm::copy(loc_U, gmm::sub_vector(result, J));
+      }
     }
     MPI_SUM_VECTOR(result);
   }
@@ -11826,7 +14021,7 @@ namespace getfem {
       }
     }
 
-    void finalize(void) const {
+    void finalize() const {
       for (const std::string &transname : local_gis.transformations)
         local_workspace.interpolate_transformation(transname)->finalize();
       local_gis = ga_instruction_set();
@@ -11954,13 +14149,13 @@ namespace getfem {
     : public virtual_interpolate_transformation, public context_dependencies {
 
   public:
-    void update_from_context(void) const {}
+    void update_from_context() const {}
     void extract_variables(const ga_workspace &/* workspace */,
                            std::set<var_trans_pair> &/* vars */,
                            bool /* ignore_data */, const mesh &/* m */,
                            const std::string &/* interpolate_name */) const {}
     void init(const ga_workspace &/* workspace */) const {}
-    void finalize(void) const {}
+    void finalize() const {}
 
     int transform(const ga_workspace &/*workspace*/, const mesh &m_x,
                   fem_interpolation_context &ctx_x,
@@ -11997,7 +14192,7 @@ namespace getfem {
       return ret_type;
     }
 
-    interpolate_transformation_neighbour(void) { }
+    interpolate_transformation_neighbour() { }
 
   };
 
@@ -12009,5 +14204,118 @@ namespace getfem {
     return p;
   }
 
+  //=========================================================================
+  // Interpolate transformation on neighbour element (for extrapolation)
+  //=========================================================================
+
+  class interpolate_transformation_element_extrapolation
+    : public virtual_interpolate_transformation, public context_dependencies {
+
+    const mesh &sm;
+    std::map<size_type, size_type> elt_corr;
+
+  public:
+    void update_from_context() const {}
+    void extract_variables(const ga_workspace &/* workspace */,
+                           std::set<var_trans_pair> &/* vars */,
+                           bool /* ignore_data */, const mesh &/* m */,
+                           const std::string &/* interpolate_name */) const {}
+    void init(const ga_workspace &/* workspace */) const {}
+    void finalize() const {}
+
+    int transform(const ga_workspace &/*workspace*/, const mesh &m_x,
+                  fem_interpolation_context &ctx_x,
+                  const base_small_vector &/*Normal*/, const mesh **m_t,
+                  size_type &cv, short_type &face_num,
+                  base_node &P_ref,
+                  base_small_vector &/*N_y*/,
+                  std::map<var_trans_pair, base_tensor> &/*derivatives*/,
+                  bool compute_derivatives) const {
+
+      int ret_type = 0;
+      *m_t = &m_x;
+      GMM_ASSERT1(&sm == &m_x, "Bad mesh");
+      size_type cv_x = ctx_x.convex_num(), cv_y = cv_x;
+      auto it = elt_corr.find(cv_x);
+      if (it != elt_corr.end()) cv_y = it->second;
+
+      if (cv_x != cv_y) {
+        bgeot::geotrans_inv_convex gic;
+        gic.init(m_x.points_of_convex(cv_y),
+                 m_x.trans_of_convex(cv_y));
+        bool converged = true;
+        gic.invert(ctx_x.xreal(), P_ref, converged, 1E-4);
+        GMM_ASSERT1(converged, "Geometric transformation inversion "
+                    "has failed in element extrapolation transformation");
+        face_num = short_type(-1);
+        cv = cv_y;
+        ret_type = 1;
+      } else {
+	cv = cv_x;
+	P_ref = ctx_x.xref();
+	ret_type = 1;
+      }
+      GMM_ASSERT1(!compute_derivatives,
+                  "No derivative for this transformation");
+      return ret_type;
+    }
+
+    void set_correspondance(const std::map<size_type, size_type> &ec) {
+      elt_corr = ec;
+    }
+
+    interpolate_transformation_element_extrapolation
+    (const mesh &sm_, const std::map<size_type, size_type> &ec)
+      : sm(sm_), elt_corr(ec) { }
+  };
+
+
+  void add_element_extrapolation_transformation
+  (model &md, const std::string &name, const mesh &sm,
+   std::map<size_type, size_type> &elt_corr) {
+    pinterpolate_transformation
+      p = std::make_shared<interpolate_transformation_element_extrapolation>
+      (sm, elt_corr);
+    md.add_interpolate_transformation(name, p);
+  }
+
+  void add_element_extrapolation_transformation
+  (ga_workspace &workspace, const std::string &name, const mesh &sm,
+   std::map<size_type, size_type> &elt_corr) {
+    pinterpolate_transformation
+      p = std::make_shared<interpolate_transformation_element_extrapolation>
+      (sm, elt_corr);
+    workspace.add_interpolate_transformation(name, p);
+  }
+
+  void set_element_extrapolation_correspondance
+  (ga_workspace &workspace, const std::string &name,
+   std::map<size_type, size_type> &elt_corr) {
+    GMM_ASSERT1(workspace.interpolate_transformation_exists(name),
+		"Unknown transformation");
+    auto pit=workspace.interpolate_transformation(name).get();
+    auto cpext
+      = dynamic_cast<const interpolate_transformation_element_extrapolation *>
+      (pit);
+    GMM_ASSERT1(cpext,
+		"The transformation is not of element extrapolation type");
+    const_cast<interpolate_transformation_element_extrapolation *>(cpext)
+      ->set_correspondance(elt_corr);
+  }
+    
+  void set_element_extrapolation_correspondance
+  (model &md, const std::string &name,
+   std::map<size_type, size_type> &elt_corr) {
+    GMM_ASSERT1(md.interpolate_transformation_exists(name),
+		"Unknown transformation");
+    auto pit=md.interpolate_transformation(name).get();
+    auto cpext
+      = dynamic_cast<const interpolate_transformation_element_extrapolation *>
+      (pit);
+    GMM_ASSERT1(cpext,
+		"The transformation is not of element extrapolation type");
+    const_cast<interpolate_transformation_element_extrapolation *>(cpext)
+      ->set_correspondance(elt_corr);
+  }
 
 } /* end of namespace */
diff --git a/src/getfem_global_function.cc b/src/getfem_global_function.cc
index a0873d1..d443a25 100644
--- a/src/getfem_global_function.cc
+++ b/src/getfem_global_function.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
  Copyright (C) 2016      Konstantinos Poulios
 
  This file is a part of GetFEM++
@@ -55,13 +55,17 @@ namespace getfem {
   // Implementation of global_function_parser
 
   scalar_type global_function_parser::val(const base_node &pt) const {
-    gmm::copy(pt, pt_);
-    const bgeot::base_tensor &t = f_val.eval();
+    const bgeot::base_tensor &t = tensor_val(pt);
     GMM_ASSERT1(t.size() == 1, "Wrong size of expression result "
                 << f_val.expression());
     return t[0];
   }
 
+  const base_tensor &global_function_parser::tensor_val(const base_node &pt) const {
+    gmm::copy(pt, pt_);
+    return f_val.eval();
+  }
+
   void global_function_parser::grad(const base_node &pt, base_small_vector &g) const {
     g.resize(dim_);
     gmm::copy(pt, pt_);
@@ -134,18 +138,60 @@ namespace getfem {
     }
   }
 
+  bool global_function_sum::is_in_support(const base_node &p) const {
+    for (const auto &f : functions)
+      if (f->is_in_support(p)) return true;
+    return false;
+  }
+
+  void global_function_sum::bounding_box
+  (base_node &bmin_, base_node &bmax_) const {
+    if (functions.size() > 0)
+      functions[0]->bounding_box(bmin_, bmax_);
+    base_node bmin0(dim()), bmax0(dim());
+    for (const auto &f : functions) {
+      f->bounding_box(bmin0, bmax0);
+      for (size_type i=0; i < dim(); ++i) {
+        if (bmin0[i] < bmin_[i]) bmin_[i] = bmin0[i];
+        if (bmax0[i] > bmax_[i]) bmax_[i] = bmax0[i];
+      }
+    }
+  }
+
   global_function_sum::global_function_sum(const std::vector<pglobal_function> &funcs)
     : global_function((funcs.size() > 0) ? funcs[0]->dim() : 0), functions(funcs) {
     for (const auto &f : functions)
       GMM_ASSERT1(f->dim() == dim(), "Incompatible dimensions among the provided"
                                      " global functions");
   }
+
   global_function_sum::global_function_sum(pglobal_function f1, pglobal_function f2)
     : global_function(f1->dim()), functions(2) {
     functions[0] = f1;
     functions[1] = f2;
-    GMM_ASSERT1(f2->dim() == dim(), "Incompatible dimensions between the provided"
-                                    " global functions");
+    GMM_ASSERT1(f1->dim() == dim() && f2->dim() == dim(),
+                "Incompatible dimensions between the provided global functions");
+  }
+
+  global_function_sum::global_function_sum(pglobal_function f1, pglobal_function f2,
+                                           pglobal_function f3)
+    : global_function(f1->dim()), functions(3) {
+    functions[0] = f1;
+    functions[1] = f2;
+    functions[2] = f3;
+    GMM_ASSERT1(f1->dim() == dim() && f2->dim() == dim() && f3->dim() == dim(),
+                "Incompatible dimensions between the provided global functions");
+  }
+
+  global_function_sum::global_function_sum(pglobal_function f1, pglobal_function f2,
+                                           pglobal_function f3, pglobal_function f4)
+    : global_function(f1->dim()), functions(4) {
+    functions[0] = f1;
+    functions[1] = f2;
+    functions[2] = f3;
+    functions[3] = f4;
+    GMM_ASSERT1(f1->dim() == dim() && f2->dim() == dim() && f3->dim() == dim(),
+                "Incompatible dimensions between the provided global functions");
   }
 
 
@@ -182,6 +228,23 @@ namespace getfem {
     gmm::rank_one_update(h, g2, g1);
   }
 
+  bool global_function_product::is_in_support(const base_node &p) const {
+    return f1->is_in_support(p) && f2->is_in_support(p);
+  }
+
+  void global_function_product::bounding_box
+  (base_node &bmin_, base_node &bmax_) const {
+    base_node bmin0(dim()), bmax0(dim());
+    f1->bounding_box(bmin0, bmax0);
+    f2->bounding_box(bmin_, bmax_);
+    for (size_type i=0; i < dim(); ++i) {
+      if (bmin0[i] > bmin_[i]) bmin_[i] = bmin0[i];
+      if (bmax0[i] < bmax_[i]) bmax_[i] = bmax0[i];
+      if (bmin_[i] > bmax_[i])
+        GMM_WARNING1("Global function product with vanishing basis function");
+    }
+  }
+
   global_function_product::global_function_product(pglobal_function f1_, pglobal_function f2_)
     : global_function(f1_->dim()), f1(f1_), f2(f2_) {
     GMM_ASSERT1(f2->dim() == dim(), "Incompatible dimensions between the provided"
diff --git a/src/getfem_im_data.cc b/src/getfem_im_data.cc
index 7c002c6..6a05dae 100644
--- a/src/getfem_im_data.cc
+++ b/src/getfem_im_data.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2012-2016 Liang Jin Lim.
+ Copyright (C) 2012-2017 Liang Jin Lim.
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem_import.cc b/src/getfem_import.cc
index 03e8040..6860d80 100644
--- a/src/getfem_import.cc
+++ b/src/getfem_import.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Julien Pommier
+ Copyright (C) 2000-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -56,7 +56,7 @@ namespace getfem {
         pgt = bgeot::prism_geotrans(3,1);
       } break;
       case 7: { /* PYRAMID */
-        GMM_ASSERT1(false, "sorry pyramidal elements not yet supported.");
+	pgt = bgeot::pyramidal_geotrans(1);
       } break;
       case 8: { /* 2ND ORDER LINE */
         pgt = bgeot::simplex_geotrans(1,2);
@@ -123,8 +123,7 @@ namespace getfem {
         nodes.resize(6);
       } break;
       case 7: { /* PYRAMID */
-        GMM_ASSERT1(false,
-                    "sorry pyramidal elements not done for the moment..");
+	nodes.resize(5);
       } break;
       case 8: { /* 2ND ORDER LINE */
         nodes.resize(3);
@@ -355,6 +354,13 @@ namespace getfem {
         ci.nodes[6] = tmp_nodes[7];
         ci.nodes[7] = tmp_nodes[6];
       } break;
+      case 7 : { /* first order pyramid */
+        //ci.nodes[0] = tmp_nodes[0];
+        ci.nodes[1] = tmp_nodes[2];
+        ci.nodes[2] = tmp_nodes[1];
+        // ci.nodes[3] = tmp_nodes[3];
+        // ci.nodes[4] = tmp_nodes[4];
+      } break;
       case 8 : { /* Second order line */
         //ci.nodes[0] = tmp_nodes[0];
         ci.nodes[1] = tmp_nodes[2];
@@ -769,10 +775,13 @@ namespace getfem {
         if (only_digits) {
           size_type type_num;
           sscanf(type_name, "%lu", &type_num);
-          if (type_num == 45 || type_num == 87 || type_num == 90 ||
-              type_num == 92 || type_num == 95 || type_num == 162 ||
-              type_num == 185 || type_num == 186 || type_num == 187 ||
-              type_num == 191)
+          if (type_num == 42 || type_num == 82 ||
+              type_num == 182 || type_num == 183)
+            elt_types[itype] = "PLANE";
+          else if (type_num == 45 || type_num == 73 || type_num == 87 ||
+                   type_num == 90 || type_num == 92 || type_num == 95 ||
+                   type_num == 162 || type_num == 185 || type_num == 186 ||
+                   type_num == 187 || type_num == 191)
             elt_types[itype] = "SOLID";
           else if (type_num == 89)
             elt_types[itype] = "VISCO";
@@ -839,55 +848,91 @@ namespace getfem {
       std::getline(f,line);
     }
 
-    // EBLOCK, NUM_NODES, SOLKEY
-    //EBLOCK,19,SOLID,    825431,    110833
-    size_type elements2read;
-    pos = line.find_last_of(",");
-    sscanf(line.substr(pos+1).c_str(), "%lu", &elements2read);
 
     //(19i8)
     size_type fieldsno, fieldwidth; // 19,8
-    std::string elt_info_fmt;
+    std::string elt_info_fmt, imat_fmt;
     { // "%8lu%8lu%8lu%8lu%8lu%8lu%8lu%8lu"
       std::string fortran_fmt;
       std::getline(f,fortran_fmt);
       sscanf(fortran_fmt.c_str(),"(%lu%*[i]%lu)", &fieldsno, &fieldwidth);
       GMM_ASSERT1(fieldsno == 19, "Ansys mesh import routine requires EBLOCK entries "
                                   "with 19 fields");
-      std::stringstream ss;
-      for (size_type i=0; i < 19; ++i)
+      std::stringstream ss0, ss;
+      ss0 << "%" << fieldwidth << "li";
+      imat_fmt = ss0.str();
+      for (size_type i=0; i < 10; ++i)
         ss << "%" << fieldwidth << "lu";
       elt_info_fmt = ss.str();
     }
 
     size_type II,JJ,KK,LL,MM,NN,OO,PP,QQ,RR,SS,TT,UU,VV,WW,XX,YY,ZZ,AA,BB;
-    for (size_type i=0; i < elements2read; ++i) {
+    while (true) {
       GMM_ASSERT1(!f.eof(), "File ended before all elements could be read");
       size_type imat, itype, realconst, isection, coordsys, deathflag,
                 modelref, shapeflag, nodesno, notused, eltid;
       std::getline(f,line);
-      sscanf(line.substr(0,11*fieldwidth).c_str(), elt_info_fmt.c_str(),
-             &imat, &itype, &realconst, &isection, &coordsys, &deathflag,
+      {
+        long int ii;
+        sscanf(line.substr(0,fieldwidth).c_str(), imat_fmt.c_str(),
+               &ii);
+        if (ii < 0)
+          break;
+        else
+          imat = size_type(ii);
+
+        if (imat_filt != size_type(-1) && imat != imat_filt) { // skip current element
+          if (nodesno > 8)
+            std::getline(f,line);
+          continue;
+        }
+      }
+      sscanf(line.substr(fieldwidth,11*fieldwidth).c_str(), elt_info_fmt.c_str(),
+             &itype, &realconst, &isection, &coordsys, &deathflag,
              &modelref, &shapeflag, &nodesno, &notused, &eltid);
       line = line.substr(11*fieldwidth);
 
-      if (imat_filt != size_type(-1) && imat != imat_filt) { // skip current element
-        if (nodesno > 8)
-          std::getline(f,line);
-        continue;
-      }
-
       if (imat+1 > regions.size())
         regions.resize(imat+1);
 
       if (nodesno == 3) {
-        // TODO MESH200_2
-      }
-      else if (nodesno == 3) {
-        // TODO MESH200_3, MESH200_4
+        // TODO MESH200_2, MESH200_3, MESH200_4
       }
       else if (nodesno == 4) {
-        // TODO MESH200_6, MESH200_8
+
+        sscanf(line.c_str(), elt_info_fmt.c_str(),
+               &II, &JJ, &KK, &LL);
+
+        // assume MESH200_6 (4-node quadrilateral)
+        std::string eltname("MESH200_6");
+        if (elt_types.size() > itype && elt_types[itype].size() > 0)
+          eltname = elt_types[itype];
+
+        if (eltname.compare("MESH200_6") == 0 ||
+            eltname.compare("PLANE42") == 0 ||
+            eltname.compare("PLANE182") == 0) {
+          getfem_cv_nodes.resize(4);
+          getfem_cv_nodes[0] = cdb_node_2_getfem_node[II];
+          getfem_cv_nodes[1] = cdb_node_2_getfem_node[JJ];
+          getfem_cv_nodes[2] = cdb_node_2_getfem_node[LL];
+          getfem_cv_nodes[3] = cdb_node_2_getfem_node[KK];
+          regions[imat].add(m.add_convex(bgeot::parallelepiped_geotrans(2,1),
+                                         getfem_cv_nodes.begin()));
+          if (itype < elt_cnt.size())
+            elt_cnt[itype] += 1;
+        }
+        else if (eltname.compare("MESH200_8") == 0 ||
+                 eltname.compare("SOLID72") == 0) {
+          getfem_cv_nodes.resize(4);
+          getfem_cv_nodes[0] = cdb_node_2_getfem_node[II];
+          getfem_cv_nodes[1] = cdb_node_2_getfem_node[JJ];
+          getfem_cv_nodes[2] = cdb_node_2_getfem_node[KK];
+          getfem_cv_nodes[3] = cdb_node_2_getfem_node[LL];
+          regions[imat].add(m.add_convex(bgeot::simplex_geotrans(3,1),
+                                         getfem_cv_nodes.begin()));
+          if (itype < elt_cnt.size())
+            elt_cnt[itype] += 1;
+        }
       }
       else if (nodesno == 6) {
         // TODO MESH200_5
@@ -902,8 +947,22 @@ namespace getfem {
         if (elt_types.size() > itype && elt_types[itype].size() > 0)
           eltname = elt_types[itype];
 
-        if (eltname.compare("MESH200_7") == 0) {
-          // TODO 8-node quadrilateral
+        if (eltname.compare("MESH200_7") == 0 ||
+            eltname.compare("PLANE82") == 0 ||
+            eltname.compare("PLANE183") == 0) {
+          getfem_cv_nodes.resize(8);
+          getfem_cv_nodes[0] = cdb_node_2_getfem_node[II];
+          getfem_cv_nodes[1] = cdb_node_2_getfem_node[MM];
+          getfem_cv_nodes[2] = cdb_node_2_getfem_node[JJ];
+          getfem_cv_nodes[3] = cdb_node_2_getfem_node[PP];
+          getfem_cv_nodes[4] = cdb_node_2_getfem_node[NN];
+          getfem_cv_nodes[5] = cdb_node_2_getfem_node[LL];
+          getfem_cv_nodes[6] = cdb_node_2_getfem_node[OO];
+          getfem_cv_nodes[7] = cdb_node_2_getfem_node[KK];
+          regions[imat].add(m.add_convex(bgeot::Q2_incomplete_geotrans(2),
+                                         getfem_cv_nodes.begin()));
+          if (itype < elt_cnt.size())
+            elt_cnt[itype] += 1;
         }
         else if (eltname.compare("MESH200_10") == 0 ||
                  eltname.compare("SOLID45") == 0 ||
@@ -1017,9 +1076,9 @@ namespace getfem {
             if (itype < elt_cnt.size())
               elt_cnt[itype] += 1;
           } else if (MM == NN && NN == OO && OO == PP) { // assume 13-node pyramid
-            GMM_ASSERT1(false, "Ansys 13-node pyramid elements are not supported yet");
-          } else if (KK == LL && OO == PP) { // assume 15-node pyramid
-            GMM_ASSERT1(false, "Ansys 15-node prism elements are not supported yet");
+            GMM_ASSERT1(false, "Ansys 13-node pyramid elements are not supported yet, import to be done");
+          } else if (KK == LL && OO == PP) { // assume 15-node prism
+            GMM_ASSERT1(false, "Ansys 15-node prism elements are not supported yet, import to be done");
           } else {
             getfem_cv_nodes.resize(20);
             getfem_cv_nodes[0] = cdb_node_2_getfem_node[II];
diff --git a/src/getfem_integration.cc b/src/getfem_integration.cc
index 29381b4..047fc3f 100644
--- a/src/getfem_integration.cc
+++ b/src/getfem_integration.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -830,68 +830,89 @@ namespace getfem {
   struct quasi_polar_integration : public approx_integration {
     quasi_polar_integration(papprox_integration base_im, 
 			    size_type ip1, size_type ip2=size_type(-1)) : 
-      approx_integration(bgeot::simplex_of_reference(base_im->dim()))  {
+      approx_integration
+      ((base_im->structure() == bgeot::parallelepiped_structure(3)) ?
+       bgeot::pyramidal_element_of_reference(1)
+       : bgeot::simplex_of_reference(base_im->dim()))  {
       size_type N = base_im->dim();
 
-      enum { SQUARE, PRISM, PYRAMID, PRISM2 } what;
+      enum { SQUARE, PRISM, TETRA_CYL, PRISM2, PYRAMID } what;
       if (N == 2) what = SQUARE;
       else if (base_im->structure() == bgeot::prism_structure(3))
 	what = (ip2 == size_type(-1) || ip1 == ip2) ? PRISM2 : PRISM;
       else if (base_im->structure() == bgeot::simplex_structure(3))
+	what = TETRA_CYL;
+      else if (base_im->structure() == bgeot::parallelepiped_structure(3))
 	what = PYRAMID;
       else GMM_ASSERT1(false, "Incoherent integration method");
 
       // The first geometric transformation collapse a face of
-      // a parallelepiped.
+      // a parallelepiped or collapse a parrallelepiped on a pyramid.
       // The second geometric transformation chooses the orientation.
-      // The third is used for the PYRAMID case only.
+      // The third is used for the TETRA_CYL case only.
       bgeot::pgeometric_trans pgt1 = bgeot::parallelepiped_geotrans(N,1);
+      std::vector<base_node> nodes1 = pgt1->convex_ref()->points();
       bgeot::pgeometric_trans pgt2 = bgeot::simplex_geotrans(N, 1);
+      std::vector<base_node> nodes2(N+1);
+      if (what == PYRAMID) {
+	pgt2 = bgeot::pyramidal_geotrans(1);
+	nodes2.resize(5);
+      }
+      std::vector<size_type> other_nodes; // for the construction of node2
       bgeot::pgeometric_trans pgt3 = bgeot::simplex_geotrans(N, 1);
-      std::vector<base_node> nodes1 = pgt1->convex_ref()->points();
-      std::vector<base_node> nodes2(N+1), nodes3(N+1);
-      std::vector<size_type> other_nodes;
+      std::vector<base_node> nodes3(N+1);
 
       switch (what) {
-	case SQUARE :
-	  nodes1[3] = nodes1[1];
-	  nodes2[ip1] = nodes1[1]; ip2 = ip1;
-	  other_nodes.push_back(0);
-	  other_nodes.push_back(2);
-	  break;
-	case PRISM :
-	  nodes1[4] = nodes1[0]; nodes1[5] = nodes1[1];
-	  nodes2[ip1] = nodes1[0];
-	  nodes2[ip2] = nodes1[1];
-	  other_nodes.push_back(2);
-	  other_nodes.push_back(6);
-	  break;
-	case PYRAMID :
-	  nodes3[0] = nodes1[0]; nodes3[1] = nodes1[1];
-	  nodes3[2] = nodes1[2]; nodes3[3] = nodes1[4];
-	  // nodes1[4] = nodes1[0]; nodes1[7] = base_node(1.0, 1.0, 2.0);
-	  nodes2[ip1] = nodes1[1]; ip2 = ip1;
-	  other_nodes.push_back(0);
-	  other_nodes.push_back(2);
-	  other_nodes.push_back(4);
-	  break;
-	case PRISM2 :
-	  nodes2[ip1] = nodes1[4];
-	  other_nodes.push_back(0);
-	  other_nodes.push_back(1);
-	  other_nodes.push_back(2);
-	  break;
+      case SQUARE :
+	nodes1[3] = nodes1[1];
+	nodes2[ip1] = nodes1[1]; ip2 = ip1;
+	other_nodes.push_back(0);
+	other_nodes.push_back(2);
+	break;
+      case PRISM :
+	nodes1[4] = nodes1[0]; nodes1[5] = nodes1[1];
+	nodes2[ip1] = nodes1[0];
+	nodes2[ip2] = nodes1[1];
+	other_nodes.push_back(2);
+	other_nodes.push_back(6);
+	break;
+      case TETRA_CYL :
+	nodes3[0] = nodes1[0]; nodes3[1] = nodes1[1];
+	nodes3[2] = nodes1[2]; nodes3[3] = nodes1[4];
+	// nodes1[4] = nodes1[0]; nodes1[7] = base_node(1.0, 1.0, 2.0);
+	nodes2[ip1] = nodes1[1]; ip2 = ip1;
+	other_nodes.push_back(0);
+	other_nodes.push_back(2);
+	other_nodes.push_back(4);
+	break;
+      case PRISM2 :
+	nodes2[ip1] = nodes1[4];
+	other_nodes.push_back(0);
+	other_nodes.push_back(1);
+	other_nodes.push_back(2);
+	break;
+      case PYRAMID :
+	ip2 = ip1 = 0;
+	nodes1[0] =  base_node(-1.,-1., 0.);
+	nodes1[1] =  base_node( 1.,-1., 0.);
+	nodes1[2] =  base_node(-1., 1., 0.);
+	nodes1[3] =  base_node( 1., 1., 0.);
+	nodes1[4] =  base_node( 0., 0., 1.);
+	nodes1[5] =  nodes1[6] = nodes1[7] =  nodes1[4];
+	nodes2[ip1] = nodes1[0];
+	other_nodes.push_back(4);
+	other_nodes.push_back(3);
+	other_nodes.push_back(2);
+	other_nodes.push_back(1);
       }
 
-      for (size_type i = 0; i <= N; ++i)
+      for (size_type i = 0; i <= nodes2.size()-1; ++i)
 	if (i != ip1 && i != ip2) {
 	  GMM_ASSERT3(!other_nodes.empty(), "");
 	  nodes2[i] = nodes1[other_nodes.back()];
 	  other_nodes.pop_back();
 	}
 
-      //cout << "nodes2 = " << nodes2 << endl;
-
       base_matrix G1, G2, G3; 
       base_matrix K(N, N), grad(N, N), K3(N, N), K4(N, N);
       base_node normal1(N), normal2(N);
@@ -903,7 +924,7 @@ namespace getfem {
 
       for (size_type nc = 0; nc < 2; ++nc) {
 	
-	if (what == PYRAMID) {
+	if (what == TETRA_CYL) {
 	  if (nc == 1) nodes3[0] = nodes1[3];
 	  bgeot::vectors_to_base_matrix(G3, nodes3);
 	  pgt3->poly_vector_grad(nodes1[0], grad);
@@ -913,10 +934,10 @@ namespace getfem {
 
 	for (size_type i=0; i <  base_im->nb_points(); ++i) {
 
-	  gmm::copy(gmm::identity_matrix(), K4); J4=J1=scalar_type(1);
+	  gmm::copy(gmm::identity_matrix(), K4); J4 = J1 = scalar_type(1);
 
-	  size_type fp = size_type(-1);
-	  if (i >= base_im->nb_points_on_convex()) {
+	  size_type fp = size_type(-1); // Search the face number in the
+	  if (i >= base_im->nb_points_on_convex()) { // original element
 	    size_type ii = i - base_im->nb_points_on_convex();
 	    for (short_type ff=0; ff < base_im->structure()->nb_faces(); ++ff) {
 	      if (ii < base_im->nb_points_on_face(ff)) { fp = ff; break; }
@@ -926,7 +947,7 @@ namespace getfem {
 	  }
 
 	  base_node P = base_im->point(i);
-	  if (what == PYRAMID) { 
+	  if (what == TETRA_CYL) { 
 	    P = pgt3->transform(P, nodes3);
 	    scalar_type x = P[0], y = P[1], one_minus_z = 1.0 - P[2];
 	    K4(0, 1) = - y / one_minus_z;
@@ -950,7 +971,7 @@ namespace getfem {
 	  J1 = gmm::abs(gmm::lu_det(K)) * J3 * J4;
 
 	  if (fp != size_type(-1) && J1 > 1E-10 && J4 > 1E-10) {
-	    if (what == PYRAMID) {
+	    if (what == TETRA_CYL) {
 	      gmm::mult(K3, normal1, normal2);
 	      normal1 = normal2;
 	    }
@@ -962,7 +983,6 @@ namespace getfem {
 	    J1 *= gmm::vect_norm2(normal2);
 	    normal2 /= gmm::vect_norm2(normal2);
 	  }
-	  
 	  gic.invert(P1, P2);
 	  GMM_ASSERT1(pgt2->convex_ref()->is_in(P2) < 1E-8,
 		      "Point not in the convex ref : " << P2);
@@ -988,7 +1008,7 @@ namespace getfem {
 	    // else { cout << "Point " << P2 << " eliminated" << endl; }
 	  }  
 	}
-	if (what != PYRAMID) break;
+	if (what != TETRA_CYL) break;
       }
       valid_method();
     }
@@ -997,16 +1017,23 @@ namespace getfem {
 
   static pintegration_method quasi_polar(im_param_list &params,
 	std::vector<dal::pstatic_stored_object> &dependencies) {
-    GMM_ASSERT1(params.size() == 2 || params.size() == 3,
-		"Bad number of parameters : " << params.size()
-		<< " should be 2 or 3.");
-    GMM_ASSERT1(params[0].type() == 1 && params[1].type() == 0
-		&& params.back().type() == 0, "Bad type of parameters");
+    GMM_ASSERT1(params.size() >= 1 && params[0].type() == 1,
+		"Bad parameters for quasi polar integration: the first "
+		"parameter should be an integration method");
     pintegration_method a = params[0].method();
     GMM_ASSERT1(a->type()==IM_APPROX,"need an approximate integration method");
-
-    int ip1 = int(::floor(params[1].num() + 0.01));
-    int ip2 = int(::floor(params.back().num() + 0.01));
+    int ip1 = 0, ip2 = 0;
+    if (a->approx_method()->structure() == bgeot::parallelepiped_structure(3)) {
+      GMM_ASSERT1(params.size() == 1, "Bad number of parameters");
+    } else {
+      GMM_ASSERT1(params.size() == 2 || params.size() == 3,
+		  "Bad number of parameters : " << params.size()
+		  << " should be 2 or 3.");
+      GMM_ASSERT1(params[1].type() == 0
+		  && params.back().type() == 0, "Bad type of parameters");
+      ip1 = int(::floor(params[1].num() + 0.01));
+      ip2 = int(::floor(params.back().num() + 0.01));
+    }
     int N = a->approx_method()->dim();
     GMM_ASSERT1(N >= 2 && N <= 3 && ip1 >= 0 && ip2 >= 0 && ip1 <= N
 		&& ip2 <= N, "Bad parameters");
@@ -1020,6 +1047,25 @@ namespace getfem {
     return p;
   }
 
+  static pintegration_method pyramid(im_param_list &params,
+	std::vector<dal::pstatic_stored_object> &dependencies) {
+    GMM_ASSERT1(params.size() == 1 && params[0].type() == 1,
+		"Bad parameters for pyramid integration: the first "
+		"parameter should be an integration method");
+    pintegration_method a = params[0].method();
+    GMM_ASSERT1(a->type()==IM_APPROX,"need an approximate integration method");
+    int N = a->approx_method()->dim();
+    GMM_ASSERT1(N == 3, "Bad parameters");
+
+    papprox_integration
+      pai = std::make_shared<quasi_polar_integration>(a->approx_method(), 0, 0);
+    pintegration_method p = std::make_shared<integration_method>(pai);
+    dependencies.push_back(p->approx_method()->ref_convex());
+    dependencies.push_back(p->approx_method()->pintegration_points());
+    return p;
+  }
+
+
 
   /* ******************************************************************** */
   /*    Naming system                                                     */
@@ -1033,6 +1079,9 @@ namespace getfem {
   pintegration_method QUADC1_composite_int_method(im_param_list &params,
    std::vector<dal::pstatic_stored_object> &dependencies);
 
+  pintegration_method pyramid_composite_int_method(im_param_list &params,
+   std::vector<dal::pstatic_stored_object> &dependencies);
+
   struct im_naming_system : public dal::naming_system<integration_method> {
     im_naming_system() : dal::naming_system<integration_method>("IM") {
       add_suffix("NONE",im_none);
@@ -1046,12 +1095,15 @@ namespace getfem {
       add_suffix("NC_PRISM", Newton_Cotes_prism);
       add_suffix("GAUSS_PARALLELEPIPED", Gauss_paramul);
       add_suffix("QUASI_POLAR", quasi_polar);
+      add_suffix("PYRAMID", pyramid);
       add_suffix("STRUCTURED_COMPOSITE",
                  structured_composite_int_method);
       add_suffix("HCT_COMPOSITE",
                  HCT_composite_int_method);
       add_suffix("QUADC1_COMPOSITE",
                  QUADC1_composite_int_method);
+      add_suffix("PYRAMID_COMPOSITE",
+                 pyramid_composite_int_method);
       add_generic_function(im_list_integration);
     }
   };
diff --git a/src/getfem_integration_composite.cc b/src/getfem_integration_composite.cc
index ab262ce..828d0de 100644
--- a/src/getfem_integration_composite.cc
+++ b/src/getfem_integration_composite.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -183,7 +183,41 @@ namespace getfem {
     return p;
   }
 
+  struct just_for_singleton_pyramidc__ { mesh m; bgeot::mesh_precomposite mp; };
+  
+  pintegration_method pyramid_composite_int_method(im_param_list &params,
+	std::vector<dal::pstatic_stored_object> &dependencies) {
+
+    just_for_singleton_pyramidc__ &jfs
+      = dal::singleton<just_for_singleton_pyramidc__>::instance();
+
+    GMM_ASSERT1(params.size() == 1, "Bad number of parameters : "
+		<< params.size() << " should be 1.");
+    GMM_ASSERT1(params[0].type() == 1, "Bad type of parameters");
+    pintegration_method pim = params[0].method();
+    GMM_ASSERT1(pim->type() == IM_APPROX, "Bad parameters");
+    
+    jfs.m.clear();
+    size_type i0 = jfs.m.add_point(base_node(-1.0, -1.0, 0.0));
+    size_type i1 = jfs.m.add_point(base_node( 1.0, -1.0, 0.0));
+    size_type i2 = jfs.m.add_point(base_node(-1.0,  1.0, 0.0));
+    size_type i3 = jfs.m.add_point(base_node( 1.0,  1.0, 0.0));
+    size_type i4 = jfs.m.add_point(base_node( 0.0,  0.0, 1.0));
+    jfs.m.add_tetrahedron(i0, i1, i2, i4);
+    jfs.m.add_tetrahedron(i1, i3, i2, i4);
+    jfs.mp = bgeot::mesh_precomposite(jfs.m);
+
+    mesh_im mi(jfs.m);
+    mi.set_integration_method(jfs.m.convex_index(), pim);
 
+    pintegration_method
+      p = std::make_shared<integration_method>
+      (composite_approx_int_method(jfs.mp, mi,
+				   bgeot::pyramidal_element_of_reference(1)));
+    dependencies.push_back(p->approx_method()->ref_convex());
+    dependencies.push_back(p->approx_method()->pintegration_points());
+    return p;
+  }
 
 
   
diff --git a/src/getfem_interpolated_fem.cc b/src/getfem_interpolated_fem.cc
index 5926779..e58e3e7 100644
--- a/src/getfem_interpolated_fem.cc
+++ b/src/getfem_interpolated_fem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -172,8 +172,7 @@ namespace getfem {
   inline void interpolated_fem::actualize_fictx(pfem pf, size_type cv,
                                                 const base_node &ptr) const {
     if (fictx_cv != cv) {
-      bgeot::vectors_to_base_matrix
-        (G, mf.linked_mesh().points_of_convex(cv));
+      mf.linked_mesh().points_of_convex(cv, G);
       fictx = fem_interpolation_context
         (mf.linked_mesh().trans_of_convex(cv), pf, base_node(), G, cv,
          short_type(-1));
@@ -338,7 +337,7 @@ namespace getfem {
 
   void interpolated_fem::gauss_pts_stats(unsigned &ming, unsigned &maxg,
                                          scalar_type &meang) const {
-    std::vector<unsigned> v(mf.linked_mesh().convex_index().last_true()+1);
+    std::vector<unsigned> v(mf.linked_mesh().nb_allocated_convex());
     for (dal::bv_visitor cv(mim.linked_mesh().convex_index());
          !cv.finished(); ++cv) {
       for (unsigned ii=0; ii < elements.at(cv).gausspt.size(); ++ii) {
@@ -381,7 +380,7 @@ namespace getfem {
     DAL_STORED_OBJECT_DEBUG_CREATED(this, "Interpolated fem");
     this->add_dependency(mf);
     this->add_dependency(mim);
-    is_pol = is_lag = false; es_degree = 5;
+    is_pol = is_lag = is_standard_fem = false; es_degree = 5;
     is_equiv = real_element_defined = true;
     gmm::resize(trans, mf.linked_mesh().dim(), mf.linked_mesh().dim());
     ntarget_dim = mef.get_qdim();
diff --git a/src/getfem_interpolation.cc b/src/getfem_interpolation.cc
index bf88b59..73889e7 100644
--- a/src/getfem_interpolation.cc
+++ b/src/getfem_interpolation.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2001-2016 Yves Renard
+ Copyright (C) 2001-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -56,7 +56,7 @@ namespace getfem {
     bool all_convexes = (rg_source.id() == mesh_region::all_convexes().id());
 
     size_type nbpts = nb_points();
-    size_type nbcvx = msh.convex_index().last_true() + 1;
+    size_type nbcvx = msh.nb_allocated_convex();
     ref_coords.resize(nbpts);
     std::vector<double> dist(nbpts);
     std::vector<size_type> cvx_pts(nbpts);
diff --git a/src/getfem_level_set.cc b/src/getfem_level_set.cc
index ee08b42..f34101b 100644
--- a/src/getfem_level_set.cc
+++ b/src/getfem_level_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem_level_set_contact.cc b/src/getfem_level_set_contact.cc
index 90e73fc..bc26f87 100644
--- a/src/getfem_level_set_contact.cc
+++ b/src/getfem_level_set_contact.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2012-2016 Andriy Andreykiv
+ Copyright (C) 2012-2017 Andriy Andreykiv
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem_linearized_plates.cc b/src/getfem_linearized_plates.cc
index 55e2472..55cba5e 100644
--- a/src/getfem_linearized_plates.cc
+++ b/src/getfem_linearized_plates.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard, Jeremie Lasry, Mathieu Fabre
+ Copyright (C) 2004-2017 Yves Renard, Jeremie Lasry, Mathieu Fabre
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem_mat_elem.cc b/src/getfem_mat_elem.cc
index 65960e0..a5498f6 100644
--- a/src/getfem_mat_elem.cc
+++ b/src/getfem_mat_elem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -44,9 +44,12 @@ namespace getfem {
     bool prefer_comp_on_real_element;
     virtual bool compare(const static_stored_object_key &oo) const {
       const emelem_comp_key_ &o = dynamic_cast<const emelem_comp_key_ &>(oo);
-      if (pmt < o.pmt) return true; if (o.pmt < pmt) return false;
-      if (ppi < o.ppi) return true; if (o.ppi < ppi) return false;
-      if (pgt < o.pgt) return true; if (o.pgt < pgt) return false;
+      if (pmt < o.pmt) return true;
+      if (o.pmt < pmt) return false;
+      if (ppi < o.ppi) return true;
+      if (o.ppi < ppi) return false;
+      if (pgt < o.pgt) return true;
+      if (o.pgt < pgt) return false;
       if (prefer_comp_on_real_element < o.prefer_comp_on_real_element)
         return true;
       return false;
diff --git a/src/getfem_mat_elem_type.cc b/src/getfem_mat_elem_type.cc
index 089e568..cced331 100644
--- a/src/getfem_mat_elem_type.cc
+++ b/src/getfem_mat_elem_type.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -27,10 +27,13 @@
 namespace getfem {
 
   bool operator < (const constituant &m, const constituant &n) {
-    if (m.t < n.t) return true; if (m.t > n.t) return false;
+    if (m.t < n.t) return true;
+    if (m.t > n.t) return false;
     if (m.t == GETFEM_NONLINEAR_) {
-      if (m.nlt < n.nlt) return true; if (n.nlt < m.nlt) return false;
-      if (m.nl_part < n.nl_part) return true; if (m.nl_part > n.nl_part) return false;
+      if (m.nlt < n.nlt) return true;
+      if (n.nlt < m.nlt) return false;
+      if (m.nl_part < n.nl_part) return true;
+      if (m.nl_part > n.nl_part) return false;
     }
     if (m.pfi < n.pfi) return true;
     return false;
diff --git a/src/getfem_mesh.cc b/src/getfem_mesh.cc
index 63f9ee4..caeb31d 100644
--- a/src/getfem_mesh.cc
+++ b/src/getfem_mesh.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -90,7 +90,7 @@ namespace getfem {
                 giv.invert(pt, barycentre);
 
         
-                if (gmm::abs(pgt->convex_ref()->is_in_face(f, barycentre)) < 0.1)
+                if (gmm::abs(pgt->convex_ref()->is_in_face(f,barycentre)) < 0.001)
                   r.add(icv[jc], fsub);
               }
             }
@@ -115,7 +115,7 @@ namespace getfem {
               giv.invert(pt, barycentre);
         
               for (short_type f = 0; f < pgt->structure()->nb_faces(); ++f)
-                if (gmm::abs(pgt->convex_ref()->is_in_face(f, barycentre)) < 0.1)
+                if (gmm::abs(pgt->convex_ref()->is_in_face(f,barycentre)) < 0.001)
                   { r.add(ic, f); break; }
           }
         }
@@ -156,7 +156,7 @@ namespace getfem {
       else {
         int ne = int(nb_convex());
         std::vector<int> xadj(ne+1), adjncy, numelt(ne), npart(ne);
-        std::vector<int> indelt(convex_index().last_true()+1);
+        std::vector<int> indelt(nb_allocated_convex());
         
         double t_ref = MPI_Wtime();
 
@@ -217,10 +217,9 @@ namespace getfem {
   }
 #endif
 
-  void mesh::optimize_structure() {
+  void mesh::optimize_structure(bool with_renumbering) {
     pts.resort();
-    size_type i, j;
-    j = nb_convex();
+    size_type i, j = nb_convex(), nbc = j;
     for (i = 0; i < j; i++)
       if (!convex_tab.index_valid(i))
         swap_convex(i, convex_tab.ind_last());
@@ -231,14 +230,20 @@ namespace getfem {
         while (i < j && j != ST_NIL && !(pts.index()[j])) --j;
         if (i < j && j != ST_NIL ) swap_points(i, j);
       }
-  }
-
-  const std::vector<size_type> &mesh::cuthill_mckee_ordering() const {
-    if (!cuthill_mckee_uptodate) {
-      bgeot::cuthill_mckee_on_convexes(*this, cmk_order);
-      cuthill_mckee_uptodate = true;
+    if (with_renumbering) { // Could be optimized no using only swap_convex
+      std::vector<size_type> cmk, iord(nbc), iordinv(nbc);
+      for (i = 0; i < nbc; ++i) iord[i] = iordinv[i] = i;
+      
+      bgeot::cuthill_mckee_on_convexes(*this, cmk);
+      for (i = 0; i < nbc; ++i) {
+	j = iordinv[cmk[i]];
+	if (i != j) {
+	  swap_convex(i, j);
+	  std::swap(iord[i], iord[j]);
+	  std::swap(iordinv[iord[i]], iordinv[iord[j]]);
+	}
+      }
     }
-    return cmk_order;
   }
 
   void mesh::translation(const base_small_vector &V)
@@ -293,6 +298,12 @@ namespace getfem {
     return add_simplex(3, &(ipt[0]));
   }
 
+  size_type mesh::add_pyramid(size_type a, size_type b,
+                                  size_type c, size_type d, size_type e) {
+    size_type ipt[5]; ipt[0] = a; ipt[1] = b; ipt[2] = c; ipt[3] = d; ipt[4] = e;
+    return add_convex(bgeot::pyramidal_geotrans(1), &(ipt[0]));
+  }
+
   size_type mesh::add_tetrahedron_by_points
   (const base_node &p1, const base_node &p2,
    const base_node &p3, const base_node &p4) {
@@ -870,6 +881,28 @@ namespace getfem {
     return mrr;
   }
 
+  mesh_region select_convexes_in_box(const mesh &m, const mesh_region &mr,
+                                     const base_node &pt1, const base_node &pt2) {
+    mesh_region mrr;
+    size_type N = m.dim();
+    GMM_ASSERT1(pt1.size() == N && pt2.size() == N, "Wrong dimensions"); 
+    for (getfem::mr_visitor i(mr, m); !i.finished(); ++i)
+      if (i.f() == short_type(-1)) {
+        bgeot::mesh_structure::ind_cv_ct pt = m.ind_points_of_convex(i.cv());
+
+        bool is_in = true;
+        for (bgeot::mesh_structure::ind_cv_ct::iterator it = pt.begin();
+             it != pt.end(); ++it) {
+          for (size_type j = 0; j < N; ++j)
+            if (m.points()[*it][j] < pt1[j] || m.points()[*it][j] > pt2[j])
+              { is_in = false; break; }
+          if (!is_in) break;
+        }
+        if (is_in) mrr.add(i.cv());
+      }
+    return mrr;
+  }
+
   void extrude(const mesh& in, mesh& out, size_type nb_layers, short_type degree) {
     dim_type dim = in.dim();
     base_node pt(dim+1);
@@ -917,9 +950,12 @@ namespace bgeot {
 namespace getfem {
 
   bool mesh::edge::operator <(const edge &e) const {
-    if (i0 < e.i0) return true; if (i0 > e.i0) return false;
-    if (i1 < e.i1) return true; if (i1 > e.i1) return false;
-    if (i2 < e.i2) return true; return false;
+    if (i0 < e.i0) return true;
+    if (i0 > e.i0) return false;
+    if (i1 < e.i1) return true;
+    if (i1 > e.i1) return false;
+    if (i2 < e.i2) return true;
+    return false;
   }
 
   void mesh::Bank_sup_convex_from_green(size_type i) {
diff --git a/src/getfem_mesh_fem.cc b/src/getfem_mesh_fem.cc
index d9e8768..14bf08f 100644
--- a/src/getfem_mesh_fem.cc
+++ b/src/getfem_mesh_fem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -27,7 +27,7 @@
 
 namespace getfem {
 
-  void mesh_fem::update_from_context(void) const {
+  void mesh_fem::update_from_context() const {
     for (dal::bv_visitor i(fe_convex); !i.finished(); ++i) {
       if (linked_mesh_->convex_index().is_in(i)) {
         if (v_num_update < linked_mesh_->convex_version_number(i)) {
@@ -142,11 +142,21 @@ namespace getfem {
                   "Incompatibility between Qdim=" << int(Qdim) <<
                   " and target_dim " << int(pf->target_dim()) << " of " <<
                   name_of_fem(pf));
-      if (!fe_convex.is_in(cv) || f_elems[cv] != pf) {
-        fe_convex.add(cv);
-        f_elems[cv] = pf;
-        dof_enumeration_made = false;
+
+      
+      if (cv == f_elems.size()) {
+	f_elems.push_back(pf);
+	fe_convex.add(cv);
+	dof_enumeration_made = false;
         touch(); v_num = act_counter();
+      } else {
+	if (cv > f_elems.size()) f_elems.resize(cv+1);
+	if (!fe_convex.is_in(cv) || f_elems[cv] != pf) {
+	  fe_convex.add(cv);
+	  f_elems[cv] = pf;
+	  dof_enumeration_made = false;
+	  touch(); v_num = act_counter();
+	}
       }
     }
   }
@@ -290,22 +300,34 @@ namespace getfem {
     }
   }
 
+  bool mesh_fem::is_uniform() const {
+    context_check(); if (!dof_enumeration_made) enumerate_dof();
+    return is_uniform_;
+  }
+
+  bool mesh_fem::is_uniformly_vectorized() const {
+    context_check(); if (!dof_enumeration_made) enumerate_dof();
+    return is_uniformly_vectorized_;
+  }
+
   /// Enumeration of dofs
-  void mesh_fem::enumerate_dof(void) const {
+  void mesh_fem::enumerate_dof() const {
     bgeot::index_node_pair ipt;
+    is_uniform_ = true;
+    is_uniformly_vectorized_ = (get_qdim() > 1);
     GMM_ASSERT1(linked_mesh_ != 0, "Uninitialized mesh_fem");
     context_check();
     if (fe_convex.card() == 0)
       { dof_enumeration_made = true; nb_total_dof = 0; return; }
-
-    // Gives the Cuthill McKee ordering to iterate on elements
-    const std::vector<size_type> &cmk = linked_mesh().cuthill_mckee_ordering();
+    pfem first_pf = f_elems[fe_convex.first_true()];
+    if (first_pf && first_pf->is_on_real_element()) is_uniform_ = false;
+    if (first_pf && first_pf->target_dim() > 1) is_uniformly_vectorized_=false;
 
     // Dof counter
     size_type nbdof = 0;
 
     // Information stored per element
-    size_type nb_max_cv = linked_mesh().convex_index().last_true()+1;
+    size_type nb_max_cv = linked_mesh().nb_allocated_convex();
     std::vector<bgeot::kdtree> dof_nodes(nb_max_cv);
     std::vector<scalar_type> elt_car_sizes(nb_max_cv);
     std::vector<std::map<fem_dof, size_type, dof_comp_>> dof_sorts(nb_max_cv);
@@ -326,7 +348,8 @@ namespace getfem {
     bgeot::pgeometric_trans pgt_old = 0;
     bgeot::pgeotrans_precomp pgp = 0;
 
-    for (size_type cv : cmk) {
+    for (dal::bv_visitor cv(linked_mesh().convex_index());
+      	 !cv.finished(); ++cv) {
       if (fe_convex.is_in(cv)) {
 	gmm::copy(linked_mesh().points_of_convex(cv)[0], bmin);
 	gmm::copy(bmin, bmax);
@@ -342,10 +365,13 @@ namespace getfem {
     }
 
     dal::bit_vector cv_done;
-
-    for (size_type cv : cmk) { // Loop on elements
+    
+    for (dal::bv_visitor cv(linked_mesh().convex_index());
+	 !cv.finished(); ++cv) { // Loop on elements
       if (!fe_convex.is_in(cv)) continue;
       pfem pf = fem_of_element(cv);
+      if (pf != first_pf) is_uniform_ = false;
+      if (pf->target_dim() > 1) is_uniformly_vectorized_ = false;
       bgeot::pgeometric_trans pgt = linked_mesh().trans_of_convex(cv);
       bgeot::pstored_point_tab pspt = pf->node_tab(cv);
       if (pgt != pgt_old || pspt != pspt_old)
@@ -433,9 +459,10 @@ namespace getfem {
     set_reduction_matrices(RR, gmm::transposed(RR));
   }
 
-  void mesh_fem::clear(void) {
+  void mesh_fem::clear() {
     fe_convex.clear();
     dof_enumeration_made = false;
+    is_uniform_ = true;
     touch(); v_num = act_counter();
     dof_structure.clear();
     use_reduction = false;
@@ -446,6 +473,7 @@ namespace getfem {
   void mesh_fem::init_with_mesh(const mesh &me, dim_type Q) {
     GMM_ASSERT1(linked_mesh_ == 0, "Mesh level set already initialized");
     dof_enumeration_made = false;
+    is_uniform_ = false;
     auto_add_elt_pf = 0;
     auto_add_elt_K = dim_type(-1);
     Qdim = Q;
@@ -467,6 +495,7 @@ namespace getfem {
     E_ = mf.E_;
     dof_structure = mf.dof_structure;
     dof_enumeration_made = mf.dof_enumeration_made;
+    is_uniform_ = mf.is_uniform_;
     nb_total_dof = mf.nb_total_dof;
     auto_add_elt_pf = mf.auto_add_elt_pf;
     auto_add_elt_K = mf.auto_add_elt_K;
@@ -491,8 +520,12 @@ namespace getfem {
   mesh_fem::mesh_fem(const mesh &me, dim_type Q)
     { linked_mesh_ = 0; init_with_mesh(me, Q); }
 
-  mesh_fem::mesh_fem(void)
-    { linked_mesh_ = 0; dof_enumeration_made = false; set_qdim(1); }
+  mesh_fem::mesh_fem() {
+    linked_mesh_ = 0;
+    dof_enumeration_made = false;
+    is_uniform_ = true;
+    set_qdim(1);
+  }
 
   mesh_fem::~mesh_fem() { }
 
@@ -538,6 +571,8 @@ namespace getfem {
         } else if (bgeot::casecmp(tmp, "DOF_ENUMERATION") == 0) {
           dal::bit_vector doflst;
           dof_structure.clear(); dof_enumeration_made = false;
+	  is_uniform_ = true;
+	  size_type nbdof_unif = size_type(-1);
           touch(); v_num = act_counter();
           while (true) {
             bgeot::get_token(ist, tmp);
@@ -550,6 +585,11 @@ namespace getfem {
             std::vector<size_type> tab;
             if (convex_index().is_in(ic) && tmp.size() &&
                 isdigit(tmp[0]) && tmp2 == ":") {
+	      size_type nbd = nb_basic_dof_of_element(ic);
+	      if (nbdof_unif == size_type(-1))
+		nbdof_unif = nbd;
+	      else if (nbdof_unif != nbd)
+		is_uniform_ = false;
               tab.resize(nb_basic_dof_of_element(ic));
               for (size_type i=0; i < fem_of_element(ic)->nb_dof(ic);
                    i++) {
@@ -745,23 +785,23 @@ namespace getfem {
   }
 
   struct mf__key_ : public context_dependencies {
-    const mesh *pmesh;
+    const mesh *pmsh;
     dim_type order, qdim;
     mf__key_(const mesh &msh, dim_type o, dim_type q)
-      : pmesh(&msh), order(o), qdim(q)
+      : pmsh(&msh), order(o), qdim(q)
     { add_dependency(msh); }
     bool operator <(const mf__key_ &a) const {
-      if (pmesh < a.pmesh) return true;
-      else if (pmesh > a.pmesh) return false;
+      if (pmsh < a.pmsh) return true;
+      else if (pmsh > a.pmsh) return false;
       else if (order < a.order) return true;
       else if (order > a.order) return false;
       else if (qdim < a.qdim) return true;
       return false;
     }
-    void update_from_context(void) const {}
+    void update_from_context() const {}
     mf__key_(const mf__key_ &mfk) : context_dependencies( ) {
-      pmesh = mfk.pmesh; order = mfk.order; qdim = mfk.qdim;
-      add_dependency(*pmesh);
+      pmsh = mfk.pmsh; order = mfk.order; qdim = mfk.qdim;
+      add_dependency(*pmsh);
     }
   private :
     mf__key_& operator=(const mf__key_ &mfk);
diff --git a/src/getfem_mesh_fem_global_function.cc b/src/getfem_mesh_fem_global_function.cc
index 7133c4b..19335dd 100644
--- a/src/getfem_mesh_fem_global_function.cc
+++ b/src/getfem_mesh_fem_global_function.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
  Copyright (C) 2016      Konstantinos Poulios
 
  This file is a part of GetFEM++
diff --git a/src/getfem_mesh_fem_level_set.cc b/src/getfem_mesh_fem_level_set.cc
index e9568e9..5058ad1 100644
--- a/src/getfem_mesh_fem_level_set.cc
+++ b/src/getfem_mesh_fem_level_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem_mesh_fem_product.cc b/src/getfem_mesh_fem_product.cc
index a6ad2be..19ae7a4 100644
--- a/src/getfem_mesh_fem_product.cc
+++ b/src/getfem_mesh_fem_product.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -33,7 +33,7 @@ namespace getfem {
     cvr = pfems[0]->ref_convex(cv);
     dim_ = cvr->structure()->dim();
     is_equiv = real_element_defined = true;
-    is_polycomp = is_pol = is_lag = false;
+    is_polycomp = is_pol = is_lag = is_standard_fem = false;
     es_degree = 5; /* humm ... */
     ntarget_dim = 1;
     std::stringstream nm;
@@ -119,11 +119,8 @@ namespace getfem {
   }
   
   void fem_product::real_hess_base_value(const fem_interpolation_context &c,
-				  base_tensor &t, bool) const {
-    bgeot::multi_index mi(4);
-    mi[3] = mi[2] = short_type(c.N()); mi[1] = target_dim();
-    mi[0] = short_type(nb_dof(0));
-    t.adjust_sizes(mi);
+                                         base_tensor &t, bool) const {
+    t.adjust_sizes(nb_dof(0), target_dim(), gmm::sqr(c.N()));
     base_tensor::iterator it = t.begin();
     
     fem_interpolation_context c0 = c;
diff --git a/src/getfem_mesh_fem_sum.cc b/src/getfem_mesh_fem_sum.cc
index 90ea218..e48c691 100644
--- a/src/getfem_mesh_fem_sum.cc
+++ b/src/getfem_mesh_fem_sum.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -29,7 +29,7 @@ namespace getfem {
     dim_ = cvr->structure()->dim();
     is_equiv = !smart_global_dof_linking_;
     real_element_defined = true;
-    is_polycomp = is_pol = is_lag = false;
+    is_polycomp = is_pol = is_lag = is_standard_fem = false;
     es_degree = 5; /* humm ... */
     ntarget_dim = 1;
 
@@ -215,10 +215,7 @@ namespace getfem {
   
   void fem_sum::real_hess_base_value(const fem_interpolation_context &c,
                                      base_tensor &t, bool withM) const {
-    bgeot::multi_index mi(4);
-    mi[3] = mi[2] = short_type(c.N()); mi[1] = target_dim();
-    mi[0] = short_type(nb_dof(0));
-    t.adjust_sizes(mi);
+    t.adjust_sizes(nb_dof(0), target_dim(), gmm::sqr(c.N()));
     base_tensor::iterator it = t.begin(), itf;
     
     fem_interpolation_context c0 = c;
@@ -231,16 +228,12 @@ namespace getfem {
       c0.hess_base_value(hess_e[k]);
     }
 
-    for (dim_type j = 0; j < c.N() ; ++j) {
-      for (dim_type k = 0; k < c.N() ; ++k) {
-        for (dim_type q = 0; q < target_dim(); ++q) {
-          for (size_type f = 0; f < pfems.size(); ++f) {
-            itf = hess_e[f].begin()
-              + ((j * c.N() + k) * target_dim() + q) * pfems[f]->nb_dof(cv); 
-            for (size_type i = 0; i < pfems[f]->nb_dof(cv); ++i)
-              *it++ = *itf++;
-          }
-        }
+    dim_type NNdim = dim_type(gmm::sqr(c.N())*target_dim());
+    for (dim_type jkq = 0; jkq < NNdim ; ++jkq) {
+      for (size_type f = 0; f < pfems.size(); ++f) {
+        itf = hess_e[f].begin() + (jkq * pfems[f]->nb_dof(cv)); 
+        for (size_type i = 0; i < pfems[f]->nb_dof(cv); ++i)
+          *it++ = *itf++;
       }
     }
     assert(it == t.end());
diff --git a/src/getfem_mesh_im.cc b/src/getfem_mesh_im.cc
index 620fc6b..1e4990c 100644
--- a/src/getfem_mesh_im.cc
+++ b/src/getfem_mesh_im.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2005-2016 Yves Renard
+ Copyright (C) 2005-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem_mesh_im_level_set.cc b/src/getfem_mesh_im_level_set.cc
index c75dcbc..a030c0a 100644
--- a/src/getfem_mesh_im_level_set.cc
+++ b/src/getfem_mesh_im_level_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2005-2016 Yves Renard
+ Copyright (C) 2005-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -572,22 +572,20 @@ namespace getfem {
 
       switch (n) {
       case 2:
-	{
-	  for (short_type k = 0; k < n; ++k) {
-	    size_type ipt = msh.structure_of_convex(i)->ind_dir_points()[k];
-	    if (ptinter.is_in(ipt)) {
-	      
-	      const base_node &P = msh.points_of_convex(i)[ipt];
-	      cc.set_xref(P);
-
-	      if (global_intersection.search_point(cc.xreal())
-		  == size_type(-1)) {
-		global_intersection.add_point(cc.xreal());
-		new_approx->add_point(msh.points_of_convex(i)[ipt],
-				      scalar_type(1)); 
-	      }
-
+	for (short_type k = 0; k < n; ++k) {
+	  size_type ipt = msh.structure_of_convex(i)->ind_dir_points()[k];
+	  if (ptinter.is_in(ipt)) {
+	    
+	    const base_node &P = msh.points_of_convex(i)[ipt];
+	    cc.set_xref(P);
+	    
+	    if (global_intersection.search_point(cc.xreal())
+		== size_type(-1)) {
+	      global_intersection.add_point(cc.xreal());
+	      new_approx->add_point(msh.points_of_convex(i)[ipt],
+				    scalar_type(1)); 
 	    }
+	    
 	  }
 	}
       case 3:
diff --git a/src/getfem_mesh_level_set.cc b/src/getfem_mesh_level_set.cc
index 11ca100..0f2917f 100644
--- a/src/getfem_mesh_level_set.cc
+++ b/src/getfem_mesh_level_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2005-2016 Julien Pommier
+ Copyright (C) 2005-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -766,7 +766,7 @@ struct Chrono {
       scalar_type error = test_integration_error(new_approx, 1);
       if (noisy) cout << " max monomial integration err: " << error << "\n";
       if (error > 1e-5) {
-	if (noisy) cout << "Not Good ! Let us make a finer cut.\n"; if (noisy) getchar();
+	if (noisy) cout << "Not Good ! Let us make a finer cut.\n";
 	if (dmin > 3*h0) { dmin /= 2.; }
 	else { h0 /= 2.0; dmin = 2.*h0; }
 	h0_is_ok = false;
@@ -808,7 +808,7 @@ struct Chrono {
 	for (size_type i = 0; i < msh.nb_points(); ++i)
 	  pts[i] = m.add_point(pgt->transform(msh.points()[i], G));
 	
-	std::vector<size_type> ic2(msh.convex_index().last_true()+1);
+	std::vector<size_type> ic2(msh.nb_allocated_convex());
 
 	for (dal::bv_visitor i(msh.convex_index()); !i.finished(); ++i) {
 	  ic2[i] = m.add_convex(msh.trans_of_convex(i), 
diff --git a/src/getfem_mesh_region.cc b/src/getfem_mesh_region.cc
index 4ac0018..51ab170 100644
--- a/src/getfem_mesh_region.cc
+++ b/src/getfem_mesh_region.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2005-2016 Yves Renard
+ Copyright (C) 2005-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -81,7 +81,6 @@ namespace getfem {
       }
     }
     index_updated = false;
-    /* TODO? : verifier que la liste des convexes est bien inclue dans m.convex_index */
     return *this;
   }
 
@@ -128,6 +127,7 @@ namespace getfem {
   bool mesh_region::compare(const mesh &m1, const mesh_region &mr,
                             const mesh &m2) const {
     if (&m1 != &m2) return false;
+    if (!p.get() && !mr.p.get()) return (id_ == mr.id_);
     this->from_mesh(m1);
     mr.from_mesh(m2);
     if (this->p.get() && !(mr.p.get())) return false;
@@ -313,11 +313,29 @@ namespace getfem {
 
   bool mesh_region::is_in(size_type cv, short_type f) const 
   {
+    GMM_ASSERT1(p.get(), "Use from mesh on that region before");
     map_t::const_iterator it = rp().m.find(cv);
     if (it == rp().m.end() || short_type(f+1) >= MAX_FACES_PER_CV) return false;
     return ((*it).second)[short_type(f+1)];
   }
 
+  bool mesh_region::is_in(size_type cv, short_type f, const mesh &m) const 
+  {
+    if (p.get()) {
+      map_t::const_iterator it = rp().m.find(cv);
+      if (it == rp().m.end() || short_type(f+1) >= MAX_FACES_PER_CV)
+	return false;
+      return ((*it).second)[short_type(f+1)];
+    }
+    else
+    {
+      if (id() == size_type(-1)) return true;
+      else return m.region(id()).is_in(cv, f);
+    }
+  }
+
+  
+
   bool mesh_region::is_empty() const 
   {
     return rp().m.empty();
@@ -386,15 +404,15 @@ namespace getfem {
     for these operations as there are not intended to be manipulated
     (they only exist to provide a default argument to the mesh_region
     parameters of assembly procedures etc. */
-    GMM_ASSERT1(a.id() != all_convexes().id() ||
-      b.id() != all_convexes().id(), "the 'all_convexes' regions "
-      "are not supported for set operations");
-    if (a.id() == all_convexes().id()) 
+    GMM_ASSERT1(a.id() !=  size_type(-1)||
+		b.id() != size_type(-1), "the 'all_convexes' regions "
+		"are not supported for set operations");
+    if (a.id() == size_type(-1)) 
     {
       for (const_iterator it = b.begin();it != b.end(); ++it) r.wp().m.insert(*it);
       return r;
     }
-    else if (b.id() == all_convexes().id()) 
+    else if (b.id() == size_type(-1)) 
     {
       for (const_iterator it = a.begin();it != a.end(); ++it) r.wp().m.insert(*it);
       return r;
@@ -422,10 +440,10 @@ namespace getfem {
   mesh_region mesh_region::merge(const mesh_region &a, 
                                  const mesh_region &b) 
   {
-    GMM_TRACE4("Merger of "<<a.id()<<" and "<<b.id());
+    GMM_TRACE4("Merger of " << a.id() << " and " << b.id());
     mesh_region r;
-    GMM_ASSERT1(a.id() != all_convexes().id() &&
-      b.id() != all_convexes().id(), "the 'all_convexes' regions "
+    GMM_ASSERT1(a.id() != size_type(-1) &&
+      b.id() != size_type(-1), "the 'all_convexes' regions "
       "are not supported for set operations");
     for (const_iterator it = a.begin();it != a.end(); ++it)
     { 
@@ -444,8 +462,8 @@ namespace getfem {
   {
     GMM_TRACE4("subtraction of "<<a.id()<<" and "<<b.id());
     mesh_region r;
-    GMM_ASSERT1(a.id() != all_convexes().id() &&
-      b.id() != all_convexes().id(), "the 'all_convexes' regions "
+    GMM_ASSERT1(a.id() != size_type(-1) &&
+      b.id() != size_type(-1), "the 'all_convexes' regions "
       "are not supported for set operations");
     for (const_iterator ita = a.begin();ita != a.end(); ++ita) 
       r.wp().m.insert(*ita);
@@ -462,10 +480,16 @@ namespace getfem {
     return r;
   }
 
-  int mesh_region::region_is_faces_of(const mesh_region &rg) {
+  int mesh_region::region_is_faces_of(const getfem::mesh& m1,
+				      const mesh_region &rg2,
+				      const getfem::mesh& m2) const {
+    if (&m1 != &m2) return 0;
     int r = 1, partially = 0;
-    for (mr_visitor cv(*this); !cv.finished(); cv.next())
-      if (cv.is_face() && rg.is_in(cv.cv())) partially = -1; else r = 0;
+    for (mr_visitor cv(*this, m1); !cv.finished(); cv.next())
+      if (cv.is_face() && rg2.is_in(cv.cv(),short_type(-1), m2))
+	partially = -1;
+      else
+	r = 0;
     if (r == 1) return 1; else return partially;
   }
 
@@ -491,13 +515,82 @@ namespace getfem {
                 "of convexes or a set of faces, but not a mixed set");
   }
 
-  mesh_region::visitor::visitor(const mesh_region &s, const mesh &m) : 
+
+
+
+#if GETFEM_PARA_LEVEL > 1
+  
+  mesh_region::visitor::visitor(const mesh_region &s, const mesh &m,
+				bool intersect_with_mpi) :
     cv_(size_type(-1)), f_(short_type(-1)), finished_(false) 
   {
-    s.from_mesh(m);
-    init(s);
+    if ((me_is_multithreaded_now() && s.partitioning_allowed)) {
+      s.from_mesh(m);
+      init(s);
+    } else {
+      if (s.id() == size_type(-1)) {
+	if (intersect_with_mpi)
+	  init(m.get_mpi_region());
+	else
+	  init(m.convex_index());
+      } else if (s.p.get())  {
+	if (intersect_with_mpi)
+	  { mpi_rg = s; m.intersect_with_mpi_region(mpi_rg); init(mpi_rg); }
+	else
+	  init(s);
+      } else {
+	if (intersect_with_mpi)
+	  init(m.get_mpi_sub_region(s.id()));
+	else
+	  init(m.region(s.id()));
+      }
+    }
+  }
+
+#else
+  
+  mesh_region::visitor::visitor(const mesh_region &s, const mesh &m, bool)
+    :cv_(size_type(-1)), f_(short_type(-1)), finished_(false) 
+  {
+    if ((me_is_multithreaded_now() && s.partitioning_allowed)) {
+      s.from_mesh(m);
+      init(s);
+    } else {
+      if (s.id() == size_type(-1)) {
+	init(m.convex_index());
+      } else if (s.p.get())  {
+	init(s);
+      } else {
+	init(m.region(s.id()));
+      }
+    }
   }
 
+#endif
+
+  
+  bool mesh_region::visitor::next() 
+  {
+    if (whole_mesh) {
+      if (itb == iteb) { finished_ = true; return false; }
+      cv_ = itb.index();
+      c = 0;
+      f_ = 0;
+      ++itb; while (itb != iteb && !(*itb)) ++itb;
+      return true;
+    }
+    while (c.none()) 
+      {
+	if (it == ite) { finished_=true; return false; }
+	cv_ = it->first;
+	c   = it->second;  
+	f_ = short_type(-1);
+	++it; 
+	if (c.none()) continue;
+      }
+    next_face();
+    return true;
+  }
 
   mesh_region::visitor::visitor(const mesh_region &s) :
     cv_(size_type(-1)), f_(short_type(-1)), finished_(false) 
@@ -505,11 +598,17 @@ namespace getfem {
     init(s);
   }
 
+  void mesh_region::visitor::init(const dal::bit_vector &bv) 
+  {
+    whole_mesh = true;
+    itb = bv.begin(); iteb = bv.end();
+    while (itb != iteb && !(*itb)) ++itb;
+    next();
+  }
 
   void mesh_region::visitor::init(const mesh_region &s) 
   {
-    GMM_ASSERT1(&s != 0, "Attemps to use an invalid mesh_region "
-      "(need to call 'from_mesh')");
+    whole_mesh = false;
     it  = s.begin();
     ite = s.end();
     next();
@@ -517,17 +616,22 @@ namespace getfem {
 
   std::ostream & operator <<(std::ostream &os, const mesh_region &w) 
   {
-    if (w.id() == mesh_region::all_convexes().id())
+    if (w.id() == size_type(-1))
       os << " ALL_CONVEXES";
-    else 
+    else if (w.p.get())
+    {
       for (mr_visitor cv(w); !cv.finished(); cv.next()) 
-      {
-        os << cv.cv();
-        if (cv.is_face()) os << "/" << cv.f();
-        os << " ";
-      }
-
-      return os;
+	{
+	  os << cv.cv();
+	  if (cv.is_face()) os << "/" << cv.f();
+	  os << " ";
+	}
+    }
+    else
+    {
+      os << " region " << w.id();
+    }
+    return os;
   }
 
   struct dummy_mesh_region_ {
diff --git a/src/getfem_mesh_slice.cc b/src/getfem_mesh_slice.cc
index d9d2da4..0b6948d 100644
--- a/src/getfem_mesh_slice.cc
+++ b/src/getfem_mesh_slice.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2003-2016 Julien Pommier
+ Copyright (C) 2003-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -28,11 +28,11 @@ namespace getfem {
     o << "stored_mesh_slice, containing " << m.nb_convex() << " convexes\n";
     for (size_type ic = 0; ic < m.nb_convex(); ++ic) {
       o << "slice convex #" << ic << " (original = " << m.convex_num(ic)
-	<< ")\n";
+        << ")\n";
       for (size_type i = 0; i < m.nodes(ic).size(); ++i) {
         o << "node " << i << ": " << m.nodes(ic)[i].pt << ", ref="
-	  << m.nodes(ic)[i].pt_ref << " flist=" << m.nodes(ic)[i].faces
-	  << endl;
+          << m.nodes(ic)[i].pt_ref << " flist=" << m.nodes(ic)[i].faces
+          << endl;
       }
       for (size_type i = 0; i < m.simplexes(ic).size(); ++i) {
         o << "simplex " << i << ", inodes=";
@@ -46,7 +46,7 @@ namespace getfem {
   }
 
   void stored_mesh_slice::write_to_file(const std::string &name, 
-			       bool with_mesh) const {
+                                        bool with_mesh) const {
     std::ofstream o(name.c_str());
     GMM_ASSERT1(o, "impossible to open file '" << name << "'");
     o << "% GETFEM SLICE FILE " << '\n';
@@ -61,49 +61,48 @@ namespace getfem {
     for (unsigned i=0; i < cvlst.size(); ++i) {
       const convex_slice &cs = cvlst[i];
       os << " CONVEX " << cs.cv_num 
-	 << " " << int(cs.fcnt)
-	 << " " << int(cs.discont) << "\n"
-	 << " " << cs.nodes.size() << " " << cs.simplexes.size() << "\n";
+         << " " << int(cs.fcnt)
+         << " " << int(cs.discont) << "\n"
+         << " " << cs.nodes.size() << " " << cs.simplexes.size() << "\n";
       for (unsigned j=0; j < cs.nodes.size(); ++j) {
-	os << "\t";
-	for (unsigned k=0; k < cs.nodes[j].pt.size(); ++k) {
-	  if (k) os << " ";
-	  os << cs.nodes[j].pt[k];
-	}
-	os << ";";
-	for (unsigned k=0; k < cs.nodes[j].pt_ref.size(); ++k)
-	  os << " " << cs.nodes[j].pt_ref[k];
-	os << "; "; os << cs.nodes[j].faces.to_ulong();;
-	os << "\n";
+        os << "\t";
+        for (unsigned k=0; k < cs.nodes[j].pt.size(); ++k) {
+          if (k) os << " ";
+          os << cs.nodes[j].pt[k];
+        }
+        os << ";";
+        for (unsigned k=0; k < cs.nodes[j].pt_ref.size(); ++k)
+          os << " " << cs.nodes[j].pt_ref[k];
+        os << "; "; os << cs.nodes[j].faces.to_ulong();;
+        os << "\n";
       }
       for (unsigned j=0; j < cs.simplexes.size(); ++j) {
-	os << "\t" << cs.simplexes[j].inodes.size() << ":";
-	for (unsigned k=0; k < cs.simplexes[j].inodes.size(); ++k) {
-	  os << " " << cs.simplexes[j].inodes[k];
-	}
-	os << "\n";
+        os << "\t" << cs.simplexes[j].inodes.size() << ":";
+        for (unsigned k=0; k < cs.simplexes[j].inodes.size(); ++k) {
+          os << " " << cs.simplexes[j].inodes[k];
+        }
+        os << "\n";
       }
     }
     os << "END MESH_SLICE\n";
   }
 
   void stored_mesh_slice::read_from_file(const std::string &name,
-					 const getfem::mesh &m) {
+                                         const getfem::mesh &m) {
     std::ifstream o(name.c_str());
     GMM_ASSERT1(o, "slice file '" << name << "' does not exist");
     read_from_file(o,m);
   }
 
   void stored_mesh_slice::read_from_file(std::istream &ist,
-					 const getfem::mesh &m) {
+                                         const getfem::mesh &m) {
     if (!poriginal_mesh) {
       poriginal_mesh = &m; 
     } else GMM_ASSERT1(poriginal_mesh == &m, "wrong mesh..");
 
     dim_ = m.dim();
     cv2pos.clear(); 
-    cv2pos.resize(m.convex_index().last_true() + 1, 
-		  size_type(-1));
+    cv2pos.resize(m.nb_allocated_convex(), size_type(-1));
 
     std::string tmp;
     ist.precision(16);
@@ -117,70 +116,70 @@ namespace getfem {
     while (true) {
       ist >> std::ws; bgeot::get_token(ist, tmp);
       if (bgeot::casecmp(tmp, "END")==0) {
-	break;
+        break;
       } else if (bgeot::casecmp(tmp, "DIM")==0) {
-	int d; ist >> d;
-	dim_ = d;
+        int d; ist >> d;
+        dim_ = d;
       } else if (bgeot::casecmp(tmp, "CONVEX")==0) {
-	bgeot::get_token(ist,tmp);
-	size_type ic = atoi(tmp.c_str());
-	GMM_ASSERT1(m.convex_index().is_in(ic), "Convex " << ic <<
-		    " does not exist, are you sure "
-		    "that the mesh attached to this object is right one ?");
-	bgeot::pconvex_ref cvr = m.trans_of_convex(ic)->convex_ref();
-	unsigned fcnt, discont, nbn, nbs;
-	ist >> fcnt >> discont >> nbn >> nbs;
-	nod.resize(nbn); 
-	sim.resize(nbs);
-	for (unsigned i=0; i < nbn; ++i) {
-	  nod[i].pt.resize(dim()); 
-	  nod[i].pt_ref.resize(cvr->structure()->dim());
-	  for (unsigned j=0; j < dim(); ++j) 
-	    ist >> nod[i].pt[j];
-	  ist >> bgeot::skip(";");
-	  for (unsigned j=0; j < cvr->structure()->dim(); ++j) 
-	    ist >> nod[i].pt_ref[j];
-	  ist >> bgeot::skip(";");
-	  unsigned long ul; ist >> ul;
-	  nod[i].faces = slice_node::faces_ct(int(ul));
-	}
-	for (unsigned i=0; i < nbs; ++i) {
-	  unsigned np(0);
-	  ist >> np >> bgeot::skip(":");
-	  GMM_ASSERT1(np <= dim()+1, "invalid simplex..");
-	  sim[i].inodes.resize(np);
-	  for (unsigned j=0; j < np; ++j) 
-	    ist >> sim[i].inodes[j];
-	}
-	dal::bit_vector bv; bv.add(0, nbs);
-	set_convex(ic, cvr, nod, sim, dim_type(fcnt), bv, discont);
+        bgeot::get_token(ist,tmp);
+        size_type ic = atoi(tmp.c_str());
+        GMM_ASSERT1(m.convex_index().is_in(ic), "Convex " << ic <<
+                    " does not exist, are you sure "
+                    "that the mesh attached to this object is right one ?");
+        bgeot::pconvex_ref cvr = m.trans_of_convex(ic)->convex_ref();
+        unsigned fcnt, discont, nbn, nbs;
+        ist >> fcnt >> discont >> nbn >> nbs;
+        nod.resize(nbn); 
+        sim.resize(nbs);
+        for (unsigned i=0; i < nbn; ++i) {
+          nod[i].pt.resize(dim()); 
+          nod[i].pt_ref.resize(cvr->structure()->dim());
+          for (unsigned j=0; j < dim(); ++j) 
+            ist >> nod[i].pt[j];
+          ist >> bgeot::skip(";");
+          for (unsigned j=0; j < cvr->structure()->dim(); ++j) 
+            ist >> nod[i].pt_ref[j];
+          ist >> bgeot::skip(";");
+          unsigned long ul; ist >> ul;
+          nod[i].faces = slice_node::faces_ct(int(ul));
+        }
+        for (unsigned i=0; i < nbs; ++i) {
+          unsigned np(0);
+          ist >> np >> bgeot::skip(":");
+          GMM_ASSERT1(np <= dim()+1, "invalid simplex..");
+          sim[i].inodes.resize(np);
+          for (unsigned j=0; j < np; ++j) 
+            ist >> sim[i].inodes[j];
+        }
+        dal::bit_vector bv; bv.add(0, nbs);
+        set_convex(ic, cvr, nod, sim, dim_type(fcnt), bv, discont);
       } else if (tmp.size()) {
-	GMM_ASSERT1(false, "Unexpected token '" << tmp <<
-		    "' [pos=" << std::streamoff(ist.tellg()) << "]");
+        GMM_ASSERT1(false, "Unexpected token '" << tmp <<
+                    "' [pos=" << std::streamoff(ist.tellg()) << "]");
       } else if (ist.eof()) {
-	GMM_ASSERT1(false, "Unexpected end of stream "
-		    << "(missing BEGIN MESH_SLICE/END MESH_SLICE ?)");	
+        GMM_ASSERT1(false, "Unexpected end of stream "
+                    << "(missing BEGIN MESH_SLICE/END MESH_SLICE ?)");
       }
     }
   }
 
   void slicer_build_stored_mesh_slice::exec(mesh_slicer &ms) {
     if (!sl.poriginal_mesh) {
-      sl.poriginal_mesh = &ms.m; sl.dim_ = sl.linked_mesh().dim();
-      sl.cv2pos.clear();
-      sl.cv2pos.resize(sl.linked_mesh().convex_index().last_true() + 1,
-		       size_type(-1));
+      sl.poriginal_mesh = &ms.m;
+      sl.dim_ = sl.linked_mesh().dim();
+      sl.cv2pos.resize(sl.linked_mesh().nb_allocated_convex());
+      gmm::fill(sl.cv2pos, size_type(-1));
     } else if (sl.poriginal_mesh != &ms.m) GMM_ASSERT1(false, "wrong mesh..");
     sl.set_convex(ms.cv, ms.cvr, ms.nodes, ms.simplexes, dim_type(ms.fcnt),
-		  ms.splx_in, ms.discont);
+                  ms.splx_in, ms.discont);
   }
 
   void stored_mesh_slice::set_convex(size_type cv, bgeot::pconvex_ref cvr, 
-				     mesh_slicer::cs_nodes_ct cv_nodes, 
-				     mesh_slicer::cs_simplexes_ct cv_simplexes,
-				     dim_type fcnt,
-				     const dal::bit_vector& splx_in,
-				     bool discont) {
+                                     mesh_slicer::cs_nodes_ct cv_nodes, 
+                                     mesh_slicer::cs_simplexes_ct cv_simplexes,
+                                     dim_type fcnt,
+                                     const dal::bit_vector& splx_in,
+                                     bool discont) {
     /* push the used nodes and simplexes in the final list */
     if (splx_in.card() == 0) return;
     merged_nodes_available = false;
@@ -207,7 +206,7 @@ namespace getfem {
         size_type lnum = s.inodes[i];
         if (nused[lnum] == size_type(-1)) {
           nused[lnum] = sc->nodes.size(); sc->nodes.push_back(cv_nodes[lnum]);
-	  dim_ = std::max(int(dim_), int(cv_nodes[lnum].pt.size()));
+          dim_ = std::max(int(dim_), int(cv_nodes[lnum].pt.size()));
           points_cnt++;
         }
         s.inodes[i] = nused[lnum];
@@ -230,52 +229,52 @@ namespace getfem {
   };
 
   void stored_mesh_slice::get_edges(std::vector<size_type> &edges,
-				    dal::bit_vector &slice_edges,
-				    bool from_merged_nodes) const {
+                                    dal::bit_vector &slice_edges,
+                                    bool from_merged_nodes) const {
     if (from_merged_nodes && !merged_nodes_available) merge_nodes();
     std::set<get_edges_aux> e;
     for (cvlst_ct::const_iterator it=cvlst.begin(); it != cvlst.end(); ++it) {
       for (size_type is=0; is < it->simplexes.size(); ++is) {
-	const slice_simplex &s = it->simplexes[is];
-	for (size_type i=0; i < s.dim(); ++i) {
-	  for (size_type j=i+1; j <= s.dim(); ++j) {
-	    const slice_node& A = it->nodes[s.inodes[i]];
-	    const slice_node& B = it->nodes[s.inodes[j]];
-	    /* duplicate with slicer_build_edges_mesh which also 
-	       builds a list of edges */
-	    if ((A.faces & B.faces).count() >= unsigned(it->cv_dim-1)) {
-	      slice_node::faces_ct fmask((1 << it->cv_nbfaces)-1);
-	      fmask.flip();
-	      size_type iA, iB;
-	      iA = it->global_points_count + s.inodes[i];
-	      iB = it->global_points_count + s.inodes[j];
-	      if (from_merged_nodes) {
-		iA = to_merged_index[iA]; iB = to_merged_index[iB];
-	      }
-	      get_edges_aux a(iA,iB,((A.faces & B.faces) & fmask).any());
-	      std::set<get_edges_aux>::iterator p=e.find(a);
-	      if (p != e.end()) {
-		if (p->slice_edge && !a.slice_edge) p->slice_edge = false;
-	      } else e.insert(a);
-	    }
-	  }
-	}
+        const slice_simplex &s = it->simplexes[is];
+        for (size_type i=0; i < s.dim(); ++i) {
+          for (size_type j=i+1; j <= s.dim(); ++j) {
+            const slice_node& A = it->nodes[s.inodes[i]];
+            const slice_node& B = it->nodes[s.inodes[j]];
+            /* duplicate with slicer_build_edges_mesh which also 
+               builds a list of edges */
+            if ((A.faces & B.faces).count() >= unsigned(it->cv_dim-1)) {
+              slice_node::faces_ct fmask((1 << it->cv_nbfaces)-1);
+              fmask.flip();
+              size_type iA, iB;
+              iA = it->global_points_count + s.inodes[i];
+              iB = it->global_points_count + s.inodes[j];
+              if (from_merged_nodes) {
+                iA = to_merged_index[iA]; iB = to_merged_index[iB];
+              }
+              get_edges_aux a(iA,iB,((A.faces & B.faces) & fmask).any());
+              std::set<get_edges_aux>::iterator p=e.find(a);
+              if (p != e.end()) {
+                if (p->slice_edge && !a.slice_edge) p->slice_edge = false;
+              } else e.insert(a);
+            }
+          }
+        }
       }
     }
     slice_edges.clear(); slice_edges.sup(0, e.size());
     edges.clear(); edges.reserve(2*e.size());
     for (std::set<get_edges_aux>::const_iterator p=e.begin();
-	 p != e.end(); ++p) {
+         p != e.end(); ++p) {
       if (p->slice_edge) slice_edges.add(edges.size()/2);
       edges.push_back(p->iA);edges.push_back(p->iB);
     }
   }
 
   void stored_mesh_slice::build(const getfem::mesh& m, 
-				const slicer_action *a,
-				const slicer_action *b,
-				const slicer_action *c, 
-				size_type nrefine) {
+                                const slicer_action *a,
+                                const slicer_action *b,
+                                const slicer_action *c, 
+                                size_type nrefine) {
     clear();
     mesh_slicer slicer(m);
     slicer.push_back_action(*const_cast<slicer_action*>(a));
@@ -287,7 +286,7 @@ namespace getfem {
   }
 
   void stored_mesh_slice::replay(slicer_action *a, slicer_action *b,
-				 slicer_action *c) const {
+                                 slicer_action *c) const {
     mesh_slicer slicer(linked_mesh());
     slicer.push_back_action(*a); 
     if (b) slicer.push_back_action(*b);
@@ -299,8 +298,8 @@ namespace getfem {
     dim_ = newdim;
     for (size_type ic=0; ic < nb_convex(); ++ic) {
       for (mesh_slicer::cs_nodes_ct::iterator it=nodes(ic).begin();
-	   it != nodes(ic).end(); ++it) {
-	it->pt.resize(newdim);
+           it != nodes(ic).end(); ++it) {
+        it->pt.resize(newdim);
       }
     }
   }
@@ -311,25 +310,26 @@ namespace getfem {
     cv2pos.resize(std::max(cv2pos.size(), sl.cv2pos.size()), size_type(-1));
     for (size_type i=0; i < sl.nb_convex(); ++i) 
       GMM_ASSERT1(cv2pos[sl.convex_num(i)] == size_type(-1) ||
-		  cvlst[cv2pos[sl.convex_num(i)]].cv_dim == sl.cvlst[i].cv_num,
-		  "inconsistent dimensions for convex " << sl.cvlst[i].cv_num
-		  << " on the slices");
+                  cvlst[cv2pos[sl.convex_num(i)]].cv_dim == sl.cvlst[i].cv_num,
+                  "inconsistent dimensions for convex " << sl.cvlst[i].cv_num
+                  << " on the slices");
     for (size_type i=0; i < sl.nb_convex(); ++i) {
       size_type cv = sl.convex_num(i);
       if (cv2pos[cv] == size_type(-1)) {
-	cv2pos[cv] = cvlst.size(); cvlst.push_back(convex_slice());
+        cv2pos[cv] = cvlst.size();
+        cvlst.push_back(convex_slice());
       }
       const stored_mesh_slice::convex_slice *src = &sl.cvlst[i];
       stored_mesh_slice::convex_slice *dst = &cvlst[cv2pos[cv]];
       size_type n = dst->nodes.size();
       dst->nodes.insert(dst->nodes.end(), src->nodes.begin(),
-			src->nodes.end());
+                        src->nodes.end());
       for (mesh_slicer::cs_simplexes_ct::const_iterator
-	     it = src->simplexes.begin(); it != src->simplexes.end(); ++it) {
-	dst->simplexes.push_back(*it);
-	for (size_type j = 0; j < (*it).dim()+1; ++j)
-	  dst->simplexes.back().inodes[j] += n;	
-	simplex_cnt[dst->simplexes.back().dim()]++;
+             it = src->simplexes.begin(); it != src->simplexes.end(); ++it) {
+        dst->simplexes.push_back(*it);
+        for (size_type j = 0; j < (*it).dim()+1; ++j)
+          dst->simplexes.back().inodes[j] += n;        
+        simplex_cnt[dst->simplexes.back().dim()]++;
       }
       points_cnt += src->nodes.size();
     }
@@ -355,10 +355,10 @@ namespace getfem {
     to_merged_index.resize(nb_points());
     for (cvlst_ct::const_iterator it = cvlst.begin(); it != cvlst.end(); ++it) {
       for (size_type i=0; i < it->nodes.size(); ++i) {
-	nv[count] = &it->nodes[i];
-	to_merged_index[count++] = mp.add_point(it->nodes[i].pt);
-	// cout << "orig[" << count-1 << "] = " << nv[count-1]->pt
-	//      << ", idx=" << to_merged_index[count-1] << "\n";
+        nv[count] = &it->nodes[i];
+        to_merged_index[count++] = mp.add_point(it->nodes[i].pt);
+        // cout << "orig[" << count-1 << "] = " << nv[count-1]->pt
+        //      << ", idx=" << to_merged_index[count-1] << "\n";
       }
     }
     gmm::sorted_indexes(to_merged_index,iv);
@@ -373,8 +373,8 @@ namespace getfem {
       // cout << "i=" << i << " -> {" << merged_nodes[i].P->pt
       //      << "," << merged_nodes[i].pos << "}\n";
       if (i == nb_points()-1 ||
-	  to_merged_index[iv[i+1]] != to_merged_index[iv[i]]) 
-	merged_nodes_idx.push_back(i+1);
+          to_merged_index[iv[i+1]] != to_merged_index[iv[i]]) 
+        merged_nodes_idx.push_back(i+1);
     }
     //cout << "merged_nodes_idx = " << merged_nodes_idx << "\n";
     merged_nodes_available = true;
@@ -383,24 +383,24 @@ namespace getfem {
   size_type stored_mesh_slice::memsize() const {
     size_type sz = sizeof(stored_mesh_slice);
     for (cvlst_ct::const_iterator it = cvlst.begin();
-	 it != cvlst.end(); ++it) {
+         it != cvlst.end(); ++it) {
       sz += sizeof(size_type);
       // cerr << "memsize: convex " << it->cv_num << " nodes:" 
       //      << it->nodes.size() << ", splxs:" << it->simplexes.size()
       //      << ", sz=" << sz << "\n";
       for (size_type i=0; i < it->nodes.size(); ++i) {
-	// cerr << "  point " << i << ": size+= " << sizeof(slice_node)
-	//      << "+" << it->nodes[i].pt.memsize() << "+"
-	//      << it->nodes[i].pt_ref.memsize() << "-"
-	//      << sizeof(it->nodes[i].pt)*2 << "\n";*/
+        // cerr << "  point " << i << ": size+= " << sizeof(slice_node)
+        //      << "+" << it->nodes[i].pt.memsize() << "+"
+        //      << it->nodes[i].pt_ref.memsize() << "-"
+        //      << sizeof(it->nodes[i].pt)*2 << "\n";*/
         sz += sizeof(slice_node) + 
           (it->nodes[i].pt.memsize()+it->nodes[i].pt_ref.memsize())
-	  - sizeof(it->nodes[i].pt)*2;
+          - sizeof(it->nodes[i].pt)*2;
       }
       for (size_type i=0; i < it->simplexes.size(); ++i) {
-	// cerr << "  simplex " << i << ": size+= " << sizeof(slice_simplex)
-	//      << "+" << it->simplexes[i].inodes.size()*sizeof(size_type)
-	//      << "\n";*/
+        // cerr << "  simplex " << i << ": size+= " << sizeof(slice_simplex)
+        //      << "+" << it->simplexes[i].inodes.size()*sizeof(size_type)
+        //      << "\n";*/
         sz += sizeof(slice_simplex) + 
           it->simplexes[i].inodes.size()*sizeof(size_type);
       }
diff --git a/src/getfem_mesh_slicers.cc b/src/getfem_mesh_slicers.cc
index 0eb7f47..446008b 100644
--- a/src/getfem_mesh_slicers.cc
+++ b/src/getfem_mesh_slicers.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -479,7 +479,7 @@ namespace getfem {
       for (size_type i=0; i < s.dim(); ++i) 
         for (size_type j=0; j < s.dim(); ++j)
           M(i,j) = ms.nodes[s.inodes[i+1]].pt[j] - ms.nodes[s.inodes[0]].pt[j];
-      scalar_type v = gmm::abs(gmm::lu_det(M));
+      scalar_type v = bgeot::lu_det(&(*(M.begin())), s.dim());
       for (size_type d=2; d <= s.dim(); ++d) v /= scalar_type(d);
       a += v;
     }
@@ -642,7 +642,7 @@ namespace getfem {
         base_small_vector d = nodes[s.inodes[i]].pt - nodes[s.inodes[0]].pt;
         gmm::copy_n(d.const_begin(), N, M.begin() + (i-1)*N);
       }
-      scalar_type J = lu_det(M);
+      scalar_type J = bgeot::lu_det(&(*(M.begin())), N);
       //cout << " lu_det = " << J << "\n";        
       if (J < 0) {
         std::swap(s.inodes[1],s.inodes[0]);
@@ -655,11 +655,13 @@ namespace getfem {
     exec_(&n, 0, cvlst);
   }
 
-  void mesh_slicer::exec(const std::vector<short_type> &nrefine, const mesh_region& cvlst) {
+  void mesh_slicer::exec(const std::vector<short_type> &nrefine,
+			 const mesh_region& cvlst) {
     exec_(&nrefine[0], 1, cvlst);
   }
 
-  static bool check_orient(size_type cv, bgeot::pgeometric_trans pgt, const mesh& m) {
+  static bool check_orient(size_type cv, bgeot::pgeometric_trans pgt,
+			   const mesh& m) {
     if (pgt->dim() == m.dim() && m.dim()>=2) { /* no orient check for 
                                                   convexes of lower dim */
       base_matrix G; bgeot::vectors_to_base_matrix(G,m.points_of_convex(cv));
@@ -667,7 +669,7 @@ namespace getfem {
       base_matrix pc; pgt->poly_vector_grad(g,pc);
       base_matrix K(pgt->dim(),pgt->dim());
       gmm::mult(G,pc,K);
-      scalar_type J = gmm::lu_det(K);
+      scalar_type J = bgeot::lu_det(&(*(K.begin())), pgt->dim());
       // bgeot::geotrans_interpolation_context ctx(pgp,0,G);
       // scalar_type J = gmm::lu_det(ctx.B()); // pb car inverse K m�me
       if (J < 0) return true;
@@ -677,7 +679,8 @@ namespace getfem {
   }
 
 #if OLD_MESH_SLICER
-  void mesh_slicer::exec_(const short_type *pnrefine, int nref_stride, const mesh_region& cvlst) {
+  void mesh_slicer::exec_(const short_type *pnrefine, int nref_stride,
+			  const mesh_region& cvlst) {
     std::vector<base_node> cvm_pts;
     const bgeot::basic_mesh *cvm = 0;
     const bgeot::mesh_structure *cvms = 0;
@@ -829,16 +832,14 @@ namespace getfem {
       bool revert_orientation = check_orient(cv, pgt,m);
 
       /* update structure-dependent data */
-      
       /* TODO : fix levelset handling when slicing faces .. */
-      if (prev_cvr != cvr || nrefine != prev_nrefine || discont || prev_discont) {
+      if (prev_cvr != cvr || nrefine != prev_nrefine
+	  || discont || prev_discont) {
         if (discont) {
-          //if (prev_cv != it.cv())
           cvm = &refined_simplex_mesh_for_convex_cut_by_level_set
             (mls->mesh_of_convex(cv), unsigned(nrefine));
         } else {
-          cvm = bgeot::refined_simplex_mesh_for_convex(cvr,
-                                                       short_type(nrefine));
+          cvm = bgeot::refined_simplex_mesh_for_convex(cvr,short_type(nrefine));
         }
         cvm_pts.resize(cvm->points().card());
         std::copy(cvm->points().begin(), cvm->points().end(), cvm_pts.begin());
@@ -848,7 +849,8 @@ namespace getfem {
       }
       if (face < dim_type(-1)) {
         if (!discont) {
-          cvms = bgeot::refined_simplex_mesh_for_convex_faces(cvr, short_type(nrefine))[face].get();
+          cvms = bgeot::refined_simplex_mesh_for_convex_faces
+	    (cvr, short_type(nrefine))[face].get();
         } else {
           cvms = &refined_simplex_mesh_for_convex_faces_cut_by_level_set(face);
         }
@@ -856,8 +858,6 @@ namespace getfem {
         cvms = cvm; 
       }
 
-
-
       /* apply the initial geometric transformation */
       std::vector<size_type> ptsid(cvm_pts.size()); std::fill(ptsid.begin(), ptsid.end(), size_type(-1));
       simplexes.resize(cvms->nb_convex());
@@ -880,7 +880,6 @@ namespace getfem {
           }
           G /= scalar_type(simplexes[snum].inodes.size());
         }
-          
 
         for (std::vector<size_type>::iterator itp = 
                simplexes[snum].inodes.begin();
diff --git a/src/getfem_mesher.cc b/src/getfem_mesher.cc
index 1ba41c8..0127b2c 100644
--- a/src/getfem_mesher.cc
+++ b/src/getfem_mesher.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier, Yves Renard
+ Copyright (C) 2004-2017 Julien Pommier, Yves Renard
 
  This file is a part of GetFEM++
 
@@ -269,7 +269,7 @@ namespace getfem {
     gmm::dense_matrix<T> B(n,n), C(n,n);
     gmm::mult(gmm::transposed(M), M, B);
     R trB = gmm::mat_trace(B);
-    gmm::lu_inverse(B);
+    bgeot::lu_inverse(&(*(B.begin())), n);
     R trBinv = gmm::mat_trace(B);
     gmm::mult(B,B,C);
     gmm::mult(gmm::scaled(M, T(-2)*trB), C, G);
@@ -356,7 +356,7 @@ namespace getfem {
             bgeot::equilateral_simplex_of_reference(dim_type(N))->points());
       gmm::mult(G, bgeot::geotrans_precomp(pgt, pgt->convex_ref()->pspt(),
 					   0)->grad(0), W);
-      gmm::lu_inverse(W);
+      bgeot::lu_inverse(&(*(W.begin())), N);
       do_build_mesh(m,fixed_points);
     }
 
@@ -384,7 +384,7 @@ namespace getfem {
           }
         }
         gmm::mult(S,W,SW);
-        if (gmm::lu_det(SW) < 1E-16) cost += 1e30;
+        if (bgeot::lu_det(&(*(SW.begin())), N) < 1E-16) cost += 1e30;
         else {
           scalar_type qual = gmm::Frobenius_condition_number_sqr(SW);
           cost += qual;
@@ -458,7 +458,7 @@ namespace getfem {
             S(k,j) = X[t(j+1,i)*N+k] - X[t(0,i)*N+k];
           }
         }
-        if (gmm::lu_det(S) < 0) {
+        if (bgeot::lu_det(&(*(S.begin())), N) < 0) {
           std::swap(t(0,i), t(1,i));
           for (size_type j=0; j < N; ++j) {
             for (size_type k=0; k < N; ++k) {
@@ -466,7 +466,7 @@ namespace getfem {
             }
           }
         }
-        if (noisy > 0 && gmm::abs(lu_det(S)) < 1e-10)
+        if (noisy > 0 && gmm::abs(bgeot::lu_det(&(*(S.begin())), N)) < 1e-10)
           cout << "Element " << i << " is very bad, det = "
                << gmm::abs(lu_det(S)) << "\n";
         gmm::mult(S,W,SW);
diff --git a/src/getfem_model_solvers.cc b/src/getfem_model_solvers.cc
index 7425b13..dae6bf5 100644
--- a/src/getfem_model_solvers.cc
+++ b/src/getfem_model_solvers.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard
+ Copyright (C) 2009-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem_models.cc b/src/getfem_models.cc
index 991b022..0aad4e0 100644
--- a/src/getfem_models.cc
+++ b/src/getfem_models.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard
+ Copyright (C) 2009-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -243,7 +243,27 @@ namespace getfem {
     return it;
   }
 
+  std::string sup_previous_and_dot_to_varname(std::string v) {
+    if (!(v.compare(0, 8, "Previous")) && (v[8] == '_' || v[9] == '_')) {
+      v = v.substr((v[8] == '_') ? 9 : 10);
+    }
+    if (!(v.compare(0, 3, "Dot")) && (v[3] == '_' || v[4] == '_')) {
+      v = v.substr((v[3] == '_') ? 4 : 5);
+    }
+    if (is_old(v)) v = no_old_prefix_name(v);
+    return v;
+  }
+
+  bool is_old(const std::string &name){
+    return name.substr(0, PREFIX_OLD_LENGTH) == PREFIX_OLD;
+  }
+
+  std::string no_old_prefix_name(const std::string &name){
+    return is_old(name) ? name.substr(PREFIX_OLD_LENGTH) : name;
+  }
+
   bool model::is_disabled_variable(const std::string &name) const {
+    if (is_old(name)) return false;
     VAR_SET::const_iterator it = find_variable(name);
     if (!(it->second.is_variable)) return false;
     if (it->second.is_affine_dependent)
@@ -252,6 +272,7 @@ namespace getfem {
   }
 
   bool model::is_data(const std::string &name) const {
+    if (is_old(name)) return true;
     VAR_SET::const_iterator it = find_variable(name);
     if (it->second.is_affine_dependent)
       it = variables.find(it->second.org_name);
@@ -259,11 +280,13 @@ namespace getfem {
   }
 
   bool model::is_true_data(const std::string &name) const {
+    if (is_old(name)) return true;
     VAR_SET::const_iterator it = find_variable(name);
     return (!(it->second.is_variable));
   }
 
   bool model::is_affine_dependent_variable(const std::string &name) const {
+    if (is_old(name)) return false;
     VAR_SET::const_iterator it = find_variable(name);
     return (it->second.is_affine_dependent);
   }
@@ -287,25 +310,26 @@ namespace getfem {
     GMM_ASSERT1(it != variables.end(), "Undefined variable " << name);
     if (it->second.alpha != a) {
       it->second.alpha = a;
-      it->second.v_num_data = act_counter();
+      for (auto &v_num : it->second.v_num_data) v_num = act_counter();
     }
   }
 
   bool model::is_im_data(const std::string &name) const {
-    VAR_SET::const_iterator it = find_variable(name);
+    auto it = find_variable(no_old_prefix_name(name));
     return (it->second.pim_data != 0);
   }
 
   const im_data *
   model::pim_data_of_variable(const std::string &name) const {
-    VAR_SET::const_iterator it = find_variable(name);
+    auto it = find_variable(no_old_prefix_name(name));
     return it->second.pim_data;
   }
 
   const gmm::uint64_type &
-  model::version_number_of_data_variable(const std::string &name) const {
+  model::version_number_of_data_variable(const std::string &name, size_type niter) const {
     VAR_SET::const_iterator it = find_variable(name);
-    return it->second.v_num_data;
+    if (niter == size_type(-1)) niter = it->second.default_iter;
+    return it->second.v_num_data[niter];
   }
 
   size_type model::nb_dof() const {
@@ -946,6 +970,10 @@ namespace getfem {
     if (!act_size_to_be_done) resize_global_system();
   }
 
+  bool model::variable_exists(const std::string &name) const {
+    return variables.count(no_old_prefix_name(name)) > 0;
+  }
+
   void model::add_macro(const std::string &name, const std::string &expr)
   { check_name_validity(name); macros[name] = expr; }
 
@@ -987,12 +1015,6 @@ namespace getfem {
        is_coercive_ = is_coercive_ &&  bricks[ibb].pbr->is_coercive();
      }
 
-     Neumann_SET::iterator it = Neumann_term_list.begin(), it2 = it;
-     for (; it != Neumann_term_list.end(); it = it2) {
-       it2++;
-       if (it->first.second == ib) Neumann_term_list.erase(it);
-     }
-
      bricks[ib] = brick_description();
   }
 
@@ -1037,13 +1059,6 @@ namespace getfem {
 
     if (it->second.pim_data != 0) sup_dependency(*(it->second.pim_data));
 
-    Neumann_SET::iterator itn = Neumann_term_list.begin(), itn2 = itn;
-    for (; itn != Neumann_term_list.end(); itn = itn2) {
-      itn2++;
-      if (!(varname.compare(itn->first.first))) Neumann_term_list.erase(itn);
-    }
-    Neumann_terms_auxilliary_variables.erase(varname);
-
     variables.erase(varname);
     act_size_to_be_done = true;
   }
@@ -1807,14 +1822,33 @@ namespace getfem {
       GMM_ASSERT1(!me_is_multithreaded_now(),
                   "List accumulation should not run in parallel");
 
-      for(size_type thread = 1; thread < num_threads(); thread++)
+      using namespace std;
+      auto to_add = vector<CONTAINER_LIST*>{};
+      to_add.push_back(&original_list);
+      for (size_type thread = 1; thread < num_threads(); ++thread)
+        to_add.push_back(&distributed_list(thread));
+
+      //List accumulation in parallel.
+      //Adding, for instance, elements 1 to 0, 2 to 3, 5 to 4 and 7 to 6
+      //on separate 4 threads in case of parallelization of the assembly
+      //on 8 threads.
+      while (to_add.size() > 1)
       {
-        auto it_original=original_list.begin();
-        auto it_distributed = distributed_list(thread).begin();
-        for(; it_original != original_list.end(); ++it_original, ++it_distributed)
-                gmm::add(*it_distributed, *it_original);
+        #pragma omp parallel default(shared)
+        {
+          auto i = this_thread() * 2;
+          if (i + 1 < to_add.size()){
+            auto &target = *to_add[i];
+            auto &source = *to_add[i + 1];
+            for (size_type j = 0; j < source.size(); ++j) gmm::add(source[j], target[j]);
+          }
+        }
+        //erase every second item , as it was already added
+        for (auto it = begin(to_add); it < end(to_add);){
+          if (next(it) < end(to_add)) it = to_add.erase(next(it));
         }
       }
+    }
   };
 
   void model::brick_call(size_type ib, build_version version,
@@ -2011,16 +2045,17 @@ namespace getfem {
         else
           gmm::copy(it->second.real_value[i-1],
                     it->second.real_value[i]);
+        it->second.v_num_data[i] = act_counter();
       }
-      if (it->second.n_iter > 1) it->second.v_num_data = act_counter();
     }
   }
 
   bool model::is_var_newer_than_brick(const std::string &varname,
-                                      size_type ib) const {
+                                      size_type ib, size_type niter) const {
     const brick_description &brick = bricks[ib];
     var_description &vd = variables[varname];
-    return (vd.v_num > brick.v_num || vd.v_num_data > brick.v_num);
+    if (niter == size_type(-1)) niter = vd.default_iter;
+    return (vd.v_num > brick.v_num || vd.v_num_data[niter] > brick.v_num);
   }
 
   bool model::is_var_mf_newer_than_brick(const std::string &varname,
@@ -2061,119 +2096,16 @@ namespace getfem {
     variable_groups[group_name] = nl;
   }
 
-
-
-
-
-  void model::auxilliary_variables_of_Neumann_terms
-  (const std::string &varname, std::vector<std::string> &aux_vars) const {
-    std::map<std::string, std::vector<std::string> >::const_iterator
-      it = Neumann_terms_auxilliary_variables.find(varname);
-    if (it !=  Neumann_terms_auxilliary_variables.end())
-      aux_vars = it->second;
-    else
-      aux_vars.resize(0);
-  }
-
-  /* Pb on this function: depend only on the variable and not on the term
-     and brick. Not well managed at brick deletion.
-  */
-  void model::add_auxilliary_variables_of_Neumann_terms
-  (const std::string &varname,
-   const std::vector<std::string> &aux_vars) const {
-
-    for (size_type i = 0; i < aux_vars.size(); ++i) {
-      bool found = false;
-      for (size_type j = 0;
-           j < Neumann_terms_auxilliary_variables[varname].size(); ++j)
-        if (!(Neumann_terms_auxilliary_variables[varname][j].compare
-              (aux_vars[i])))
-          found = true;
-      if (!found)
-        Neumann_terms_auxilliary_variables[varname].push_back(aux_vars[i]);
-    }
-  }
-
-  void model::add_auxilliary_variables_of_Neumann_terms
-  (const std::string &varname, const std::string &aux_var) const {
-    std::vector<std::string> aux_vars(1,  aux_var);
-    add_auxilliary_variables_of_Neumann_terms(varname, aux_vars);
-  }
-
-  size_type
-  model::check_Neumann_terms_consistency(const std::string &varname) const {
-
-    dal::bit_vector bnum;
-    Neumann_SET::const_iterator it = Neumann_term_list.begin();
-    for (; it != Neumann_term_list.end(); ++it) bnum.add(it->first.second);
-
-    for (dal::bv_visitor ib(active_bricks); !ib.finished(); ++ib) {
-      if (bricks[ib].pbr->has_Neumann_term() && !(bnum.is_in(ib))) {
-        for (size_type j = 0; j < bricks[ib].vlist.size(); ++j)
-          if (!(bricks[ib].vlist[j].compare(varname))) return ib;
-      }
-    }
-    return size_type(-1);
-
-  }
-
-  bool model::check_Neumann_terms_linearity(const std::string &varname) const {
-
-    Neumann_SET::const_iterator it
-      = Neumann_term_list.lower_bound(Neumann_pair(varname, 0));
-
-    while (it != Neumann_term_list.end()
-           && !(it->first.first.compare(varname))) {
-      if (!(bricks[it->first.second].pbr->is_linear())) return false;
-    }
-    return true;
-  }
-
-
-  void model::compute_Neumann_terms(int version, const std::string &varname,
-                                    const mesh_fem &mfvar,
-                                    const model_real_plain_vector &var,
-                                    fem_interpolation_context &ctx,
-                                    base_small_vector &n,
-                                    bgeot::base_tensor &t) const {
-
-    // The output tensor has to have the right size. No verification.
-    Neumann_SET::const_iterator it
-      = Neumann_term_list.lower_bound(Neumann_pair(varname, 0));
-
-    gmm::clear(t.as_vector());
-    while (it != Neumann_term_list.end()
-           && !(it->first.first.compare(varname))) {
-      if (active_bricks.is_in(it->first.second))
-        it->second->compute_Neumann_term(version, mfvar, var, ctx, n, t);
-      ++it;
-    }
-  }
-
-  void model::compute_auxilliary_Neumann_terms
-  (int version, const std::string &varname,
-   const mesh_fem &mfvar, const model_real_plain_vector &var,
-   const std::string &aux_varname,
-   fem_interpolation_context &ctx, base_small_vector &n,
-   bgeot::base_tensor &t) const {
-
-    // The output tensor has to have the right size. No verification.
-    Neumann_SET::const_iterator it
-      = Neumann_term_list.lower_bound(Neumann_pair(varname, 0));
-
-    gmm::clear(t.as_vector());
-    while (it != Neumann_term_list.end()
-           && !(it->first.first.compare(varname))) {
-      if (active_bricks.is_in(it->first.second)) {
-        size_type ind = size_type(-1);
-        for (size_type i = 0; i < it->second->auxilliary_variables.size(); ++i)
-          if (!(aux_varname.compare(it->second->auxilliary_variables[i])))
-            ind = i;
-        if (ind != size_type(-1))
-          it->second->compute_Neumann_term(version,mfvar,var,ctx,n,t,ind+1);
-      }
-      ++it;
-    }
+  void model::add_assembly_assignments(const std::string &varname,
+				       const std::string &expr, size_type rg,
+				       size_type order, bool before) {
+    GMM_ASSERT1(order < 3 || order == size_type(-1), "Bad order value");
+    const im_data *imd = pim_data_of_variable(varname);
+    GMM_ASSERT1(imd != 0, "Only applicable to im_data");
+    assignement_desc as;
+    as.varname = varname; as.expr = expr; as.region = rg; as.order = order;
+    as.before = before;
+    assignments.push_back(as);
   }
 
   void model::add_temporaries(const varnamelist &vl,
@@ -2195,7 +2127,7 @@ namespace getfem {
       if (vd.v_num_var_iter[ind] == id_num) break;
     }
     if (ind <  vd.n_iter + vd.n_temp_iter) {
-      if (vd.v_num_iter[ind] <= vd.v_num_data) {
+      if (vd.v_num_iter[ind] <= vd.v_num_data[vd.default_iter]) {
         vd.v_num_iter[ind] = act_counter();
         return false;
       }
@@ -2255,7 +2187,7 @@ namespace getfem {
     // check data list to test if a vector value of a data has changed.
     for (size_type i = 0; i < brick.dlist.size() && !tobecomputed; ++i) {
       var_description &vd = variables[brick.dlist[i]];
-      if (vd.v_num > brick.v_num || vd.v_num_data > brick.v_num) {
+      if (vd.v_num > brick.v_num || vd.v_num_data[vd.default_iter] > brick.v_num) {
         tobecomputed = true;
         version = build_version(version | BUILD_ON_DATA_CHANGE);
       }
@@ -2384,8 +2316,11 @@ namespace getfem {
                     it->second.affine_real_value, it->second.real_value[0]);
          }
         it->second.v_num = std::max(it->second.v_num, it2->second.v_num);
-        it->second.v_num_data = std::max(it->second.v_num_data,
-                                         it2->second.v_num_data);
+        for (size_type i = 0; i < it->second.n_iter; ++i)
+        {
+          it->second.v_num_data[i] = std::max(it->second.v_num_data[i],
+                                              it2->second.v_num_data[i]);
+        }
       }
   }
 
@@ -2398,7 +2333,6 @@ namespace getfem {
     GMM_ASSERT1(mf, "Works only with fem variables.");
     mesh &m = const_cast<mesh &>(mf->linked_mesh());
     mesh_im dummy_mim(m);
-    mesh_region rg = mesh_region(m, region);
 
     for (dal::bv_visitor ib(active_bricks); !ib.finished(); ++ib) {
       brick_description &brick = bricks[ib];
@@ -2409,12 +2343,15 @@ namespace getfem {
           { detected = true; break; }
 
       if (detected) {
-        int ifo = rg.region_is_faces_of(mesh_region(m, brick.region));
+	int ifo = -1;
+	for (auto &pmim :  brick.mims)
+	  ifo = std::max(ifo, mf->linked_mesh().region(region)
+			 .region_is_faces_of(m, brick.region,
+					     pmim->linked_mesh()));
         GMM_ASSERT1(ifo >= 0, "The given region is only partially covered by "
                     "region of brick " << brick.pbr->brick_name()
                     << ". Please subdivise the region");
         if (ifo == 1) {
-        
           std::string expr = brick.pbr->declare_volume_assembly_string
             (*this, ib, brick.vlist, brick.dlist);
 
@@ -2763,8 +2700,12 @@ namespace getfem {
 
             ga_workspace workspace(*this);
 
+	    for (const auto &ad : assignments)
+	      workspace.add_assignment_expression
+		(ad.varname, ad.expr, ad.region, ad.order, ad.before);
+
             for (const auto &ge : generic_expressions)
-              workspace.add_expression(ge.expr, ge.mim, ge.region);
+	      workspace.add_expression(ge.expr, ge.mim, ge.region);
 
             if (version & BUILD_RHS) {
               if (is_complex()) {
@@ -2936,19 +2877,19 @@ namespace getfem {
 
   const mesh_fem &
   model::mesh_fem_of_variable(const std::string &name) const {
-    VAR_SET::const_iterator it = find_variable(name);
+    auto it = find_variable(no_old_prefix_name(name));
     return it->second.associated_mf();
   }
 
   const mesh_fem *
   model::pmesh_fem_of_variable(const std::string &name) const {
-    VAR_SET::const_iterator it = find_variable(name);
+    auto it = find_variable(no_old_prefix_name(name));
     return it->second.passociated_mf();
   }
 
   bgeot::multi_index
   model::qdims_of_variable(const std::string &name) const {
-    VAR_SET::const_iterator it = find_variable(name);
+    auto it = find_variable(no_old_prefix_name(name));
     const mesh_fem *mf = it->second.passociated_mf();
     const im_data *imd = it->second.pim_data;
     size_type n = it->second.qdim();
@@ -2978,7 +2919,7 @@ namespace getfem {
   }
 
   size_type model::qdim_of_variable(const std::string &name) const {
-    VAR_SET::const_iterator it = find_variable(name);
+    auto it = find_variable(no_old_prefix_name(name));
     const mesh_fem *mf = it->second.passociated_mf();
     const im_data *imd = it->second.pim_data;
     size_type n = it->second.qdim();
@@ -2990,7 +2931,7 @@ namespace getfem {
     return n;
   }
 
-  
+
   const gmm::sub_interval &
   model::interval_of_variable(const std::string &name) const {
     context_check();
@@ -3000,10 +2941,18 @@ namespace getfem {
   }
 
   const model_real_plain_vector &
+  model::real_variable(const std::string &name) const {
+    if (is_old(name)) return real_variable(no_old_prefix_name(name), 1);
+    else return real_variable(name, size_type(-1));
+  }
+
+  const model_real_plain_vector &
   model::real_variable(const std::string &name, size_type niter) const {
     GMM_ASSERT1(!complex_version, "This model is a complex one");
+    GMM_ASSERT1(!is_old(name), "Please don't use Old_ prefix in combination with"
+                               " variable version");
     context_check();
-    VAR_SET::iterator it = variables.find(name);
+    auto it = variables.find(name);
     GMM_ASSERT1(it!=variables.end(), "Undefined variable " << name);
     if (act_size_to_be_done && it->second.is_fem_dofs) {
       if (it->second.filter != VDESCRFILTER_NO)
@@ -3013,16 +2962,23 @@ namespace getfem {
     }
     if (niter == size_type(-1)) niter = it->second.default_iter;
     GMM_ASSERT1(it->second.n_iter + it->second.n_temp_iter > niter,
-                "Invalid iteration number "
-                << niter << " for " << name);
+                "Invalid iteration number " << niter << " for " << name);
     return it->second.real_value[niter];
   }
 
   const model_complex_plain_vector &
+  model::complex_variable(const std::string &name) const {
+    if (is_old(name)) return complex_variable(no_old_prefix_name(name), 1);
+    else return complex_variable(name, size_type(-1));
+  }
+
+  const model_complex_plain_vector &
   model::complex_variable(const std::string &name, size_type niter) const {
     GMM_ASSERT1(complex_version, "This model is a real one");
+    GMM_ASSERT1(!is_old(name), "Please don't use Old_ prefix in combination with"
+                               " variable version");
     context_check();
-    VAR_SET::iterator it = variables.find(name);
+    auto it = variables.find(name);
     GMM_ASSERT1(it!=variables.end(), "Undefined variable " << name);
     if (act_size_to_be_done && it->second.is_fem_dofs) {
       if (it->second.filter != VDESCRFILTER_NO)
@@ -3038,10 +2994,19 @@ namespace getfem {
   }
 
   model_real_plain_vector &
+  model::set_real_variable(const std::string &name) const {
+    if (is_old(name)) return set_real_variable(no_old_prefix_name(name), 1);
+    else return set_real_variable(name, size_type(-1));
+  }
+
+
+  model_real_plain_vector &
   model::set_real_variable(const std::string &name, size_type niter) const {
     GMM_ASSERT1(!complex_version, "This model is a complex one");
+    GMM_ASSERT1(!is_old(name), "Please don't use Old_ prefix in combination with"
+                               " variable version");
     context_check();
-    VAR_SET::iterator it = variables.find(name);
+    auto it = variables.find(name);
     GMM_ASSERT1(it!=variables.end(), "Undefined variable " << name);
     if (act_size_to_be_done && it->second.is_fem_dofs) {
       if (it->second.filter != VDESCRFILTER_NO)
@@ -3049,19 +3014,27 @@ namespace getfem {
       else
         it->second.set_size();
     }
-    it->second.v_num_data = act_counter();
     if (niter == size_type(-1)) niter = it->second.default_iter;
+    it->second.v_num_data[niter] = act_counter();
     GMM_ASSERT1(it->second.n_iter + it->second.n_temp_iter > niter,
                 "Invalid iteration number "
                 << niter << " for " << name);
     return it->second.real_value[niter];
   }
 
+model_complex_plain_vector &
+  model::set_complex_variable(const std::string &name) const {
+    if (is_old(name)) return set_complex_variable(no_old_prefix_name(name), 1);
+    else return set_complex_variable(name, size_type(-1));
+  }
+
   model_complex_plain_vector &
   model::set_complex_variable(const std::string &name, size_type niter) const {
     GMM_ASSERT1(complex_version, "This model is a real one");
+    GMM_ASSERT1(!is_old(name), "Please don't use Old_ prefix in combination with"
+                               " variable version");
     context_check();
-    VAR_SET::iterator it = variables.find(name);
+    auto it = variables.find(name);
     GMM_ASSERT1(it!=variables.end(), "Undefined variable " << name);
     if (act_size_to_be_done && it->second.is_fem_dofs) {
       if (it->second.filter != VDESCRFILTER_NO)
@@ -3069,8 +3042,8 @@ namespace getfem {
       else
         it->second.set_size();
     }
-    it->second.v_num_data = act_counter();
     if (niter == size_type(-1)) niter = it->second.default_iter;
+    it->second.v_num_data[niter] = act_counter();
     GMM_ASSERT1(it->second.n_iter + it->second.n_temp_iter > niter,
                 "Invalid iteration number "
                 << niter << " for " << name);
@@ -3091,7 +3064,7 @@ namespace getfem {
       else
         it->second.set_size();
     }
-    it->second.v_num_data = act_counter();
+    for (auto &v_num : it->second.v_num_data) v_num = act_counter();
     return it->second.affine_real_value;
   }
 
@@ -3107,7 +3080,7 @@ namespace getfem {
       else
         it->second.set_size();
     }
-    it->second.v_num_data = act_counter();
+    for (auto &v_num : it->second.v_num_data) v_num = act_counter();
     return it->second.affine_complex_value;
   }
 
@@ -3125,7 +3098,6 @@ namespace getfem {
     variables.clear();
     active_bricks.clear();
     valid_bricks.clear();
-    Neumann_term_list.clear();
     real_dof_constraints.clear();
     complex_dof_constraints.clear();
     bricks.resize(0);
@@ -3386,7 +3358,7 @@ namespace getfem {
       set_flags(brickname, true /* is linear*/,
                 true /* is symmetric */, true /* is coercive */,
                 true /* is real */, false /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
       directvarname = directvarname_; directdataname = directdataname_;
     }
 
@@ -3655,196 +3627,6 @@ namespace getfem {
   //
   // ----------------------------------------------------------------------
 
-  // Deprecated
-  struct generic_elliptic_Neumann_elem_term : public Neumann_elem_term {
-
-    const mesh_fem *mf_a;
-    const model_real_plain_vector *A;
-
-    mutable fem_interpolation_context ctx_a;
-    mutable base_vector coeff, val;
-    mutable base_matrix grad, G;
-
-    void compute_Neumann_term
-    (int version, const mesh_fem &mfvar, const model_real_plain_vector &var,
-     fem_interpolation_context& ctx, base_small_vector &n,
-     base_tensor &output, size_type /*auxilliary_ind*/ = 0) const {
-
-      if (version == 3) return;  // No contribution because the term is linear
-
-      const mesh &m = mfvar.linked_mesh();
-      size_type N = m.dim(), Q = mfvar.get_qdim(), s = 1, cv=ctx.convex_num();
-
-      if (A) {
-        s = gmm::vect_size(*A);
-        if (mf_a) s = s * mf_a->get_qdim() / mf_a->nb_dof();
-      }
-      gmm::resize(val, s);
-
-      if (mf_a) {
-        GMM_ASSERT1(!(mf_a->is_reduced()),
-                    "Sorry, to be adapted for reduced mesh fems");
-
-        if (!(ctx_a.have_pf()) || ctx_a.convex_num() != cv
-            || (ctx_a.have_pfp() != ctx.have_pfp())
-            || (ctx_a.have_pfp()
-                && (ctx.pfp()->get_ppoint_tab()
-                    != ctx_a.pfp()->get_ppoint_tab()))) {
-
-          bgeot::vectors_to_base_matrix
-            (G, mf_a->linked_mesh().points_of_convex(cv));
-
-          pfem_precomp pfp = fem_precomp(mf_a->fem_of_element(cv),
-                                         ctx.pfp()->get_ppoint_tab(), 0);
-
-          if (ctx.have_pfp())
-            ctx_a = fem_interpolation_context
-              (mf_a->linked_mesh().trans_of_convex(cv), pfp, ctx.ii(),
-               G, cv, ctx.face_num());
-          else
-            ctx_a = fem_interpolation_context
-              (mf_a->linked_mesh().trans_of_convex(cv),
-               mf_a->fem_of_element(cv), ctx.xref(), G, cv, ctx.face_num());
-
-        } else {
-          if (ctx.have_pfp())  ctx_a.set_ii(ctx.ii());
-          else ctx_a.set_xref(ctx.xref());
-        }
-
-        slice_vector_on_basic_dof_of_element(*mf_a, *A, cv, coeff);
-        // coeff.resize(mf_a->nb_basic_dof_of_element(cv));
-        // gmm::copy(gmm::sub_vector(*A, gmm::sub_index
-        //                      (mfvar.ind_basic_dof_of_element(cv))), coeff);
-        ctx_a.pf()->interpolation(ctx_a, coeff, val, dim_type(s));
-      } else if (A) {
-        gmm::copy(*A, val);
-      } else {
-        val[0] = scalar_type(1);
-      }
-
-      switch (version) {
-      case 1:
-        gmm::resize(grad, Q, N);
-        slice_vector_on_basic_dof_of_element(mfvar, var, cv, coeff);
-        // coeff.resize(mfvar.nb_basic_dof_of_element(cv));
-        // gmm::copy(gmm::sub_vector(var, gmm::sub_index
-        //                      (mfvar.ind_basic_dof_of_element(cv))), coeff);
-        ctx.pf()->interpolation_grad(ctx, coeff, grad, dim_type(Q));
-
-        if (s == 1)
-          gmm::mult_add(grad, gmm::scaled(n, val[0]), output.as_vector());
-        else if (s == N*N) {
-          base_vector::const_iterator it = val.begin();
-          for (size_type j = 0; j < N; ++j)
-            for (size_type i = 0; i < N; ++i, ++it)
-              for (size_type k = 0; k < Q; ++k)
-                output[k] += (*it)*grad(k,j)*n[i];
-        }
-        else if (s == N*N*Q*Q) {
-          base_vector::const_iterator it = val.begin();
-          for (size_type l = 0; l < N; ++l)
-            for (size_type k = 0; k < Q; ++k)
-              for (size_type j = 0; j < N; ++j)
-                for (size_type i = 0; i < Q; ++i, ++it)
-                  output[i] += (*it) * grad(k, l) * n[j];
-        }
-        break;
-      case 2:
-        {
-          base_tensor t;
-          dim_type tdim = ctx.pf()->target_dim(), qmult = dim_type(Q) / tdim;
-          size_type ndof = ctx.pf()->nb_dof(cv);
-          // The return tensor is t(i,j,k) with 0<=i<ndof, 0<=j<target_dim,
-          // 0<=k<dim. In order to iterate on the tensor values, i should
-          // increment the faster, then j, then k.
-          // If target_dim == qdim, grad(phi_i)(j,k) = t(i,j,k)
-          // If target_dim == 1, grad(phi_i * e_l)(l,k) = t(i,1,k)
-          // General case, psi_{i*qmult+l} = phi_i * e_l  and
-          //    grad(psi_{i*qmult+l})(j+tdim*l,k) = t(i,j,k)
-          ctx.pf()->real_grad_base_value(ctx, t);
-
-          if (s == 1) {
-//            for (size_type l = 0; l < qmult; ++l) {
-//              for (size_type p = 0; p < Q; ++p) {
-//                base_tensor::const_iterator it = t.begin();
-//                for (size_type k = 0; k < Q; ++k)
-//                  for (size_type j = 0; j < tdim; ++j)
-//                    for (size_type i = 0; i < ndof; ++i, ++it) {
-//                      size_type jj = j + tdim*l;
-//                      if (p == jj) output(i*qmult+l, p) += val[0]*(*it)*n[k];
-//                    }
-//                GMM_ASSERT1(it ==  t.end(), "Internal error");
-//              }
-//            }
-            if (Q == 1) {
-              base_tensor::const_iterator it = t.begin();
-              for (size_type k = 0; k < N; ++k)
-                for (size_type i = 0; i < ndof; ++i, ++it)
-                  output[i] += val[0]*(*it)*n[k];
-              GMM_ASSERT1(it ==  t.end(), "Internal error");
-            } else {
-              for (size_type l = 0; l < qmult; ++l) {
-                base_tensor::const_iterator it = t.begin();
-                for (size_type k = 0; k < N; ++k)
-                  for (size_type j = 0; j < tdim; ++j)
-                    for (size_type i = 0; i < ndof; ++i, ++it) {
-                      size_type jj = j + tdim*l;
-                      output(i*qmult+l, jj) += val[0]*(*it)*n[k];
-                    }
-                GMM_ASSERT1(it ==  t.end(), "Internal error");
-              }
-            }
-          } else if (s == N*N) {
-            if (Q == 1) {
-              base_tensor::const_iterator it = t.begin();
-              for (size_type k = 0; k < N; ++k)
-                for (size_type i = 0; i < ndof; ++i, ++it) {
-                  for (size_type q = 0; q < N; ++q)
-                    output[i] += val[q+k*N]*(*it)*n[q];
-                }
-              GMM_ASSERT1(it ==  t.end(), "Internal error");
-            } else {
-              for (size_type l = 0; l < qmult; ++l) {
-                base_tensor::const_iterator it = t.begin();
-                for (size_type k = 0; k < N; ++k)
-                  for (size_type j = 0; j < tdim; ++j)
-                    for (size_type i = 0; i < ndof; ++i, ++it) {
-                      size_type jj = j + tdim*l;
-                      for (size_type q = 0; q < N; ++q)
-                        output(i*qmult+l, jj) += val[q+k*N]*(*it)*n[q];
-                    }
-                GMM_ASSERT1(it ==  t.end(), "Internal error");
-              }
-            }
-          } else if (s == N*N*Q*Q) {
-            for (size_type l = 0; l < qmult; ++l) {
-              for (size_type p = 0; p < Q; ++p) {
-                base_tensor::const_iterator it = t.begin();
-                for (size_type k = 0; k < N; ++k)
-                  for (size_type j = 0; j < tdim; ++j)
-                    for (size_type i = 0; i < ndof; ++i, ++it) {
-                      size_type jj = j + tdim*l;
-                      for (size_type q = 0; q < N; ++q)
-                        output(i*qmult+l, p)
-                          += val[p+q*Q+jj*N*Q+k*N*Q*Q]*(*it)*n[q];
-                    }
-                GMM_ASSERT1(it ==  t.end(), "Internal error");
-              }
-            }
-          }
-        }
-        break;
-      }
-    }
-
-    generic_elliptic_Neumann_elem_term
-    (const mesh_fem *mf_a_, const model_real_plain_vector *A_)
-      : mf_a(mf_a_), A(A_) {}
-
-  };
-
-
-
   // Kept only for the complex version
   struct generic_elliptic_brick : public virtual_brick {
 
@@ -3927,8 +3709,8 @@ namespace getfem {
 
     }
 
-    virtual void real_post_assembly_in_serial(const model &md, size_type ib,
-                                              const model::varnamelist &vl,
+    virtual void real_post_assembly_in_serial(const model &md, size_type,
+                                              const model::varnamelist &,
                                               const model::varnamelist &dl,
                                               const model::mimlist &/* mims */,
                                               model::real_matlist &/*matl*/,
@@ -3944,13 +3726,10 @@ namespace getfem {
         A = &(md.real_variable(dl[0]));
         mf_a = md.pmesh_fem_of_variable(dl[0]);
       }
-      pNeumann_elem_term pNt
-        = std::make_shared<generic_elliptic_Neumann_elem_term>(mf_a, A);
-      md.add_Neumann_term(pNt, vl[0], ib);
     }
 
-    virtual void complex_post_assembly_in_serial(const model &md, size_type ib,
-                                              const model::varnamelist &vl,
+    virtual void complex_post_assembly_in_serial(const model &md, size_type,
+                                              const model::varnamelist &,
                                               const model::varnamelist &dl,
                                               const model::mimlist &/*mims*/,
                                               model::complex_matlist &/*matl*/,
@@ -3966,9 +3745,6 @@ namespace getfem {
         A = &(md.real_variable(dl[0]));
         mf_a = md.pmesh_fem_of_variable(dl[0]);
       }
-      pNeumann_elem_term pNt
-        = std::make_shared<generic_elliptic_Neumann_elem_term>(mf_a, A);
-      md.add_Neumann_term(pNt, vl[0], ib);
     }
 
     virtual scalar_type asm_complex_tangent_terms(const model &md, size_type,
@@ -4274,7 +4050,7 @@ namespace getfem {
       set_flags("Source term", true /* is linear*/,
                 true /* is symmetric */, true /* is coercive */,
                 true /* is real */, true /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
     }
 
 
@@ -4427,7 +4203,7 @@ namespace getfem {
       set_flags("Normal source term", true /* is linear*/,
                 true /* is symmetric */, true /* is coercive */,
                 true /* is real */, true /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
     }
 
 
@@ -4556,34 +4332,27 @@ namespace getfem {
           gmm::clear(matl[0]);
         }
         GMM_TRACE2("Mass term assembly for Dirichlet condition");
-        if (H_version) {
-          if (mf_H)
-            asm_real_or_complex_1_param
-              (*B, mim, mf_mult, *mf_H, *H, rg, (mf_u.get_qdim() == 1) ?
-               "F=data(#2);"
-               "M(#1,#3)+=comp(Base(#1).Base(#3).Base(#2))(:,:,i).F(i)"
-               : "F=data(qdim(#1),qdim(#1),#2);"
-               "M(#1,#3)+=comp(vBase(#1).vBase(#3).Base(#2))(:,i,:,j,k).F(i,j,k);", &mf_u);
-          else {
-            asm_real_or_complex_1_param
-              (*B, mim, mf_mult, mf_u, *H, rg, (mf_u.get_qdim() == 1) ?
-               "F=data(1);"
-               "M(#1,#2)+=comp(Base(#1).Base(#2).F(1))"
-               : "F=data(qdim(#1),qdim(#1));"
-               "M(#1,#2)+=comp(vBase(#1).vBase(#2))(:,i,:,j).F(i,j);");
+        if (H_version || normal_component) {
+          ga_workspace workspace;
+	        gmm::sub_interval Imult(0, mf_mult.nb_dof()), Iu(0, mf_u.nb_dof());
+          base_vector u(mf_u.nb_dof());
+          base_vector mult(mf_mult.nb_dof());
+          workspace.add_fem_variable("u", mf_u, Iu, u);
+          workspace.add_fem_variable("mult", mf_mult, Imult, mult);
+          auto expression = std::string{};
+          if (H_version){
+            if (mf_H) workspace.add_fem_constant("A", *mf_H, *H);
+            else workspace.add_fixed_size_constant("A", *H);
+            expression = (mf_u.get_qdim() == 1) ?
+                          "Test_mult . (A . Test2_u)"
+                          :
+                          "Test_mult. (Reshape(A, qdim(u), qdim(u)) . Test2_u)";
+          } else if (normal_component){
+	          expression = "Test_mult . (Test2_u . Normal)";
           }
-        }
-        else if (normal_component) {
-          generic_assembly assem;
-          if (mf_mult.get_qdim() == 1)
-            assem.set("M(#2,#1)+=comp(Base(#2).vBase(#1).Normal())(:,:,i,i);");
-          else
-            assem.set("M(#2,#1)+=comp(vBase(#2).mBase(#1).Normal())(:,i,:,i,j,j);");
-          assem.push_mi(mim);
-          assem.push_mf(mf_u);
-          assem.push_mf(mf_mult);
-          assem.push_mat(*B);
-          assem.assembly(rg);
+          workspace.add_expression(expression, mim, rg);
+          workspace.set_assembled_matrix(*B);
+	        workspace.assembly(2);
         } else {
           asm_mass_matrix(*B, mim, mf_mult, mf_u, rg);
         }
@@ -4716,32 +4485,49 @@ namespace getfem {
         }
         GMM_TRACE2("Mass term assembly for Dirichlet condition");
         if (H_version) {
-          if (mf_H)
-            asm_real_or_complex_1_param
-              (*B, mim, mf_mult, *mf_H, *H, rg, (mf_u.get_qdim() == 1) ?
-               "F=data(#2);"
-               "M(#1,#3)+=sym(comp(Base(#1).Base(#3).Base(#2))(:,:,i).F(i))"
-               : "F=data(qdim(#1),qdim(#1),#2);"
-               "M(#1,#3)+=sym(comp(vBase(#1).vBase(#3).Base(#2))(:,i,:,j,k).F(i,j,k));", &mf_u);
-          else
-             asm_real_or_complex_1_param
-              (*B, mim, mf_mult, mf_u, *H, rg, (mf_u.get_qdim() == 1) ?
-               "F=data(1);"
-               "M(#1,#2)+=sym(comp(Base(#1).Base(#2)).F(1))"
-               : "F=data(qdim(#1),qdim(#1));"
-               "M(#1,#2)+=sym(comp(vBase(#1).vBase(#2))(:,i,:,j).F(i,j));");
+	  if (mf_u.get_qdim() == 1)
+	    asm_real_or_complex_1_param_mat(*B, mim, mf_mult, mf_H, *H, rg,
+					    "(A*Test_u).Test2_u");
+	  else
+	    asm_real_or_complex_1_param_mat(*B, mim, mf_mult, mf_H, *H, rg,
+			    "(Reshape(A,qdim(u),qdim(u))*Test2_u).Test_u");
+          // if (mf_H)
+          //   asm_real_or_complex_1_param
+          //     (*B, mim, mf_mult, *mf_H, *H, rg, (mf_u.get_qdim() == 1) ?
+          //      "F=data(#2);"
+          //      "M(#1,#3)+=sym(comp(Base(#1).Base(#3).Base(#2))(:,:,i).F(i))"
+          //      : "F=data(qdim(#1),qdim(#1),#2);"
+          //      "M(#1,#3)+=sym(comp(vBase(#1).vBase(#3).Base(#2))(:,i,:,j,k).F(i,j,k));", &mf_u);
+          // else
+          //    asm_real_or_complex_1_param
+          //     (*B, mim, mf_mult, mf_u, *H, rg, (mf_u.get_qdim() == 1) ?
+          //      "F=data(1);"
+          //      "M(#1,#2)+=sym(comp(Base(#1).Base(#2)).F(1))"
+          //      : "F=data(qdim(#1),qdim(#1));"
+          //      "M(#1,#2)+=sym(comp(vBase(#1).vBase(#2))(:,i,:,j).F(i,j));");
         }
         else if (normal_component) {
-          generic_assembly assem;
-          if (mf_mult.get_qdim() == 1)
-            assem.set("M(#2,#1)+=comp(Base(#2).vBase(#1).Normal())(:,:,i,i);");
-          else
-            assem.set("M(#2,#1)+=comp(vBase(#2).mBase(#1).Normal())(:,i,:,i,j,j);");
-          assem.push_mi(mim);
-          assem.push_mf(mf_u);
-          assem.push_mf(mf_mult);
-          assem.push_mat(gmm::real_part(*B));
-          assem.assembly(rg);
+	  ga_workspace workspace;
+	  gmm::sub_interval Imult(0, mf_mult.nb_dof()), Iu(0, mf_u.nb_dof());
+	  base_vector mult(mf_mult.nb_dof()), u(mf_u.nb_dof());
+	  workspace.add_fem_variable("mult", mf_mult, Imult, mult);
+	  workspace.add_fem_variable("u", mf_u, Iu, u);
+	  workspace.add_expression("Test_mult.(Test2_u.Normal)", mim, rg);
+	  model_real_sparse_matrix BB(mf_mult.nb_dof(), mf_u.nb_dof());
+	  workspace.set_assembled_matrix(BB);
+	  workspace.assembly(2);
+	  gmm::add(BB, *B);
+
+          // generic_assembly assem;
+          // if (mf_mult.get_qdim() == 1)
+          //   assem.set("M(#2,#1)+=comp(Base(#2).vBase(#1).Normal())(:,:,i,i);");
+          // else
+          //   assem.set("M(#2,#1)+=comp(vBase(#2).mBase(#1).Normal())(:,i,:,i,j,j);");
+          // assem.push_mi(mim);
+          // assem.push_mf(mf_u);
+          // assem.push_mf(mf_mult);
+          // assem.push_mat(gmm::real_part(*B));
+          // assem.assembly(rg);
         } else {
           asm_mass_matrix(*B, mim, mf_mult, mf_u, rg);
         }
@@ -4810,7 +4596,7 @@ namespace getfem {
                 true /* is linear*/,
                 true /* is symmetric */, penalized /* is coercive */,
                 true /* is real */, true /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
     }
   };
 
@@ -5162,7 +4948,7 @@ namespace getfem {
                 true /* is linear*/,
                 true /* is symmetric */, true /* is coercive */,
                 true /* is real */, true /* is complex */,
-                true /* compute each time */, false /* has a Neumann term */);
+                true /* compute each time */);
     }
   };
 
@@ -5507,7 +5293,7 @@ namespace getfem {
                 true /* is linear*/,
                 true /* is symmetric */, penalized /* is coercive */,
                 true /* is real */, true /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
     }
   };
 
@@ -5783,7 +5569,7 @@ namespace getfem {
       set_flags("Fourier Robin condition", true /* is linear*/,
                 true /* is symmetric */, true /* is coercive */,
                 true /* is real */, true /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
     }
 
   };
@@ -5930,7 +5716,7 @@ namespace getfem {
                 true /* is linear*/,
                 true /* is symmetric */, penalized /* is coercive */,
                 true /* is real */, true /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
     }
 
   };
@@ -6073,8 +5859,7 @@ namespace getfem {
                 true /* is linear*/,
                 symmetric_ /* is symmetric */, coercive_ /* is coercive */,
                 true /* is real */, true /* is complex */,
-                true /* is to be computed each time */,
-                false /* has a Neumann term */);
+                true /* is to be computed each time */);
     }
   };
 
@@ -6148,8 +5933,7 @@ namespace getfem {
                 true /* is linear*/,
                 true /* is symmetric */, true /* is coercive */,
                 true /* is real */, true /* is complex */,
-                true /* is to be computed each time */,
-                false /* has a Neumann term */);
+                true /* is to be computed each time */);
     }
 
   };
@@ -6171,257 +5955,6 @@ namespace getfem {
   //
   // ----------------------------------------------------------------------
 
-  // deprecated
-  struct iso_lin_elasticity_Neumann_elem_term : public Neumann_elem_term {
-
-    const mesh_fem *mf_lambda;
-    const model_real_plain_vector *lambda;
-    const mesh_fem *mf_mu;
-    const model_real_plain_vector *mu;
-
-    mutable fem_interpolation_context ctx_mu;
-    mutable base_vector coeff, val;
-    mutable base_matrix grad, E, G;
-
-    void compute_Neumann_term
-    (int version, const mesh_fem &mfvar, const model_real_plain_vector &var,
-     fem_interpolation_context& ctx, base_small_vector &n,
-     base_tensor &output, size_type /*auxilliary_ind*/ = 0) const {
-
-      if (version == 3) return;  // No contribution because the term is linear
-
-      dim_type qdim = mfvar.linked_mesh().dim();
-      gmm::resize(grad, qdim, qdim);
-      gmm::resize(E, qdim, qdim);
-      gmm::resize(val, 1);
-      size_type cv = ctx.convex_num();
-      scalar_type val_lambda = scalar_type(0), val_mu = scalar_type(0);
-
-      if (mf_mu) {
-        GMM_ASSERT1(!(mf_mu->is_reduced()),
-                    "Sorry, to be adapted for reduced mesh fems");
-
-        if (!(ctx_mu.have_pf()) || ctx_mu.convex_num() != cv
-            || (ctx_mu.have_pfp() != ctx.have_pfp())
-            || (ctx_mu.have_pfp()
-                && (ctx.pfp()->get_ppoint_tab()
-                    != ctx_mu.pfp()->get_ppoint_tab()))) {
-
-          bgeot::vectors_to_base_matrix
-            (G, mf_mu->linked_mesh().points_of_convex(cv));
-
-          pfem_precomp pfp = fem_precomp(mf_mu->fem_of_element(cv),
-                                         ctx.pfp()->get_ppoint_tab(), 0);
-
-          if (ctx.have_pfp())
-            ctx_mu = fem_interpolation_context
-              (mf_mu->linked_mesh().trans_of_convex(cv), pfp, ctx.ii(),
-               G, cv, ctx.face_num());
-          else
-            ctx_mu = fem_interpolation_context
-              (mf_mu->linked_mesh().trans_of_convex(cv),
-               mf_mu->fem_of_element(cv), ctx.xref(), G, cv, ctx.face_num());
-
-        } else {
-          if (ctx.have_pfp())  ctx_mu.set_ii(ctx.ii());
-          else ctx_mu.set_xref(ctx.xref());
-        }
-        slice_vector_on_basic_dof_of_element(*mf_mu, *mu, cv, coeff);
-        // coeff.resize(mf_mu->nb_basic_dof_of_element(cv));
-        // gmm::copy(gmm::sub_vector(*mu, gmm::sub_index
-        //                      (mf_mu->ind_basic_dof_of_element(cv))), coeff);
-        ctx_mu.pf()->interpolation(ctx_mu, coeff, val, 1);
-        val_mu = val[0];
-        slice_vector_on_basic_dof_of_element(*mf_mu, *lambda, cv, coeff);
-        // gmm::copy(gmm::sub_vector(*lambda, gmm::sub_index
-        //                      (mf_mu->ind_basic_dof_of_element(cv))), coeff);
-        ctx_mu.pf()->interpolation(ctx_mu, coeff, val, 1);
-        val_mu = val[0];
-      } else {
-        val_lambda = (*lambda)[0]; val_mu = (*mu)[0];
-      }
-
-      switch (version) {
-      case 1:
-        slice_vector_on_basic_dof_of_element(mfvar, var, cv, coeff);
-        // coeff.resize(mfvar.nb_basic_dof_of_element(cv));
-        // gmm::copy(gmm::sub_vector(var, gmm::sub_index
-        //                      (mfvar.ind_basic_dof_of_element(cv))), coeff);
-        ctx.pf()->interpolation_grad(ctx, coeff, grad, qdim);
-        gmm::copy(gmm::identity_matrix(), E);
-        gmm::scale(E, val_lambda * gmm::mat_trace(grad));
-        gmm::add(gmm::scaled(grad, val_mu), E);
-        gmm::add(gmm::scaled(gmm::transposed(grad), val_mu), E);
-        gmm::mult_add(E, n, output.as_vector());
-        break;
-      case 2:
-        {
-          base_tensor t;
-          dim_type tdim = ctx.pf()->target_dim(), qmult = qdim / tdim;
-          size_type ndof = ctx.pf()->nb_dof(cv);
-          // The return tensor is t(i,j,k) with 0<=i<ndof, 0<=j<target_dim,
-          // 0<=k<dim. In order to iterate on the tensor values, i should
-          // increment the faster, then j, then k.
-          // If target_dim == qdim, grad(phi_i)(j,k) = t(i,j,k)
-          // If target_dim == 1, grad(phi_i * e_l)(l,k) = t(i,1,k)
-          // General case, psi_{i*qmult+l} = phi_i * e_l  and
-          //    grad(psi_{i*qmult+l})(j+tdim*l,k) = t(i,j,k)
-          ctx.pf()->real_grad_base_value(ctx, t);
-
-          for (size_type l = 0; l < qmult; ++l) {
-            for (size_type p = 0; p < qdim; ++p) {
-              base_tensor::const_iterator it = t.begin();
-              for (size_type k = 0; k < qdim; ++k)
-                for (size_type j = 0; j < tdim; ++j)
-                  for (size_type i = 0; i < ndof; ++i, ++it) {
-                    size_type jj = j + tdim*l;
-                    if (k == jj) output(i*qmult+l, p) += val_lambda*(*it)*n[p];
-                    if (p == jj) output(i*qmult+l, p) += val_mu*(*it)*n[k];
-                    if (k == p) output(i*qmult+l, p) += val_mu*(*it)*n[jj];
-                  }
-              GMM_ASSERT1(it ==  t.end(), "Internal error");
-            }
-          }
-        }
-        break;
-      }
-
-    }
-
-    iso_lin_elasticity_Neumann_elem_term
-    (const mesh_fem *mf_lambda_,
-     const model_real_plain_vector *lambda_,
-     const mesh_fem *mf_mu_, const model_real_plain_vector *mu_) :
-      mf_lambda(mf_lambda_), lambda(lambda_), mf_mu(mf_mu_), mu(mu_) {
-      GMM_ASSERT1(mf_lambda == mf_mu,
-                  "The two coefficients should be described on the same "
-                  "finite element method.");
-    }
-
-  };
-
-  // deprecated brick
-  struct iso_lin_elasticity_brick : public virtual_brick {
-
-    std::string expr;
-
-    virtual void asm_real_tangent_terms(const model &md, size_type ib,
-                                        const model::varnamelist &vl,
-                                        const model::varnamelist &dl,
-                                        const model::mimlist &mims,
-                                        model::real_matlist &matl,
-                                        model::real_veclist &vecl,
-                                        model::real_veclist &,
-                                        size_type region,
-                                        build_version version) const {
-      GMM_ASSERT1(matl.size() == 1,
-                  "isotropic linearized elasticity brick has one and only "
-                  "one term");
-      GMM_ASSERT1(mims.size() == 1,
-                  "isotropic linearized elasticity brick need one and only "
-                  "one mesh_im");
-      GMM_ASSERT1(vl.size() == 1 && dl.size() >= 2 && dl.size() <= 3,
-                  "Wrong number of variables for isotropic linearized "
-                  "elasticity brick");
-
-      bool recompute_matrix = !((version & model::BUILD_ON_DATA_CHANGE) != 0)
-        || md.is_var_newer_than_brick(dl[0], ib)
-        || md.is_var_newer_than_brick(dl[1], ib);
-
-      if (recompute_matrix) {
-
-        const mesh_fem &mf_u = md.mesh_fem_of_variable(vl[0]);
-        const mesh &m = mf_u.linked_mesh();
-        size_type N = m.dim(), Q = mf_u.get_qdim();
-        GMM_ASSERT1(Q == N, "isotropic linearized elasticity brick is only "
-                    "for vector field of the same dimension as the mesh");
-        const mesh_im &mim = *mims[0];
-        mesh_region rg(region);
-        m.intersect_with_mpi_region(rg);
-        const mesh_fem *mf_lambda = md.pmesh_fem_of_variable(dl[0]);
-        const model_real_plain_vector *lambda = &(md.real_variable(dl[0]));
-        const mesh_fem *mf_mu = md.pmesh_fem_of_variable(dl[1]);
-        const model_real_plain_vector *mu = &(md.real_variable(dl[1]));
-
-        size_type sl = gmm::vect_size(*lambda);
-        if (mf_lambda) sl = sl * mf_lambda->get_qdim() / mf_lambda->nb_dof();
-        size_type sm = gmm::vect_size(*mu);
-        if (mf_mu) sm = sm * mf_mu->get_qdim() / mf_mu->nb_dof();
-
-        GMM_ASSERT1(sl == 1 && sm == 1, "Bad format of isotropic linearized "
-                    "elasticity brick coefficients");
-        GMM_ASSERT1(mf_lambda == mf_mu,
-                    "The two coefficients should be described on the same "
-                    "finite element method.");
-
-        GMM_TRACE2("Stiffness matrix assembly for isotropic linearized "
-                   "elasticity");
-        gmm::clear(matl[0]);
-        if (mf_lambda)
-          asm_stiffness_matrix_for_linear_elasticity
-            (matl[0], mim, mf_u, *mf_lambda, *lambda, *mu, rg);
-        else
-          asm_stiffness_matrix_for_homogeneous_linear_elasticity
-            (matl[0], mim, mf_u, *lambda, *mu, rg);
-
-      }
-
-
-      if  (dl.size() == 3) { // Pre-constraints given by an "initial"
-        // displacement u0. Means that the computed displacement will be u - u0
-        // The displacement u0 should be discribed on the same fem as the
-        // variable.
-        gmm::mult(matl[0],
-                  gmm::scaled(md.real_variable(dl[2]), scalar_type(-1)),
-                  vecl[0]);
-      }
-    }
-
-    virtual void real_post_assembly_in_serial(const model &md, size_type ib,
-                                              const model::varnamelist &vl,
-                                              const model::varnamelist &dl,
-                                              const model::mimlist &/*mims*/,
-                                              model::real_matlist &/*matl*/,
-                                              model::real_veclist &,
-                                              model::real_veclist &,
-                                              size_type /*region*/,
-                                              build_version version) const
-    {
-      bool recompute_matrix = !((version & model::BUILD_ON_DATA_CHANGE) != 0)
-        || md.is_var_newer_than_brick(dl[0], ib)
-        || md.is_var_newer_than_brick(dl[1], ib);
-
-      if (recompute_matrix)
-      {
-          const mesh_fem *mf_lambda = md.pmesh_fem_of_variable(dl[0]);
-          const model_real_plain_vector *lambda = &(md.real_variable(dl[0]));
-          const mesh_fem *mf_mu = md.pmesh_fem_of_variable(dl[1]);
-          const model_real_plain_vector *mu = &(md.real_variable(dl[1]));
-
-          pNeumann_elem_term pNt
-            = std::make_shared<iso_lin_elasticity_Neumann_elem_term>
-            (mf_lambda, lambda, mf_mu, mu);
-          md.add_Neumann_term(pNt, vl[0], ib);
-      }
-    }
-
-    virtual std::string declare_volume_assembly_string
-    (const model &, size_type, const model::varnamelist &,
-     const model::varnamelist &) const {
-      return expr;
-    }
-
-
-    iso_lin_elasticity_brick(const std::string &expr_) {
-      expr = expr_;
-      set_flags("isotropic linearized elasticity", true /* is linear*/,
-                true /* is symmetric */, true /* is coercive */,
-                true /* is real */, false /* is complex */);
-    }
-
-  };
-
-
   struct iso_lin_elasticity_new_brick : public virtual_brick {
 
     std::string expr, dataname3;
@@ -6517,26 +6050,11 @@ namespace getfem {
     std::string test_varname
       = "Test_" + sup_previous_and_dot_to_varname(varname);
     
-    std::string expr1 = "("+dataexpr1+")*(Div_"+varname+"-Div_"+dataname3
-      +")*Div_"+test_varname+"+("+dataexpr2+")*(Grad_"+varname+"+Grad_"
-      +varname+"'-Grad_"+dataname3+"-Grad_"+dataname3+"'):Grad_"
-      +test_varname;
-    std::string expr2 = "("+dataexpr1+")*Div_"+varname+"*Div_"+test_varname
-      + "+("+dataexpr2+")*(Grad_"+varname+"+Grad_"+varname+"'):Grad_"
-      + test_varname;
-    
-
-#if 0 // Old brick
-    pbrick pbr = std::make_shared<iso_lin_elasticity_brick>
-      (dataname3.size() ? expr1:expr2);
-    model::termlist tl;
-    tl.push_back(model::term_description(varname, varname, true));
-    model::varnamelist dl(1, dataexpr1);
-    dl.push_back(dataexpr2);
-    if (dataname3.size()) dl.push_back(dataname3);
-    return md.add_brick(pbr, model::varnamelist(1, varname), dl, tl,
-                        model::mimlist(1, &mim), region);
-#else // New brick with high-level generic assembly
+    std::string expr1 = "((("+dataexpr1+")*(Div_"+varname+"-Div_"+dataname3
+      +"))*Id(meshdim)+(2*("+dataexpr2+"))*(Sym(Grad_"+varname
+      +")-Sym(Grad_"+dataname3+"))):Grad_" +test_varname;
+    std::string expr2 = "(Div_"+varname+"*(("+dataexpr1+")*Id(meshdim))"
+      +"+(2*("+dataexpr2+"))*Sym(Grad_"+varname+")):Grad_"+test_varname;
     
     ga_workspace workspace(md, true);
     workspace.add_expression(expr2, mim, region);
@@ -6556,7 +6074,6 @@ namespace getfem {
         (md, mim, dataname3.size() ? expr1 : expr2, region, false, false,
          "Linearized isotropic elasticity (with nonlinear dependance)");
     }
-#endif
   }
 
   size_type add_isotropic_linearized_elasticity_brick_pstrain
@@ -6664,7 +6181,7 @@ namespace getfem {
       // The Lambda part is not necessary for Von Mises stress ...
       // std::string sigma = "("+data_lambda+")*Div_"+varname+"*Id(meshdim)+("
       //   + data_mu+")*(Grad_"+varname+"+Grad_"+varname+"')";
-      std::string sigma_d = "("+data_mu+")*(Grad_"+varname+"+Grad_"+varname+"')";
+      std::string sigma_d="("+data_mu+")*(Grad_"+varname+"+Grad_"+varname+"')";
       std::string expr = "sqrt(3/2)*Norm(Deviator("+sigma_d+"))";
       ga_interpolation_Lagrange_fem(md, expr, mf_vm, VM);
     }
@@ -6713,102 +6230,6 @@ namespace getfem {
   //
   // ----------------------------------------------------------------------
 
-  struct lin_incomp_Neumann_elem_term : public Neumann_elem_term {
-
-    const gmm::uint64_type &var_vnum;
-    const mesh_fem *mf_p;
-    const model_real_plain_vector *org_P;
-    mutable model_real_plain_vector P;
-    mutable gmm::uint64_type vnum;
-
-    mutable fem_interpolation_context ctx_p;
-    mutable base_vector coeff, val;
-    mutable base_matrix G;
-
-    void compute_Neumann_term
-    (int version, const mesh_fem &mfvar,
-     const model_real_plain_vector &/* var */,
-     fem_interpolation_context& ctx, base_small_vector &n,
-     base_tensor &output, size_type auxilliary_ind = 0) const {
-
-      if (version == 3) return;  // No contribution because the term is linear
-      if (version == 2 && auxilliary_ind == 0) return;
-
-      dim_type qdim = mfvar.linked_mesh().dim();
-      size_type cv = ctx.convex_num();
-
-      if (vnum != var_vnum || !(ctx_p.have_pf()) || ctx_p.convex_num() != cv
-          || (ctx_p.have_pfp() != ctx.have_pfp())
-          || (ctx_p.have_pfp()
-              && (ctx.pfp()->get_ppoint_tab()
-                  != ctx_p.pfp()->get_ppoint_tab()))) {
-
-        if (vnum != var_vnum) {
-          gmm::resize(P, mf_p->nb_basic_dof());
-          mf_p->extend_vector(*org_P, P);
-          vnum = var_vnum;
-        }
-
-        bgeot::vectors_to_base_matrix
-          (G, mf_p->linked_mesh().points_of_convex(cv));
-
-        if (ctx.have_pfp()) {
-          pfem_precomp pfp = fem_precomp(mf_p->fem_of_element(cv),
-                                         ctx.pfp()->get_ppoint_tab(), 0);
-          ctx_p = fem_interpolation_context
-            (mf_p->linked_mesh().trans_of_convex(cv), pfp, ctx.ii(),
-             G, cv, ctx.face_num());
-        } else
-          ctx_p = fem_interpolation_context
-            (mf_p->linked_mesh().trans_of_convex(cv),
-             mf_p->fem_of_element(cv), ctx.xref(), G, cv, ctx.face_num());
-      } else {
-        if (ctx_p.have_pfp()) ctx_p.set_ii(ctx.ii());
-        else ctx_p.set_xref(ctx.xref());
-
-      }
-
-      switch (version) {
-      case 1:
-        slice_vector_on_basic_dof_of_element(*mf_p, P, cv, coeff);
-        // coeff.resize(mf_p->nb_basic_dof_of_element(cv));
-        // gmm::copy(gmm::sub_vector(P, gmm::sub_index
-        //                      (mf_p->ind_basic_dof_of_element(cv))), coeff);
-        ctx_p.pf()->interpolation(ctx_p, coeff, val, 1);
-
-        for (size_type k = 0; k < qdim; ++k) output[k] -= val[0] * n[k];
-        break;
-      case 2:
-        {
-          base_tensor t;
-          size_type ndof = ctx_p.pf()->nb_dof(cv);
-          ctx_p.pf()->real_base_value(ctx_p, t);
-
-          for (size_type i = 0; i < ndof; ++i)
-            for (size_type k = 0; k < qdim; ++k)
-              output(i, k) -= t[i]*n[k];
-        }
-        break;
-      }
-
-    }
-
-    lin_incomp_Neumann_elem_term
-    (const gmm::uint64_type &var_vnum_, const mesh_fem *mf_p_,
-     const model_real_plain_vector *P_,
-     const std::string &auxvarname)
-      : var_vnum(var_vnum_), mf_p(mf_p_), org_P(P_)  {
-      auxilliary_variables.push_back(auxvarname);
-      gmm::resize(P, mf_p->nb_basic_dof());
-      mf_p->extend_vector(*P_, P);
-      vnum = var_vnum;
-      gmm::resize(val, 1);
-    }
-
-  };
-
-
-
   struct linear_incompressibility_brick : public virtual_brick {
 
     virtual void asm_real_tangent_terms(const model &md, size_type /*ib*/,
@@ -6867,8 +6288,8 @@ namespace getfem {
     }
 
 
-    virtual void real_post_assembly_in_serial(const model &md, size_type ib,
-                                              const model::varnamelist &vl,
+    virtual void real_post_assembly_in_serial(const model &, size_type,
+                                              const model::varnamelist &,
                                               const model::varnamelist &/*dl*/,
                                               const model::mimlist &/*mims*/,
                                               model::real_matlist &/*matl*/,
@@ -6876,14 +6297,7 @@ namespace getfem {
                                               model::real_veclist &,
                                               size_type /*region*/,
                                               build_version) const
-    {
-        const mesh_fem &mf_p = md.mesh_fem_of_variable(vl[1]);
-        pNeumann_elem_term pNt = std::make_shared<lin_incomp_Neumann_elem_term>
-          (md.version_number_of_data_variable( vl[1]), &mf_p,
-           &(md.real_variable(vl[1])), vl[1]);
-        md.add_Neumann_term(pNt, vl[0], ib);
-        md.add_auxilliary_variables_of_Neumann_terms(vl[0], vl[1]);
-    }
+    { }
 
 
     linear_incompressibility_brick(void) {
@@ -7039,7 +6453,7 @@ namespace getfem {
       set_flags("Mass brick", true /* is linear*/,
                 true /* is symmetric */, true /* is coercive */,
                 true /* is real */, true /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
     }
 
   };
@@ -7221,7 +6635,7 @@ namespace getfem {
       set_flags("Basic d/dt brick", true /* is linear*/,
                 true /* is symmetric */, true /* is coercive */,
                 true /* is real */, true /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
     }
 
   };
@@ -7396,7 +6810,7 @@ namespace getfem {
       set_flags("Basic d2/dt2 brick", true /* is linear*/,
                 true /* is symmetric */, true /* is coercive */,
                 true /* is real */, true /* is complex */,
-                false /* compute each time */, false /* has a Neumann term */);
+                false /* compute each time */);
     }
 
   };
diff --git a/src/getfem_nonlinear_elasticity.cc b/src/getfem_nonlinear_elasticity.cc
index 70581ac..d8ce08d 100644
--- a/src/getfem_nonlinear_elasticity.cc
+++ b/src/getfem_nonlinear_elasticity.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -126,7 +126,7 @@ namespace getfem {
     /* Third invariant det(E) */
     void compute_i3(void) {
       Einv = E;
-      i3_ = gmm::lu_inverse(Einv);
+      i3_ = bgeot::lu_inverse(&(*(Einv.begin())), gmm::mat_nrows(Einv));
       i3_c = true;
     }
 
@@ -287,7 +287,7 @@ namespace getfem {
     scalar_type d;
     do {
       gmm::fill_random(Phi);
-      d = gmm::lu_det(Phi);
+      d = bgeot::lu_det(&(*(Phi.begin())), N);
     } while (d < scalar_type(0.01)); 
     gmm::mult(gmm::transposed(Phi),Phi,E);
     gmm::scale(E,-1.); gmm::add(gmm::identity_matrix(),E); 
@@ -389,16 +389,23 @@ namespace getfem {
   }
   
   scalar_type SaintVenant_Kirchhoff_hyperelastic_law::strain_energy
-  (const base_matrix &E, const base_vector &params, scalar_type) const {
+  (const base_matrix &E, const base_vector &params, scalar_type det_trans) const {
+        // should be optimized, maybe deriving sigma from strain energy
+    if (det_trans <= scalar_type(0))
+    { return 1e200; }
+
     return gmm::sqr(gmm::mat_trace(E)) * params[0] / scalar_type(2)
     + gmm::mat_euclidean_norm_sqr(E) * params[1];
   }
   
   void SaintVenant_Kirchhoff_hyperelastic_law::sigma
-  (const base_matrix &E, base_matrix &result,const base_vector &params, scalar_type) const {
+  (const base_matrix &E, base_matrix &result,const base_vector &params, scalar_type det_trans) const {
     gmm::copy(gmm::identity_matrix(), result);
     gmm::scale(result, params[0] * gmm::mat_trace(E));
     gmm::add(gmm::scaled(E, 2 * params[1]), result);
+    if (det_trans <= scalar_type(0)) {
+      gmm::add(gmm::scaled(E, 1e200), result);
+    }
   }
   void SaintVenant_Kirchhoff_hyperelastic_law::grad_sigma
   (const base_matrix &E, base_tensor &result,const base_vector &params, scalar_type) const {
@@ -479,7 +486,7 @@ namespace getfem {
     // result(0,0,1,0) = 0;
     result(0,0,1,1) = params[1]*params[0]/(1-params[1]*poisonXY);
     result(1,1,0,0) = params[1]*params[0]/(1-params[1]*poisonXY);
-    // result(1,1,0,1) = 0;
+    // result(1,1,0,1) = 0;out
     // result(1,1,1,0) = 0;
     result(1,1,1,1) = params[2]/(1-params[1]*poisonXY);
     // result(0,1,0,0) = 0;
@@ -493,10 +500,10 @@ namespace getfem {
   }
 
   scalar_type Mooney_Rivlin_hyperelastic_law::strain_energy
-  (const base_matrix &E, const base_vector &params,
-   scalar_type /* det_trans*/) const {
-// shouldn't negative det_trans be handled here???
-//    if (compressible && det_trans <= scalar_type(0)) return 1e200;
+  (const base_matrix &E, const base_vector &params
+   ,scalar_type  det_trans) const {
+    //shouldn't negative det_trans be handled here???
+    if (compressible && det_trans <= scalar_type(0)) return 1e200;
     size_type N = gmm::mat_nrows(E);
     GMM_ASSERT1(N == 3, "Mooney Rivlin hyperelastic law only defined "
                 "on dimension 3, sorry");
@@ -504,7 +511,6 @@ namespace getfem {
     gmm::scale(C, scalar_type(2));
     gmm::add(gmm::identity_matrix(), C);
     compute_invariants ci(C);
-
     size_type i=0;
     scalar_type C1 = params[i++]; // C10
     scalar_type W = C1 * (ci.j1() - scalar_type(3));
@@ -521,7 +527,7 @@ namespace getfem {
 
   void Mooney_Rivlin_hyperelastic_law::sigma
   (const base_matrix &E, base_matrix &result,
-   const base_vector &params, scalar_type /*det_trans*/) const {
+   const base_vector &params, scalar_type det_trans) const {
     size_type N = gmm::mat_nrows(E);
     GMM_ASSERT1(N == 3, "Mooney Rivlin hyperelastic law only defined "
                 "on dimension 3, sorry");
@@ -541,9 +547,10 @@ namespace getfem {
       scalar_type D1 = params[i++];
       scalar_type di3 = D1 - D1 / sqrt(gmm::abs(ci.i3()));
       gmm::add(gmm::scaled(ci.grad_i3(), scalar_type(2) * di3), result);
+
 // shouldn't negative det_trans be handled here???
-//      if (det_trans <= scalar_type(0))
-//        gmm::add(gmm::scaled(C, 1e200), result);
+      if (det_trans <= scalar_type(0))
+          gmm::add(gmm::scaled(C, 1e200), result);
     }
   }
 
@@ -595,15 +602,15 @@ namespace getfem {
     nb_params_ = 2;
     if (compressible) ++nb_params_; // D1 != 0
     if (neohookean) --nb_params_;   // C2 == 0
+
   }
 
 
 
 
   scalar_type Neo_Hookean_hyperelastic_law::strain_energy
-  (const base_matrix &E, const base_vector &params,
-   scalar_type det_trans) const {
-    if (det_trans <= scalar_type(0)) return 1e200;
+  (const base_matrix &E, const base_vector &params, scalar_type det_trans) const {
+   if (det_trans <= scalar_type(0)) return 1e200;
     size_type N = gmm::mat_nrows(E);
     GMM_ASSERT1(N == 3, "Neo Hookean hyperelastic law only defined "
                 "on dimension 3, sorry");
@@ -626,7 +633,7 @@ namespace getfem {
 
   void Neo_Hookean_hyperelastic_law::sigma
   (const base_matrix &E, base_matrix &result,
-   const base_vector &params, scalar_type det_trans) const {
+   const base_vector &params , scalar_type det_trans) const {
     size_type N = gmm::mat_nrows(E);
     GMM_ASSERT1(N == 3, "Neo Hookean hyperelastic law only defined "
                 "on dimension 3, sorry");
@@ -644,7 +651,6 @@ namespace getfem {
     else
        gmm::add(gmm::scaled(ci.grad_i3(),
                             lambda/2 - lambda/(2*ci.i3()) - mu / ci.i3()), result);
-    
     if (det_trans <= scalar_type(0))
       gmm::add(gmm::scaled(C, 1e200), result);
   }
@@ -820,7 +826,7 @@ namespace getfem {
     base_matrix C(N, N);
     gmm::copy(gmm::scaled(E, scalar_type(2)), C);
     gmm::add(gmm::identity_matrix(), C);
-    scalar_type det = gmm::lu_det(C);
+    scalar_type det = bgeot::lu_det(&(*(C.begin())), N);
     return a * gmm::mat_trace(C)
       + b * (gmm::sqr(gmm::mat_trace(C)) - 
              gmm::mat_euclidean_norm_sqr(C))/scalar_type(2)
@@ -847,8 +853,8 @@ namespace getfem {
     gmm::add(gmm::scaled(C, -scalar_type(2) * b), result);
     if (det_trans <= scalar_type(0))
       gmm::add(gmm::scaled(C, 1e200), result);
-    else {
-      scalar_type det = gmm::lu_inverse(C);
+          else {
+      scalar_type det = bgeot::lu_inverse(&(*(C.begin())), N);
       gmm::add(gmm::scaled(C, scalar_type(2) * c * det - d), result);
     }
   }
@@ -864,7 +870,7 @@ namespace getfem {
     base_matrix C(N, N);
     gmm::copy(gmm::scaled(E, scalar_type(2)), C);
     gmm::add(gmm::identity_matrix(), C);
-    scalar_type det = gmm::lu_inverse(C);
+    scalar_type det = bgeot::lu_inverse(&(*(C.begin())), N);
     std::fill(result.begin(), result.end(), scalar_type(0));
     for (size_type i = 0; i < N; ++i)
       for (size_type j = 0; j < N; ++j) {
@@ -1103,7 +1109,7 @@ namespace getfem {
         //jyh : end complete graphi
       }
 
-      gmm::scale(sigma, scalar_type(1) / gmm::lu_det(gradphi));
+      gmm::scale(sigma, scalar_type(1) / bgeot::lu_det(&(*(gradphi.begin())), NFem));
 
       if (!tresca) {
         /* von mises: norm(deviator(sigma)) */
@@ -1355,7 +1361,7 @@ namespace getfem {
       size_type N = args[0]->sizes()[0];
       base_matrix M(N, N);
       gmm::copy(args[0]->as_vector(), M.as_vector());
-      scalar_type det = gmm::lu_det(M);
+      scalar_type det = bgeot::lu_det(&(*(M.begin())), N);
       scalar_type tr = scalar_type(0);
       for (size_type i = 0; i < N; ++i) tr += M(i,i);
       if (det > 0)
@@ -1372,7 +1378,7 @@ namespace getfem {
       gmm::copy(args[0]->as_vector(), M.as_vector());
       scalar_type tr = scalar_type(0);
       for (size_type i = 0; i < N; ++i) tr += M(i,i);
-      scalar_type det = gmm::lu_inverse(M);
+      scalar_type det = bgeot::lu_inverse(&(*(M.begin())), N);
       if (det > 0) {
         base_tensor::iterator it = result.begin();
         for (size_type j = 0; j < N; ++j)
@@ -1394,7 +1400,7 @@ namespace getfem {
       gmm::copy(args[0]->as_vector(), M.as_vector());
       scalar_type tr = scalar_type(0);
       for (size_type i = 0; i < N; ++i) tr += M(i,i);
-      scalar_type det = gmm::lu_inverse(M);
+      scalar_type det = bgeot::lu_inverse(&(*(M.begin())), N);
       if (det > 0) {
         base_tensor::iterator it = result.begin();
         for (size_type l = 0; l < N; ++l)
@@ -1434,7 +1440,7 @@ namespace getfem {
         for (size_type j = 0; j < N; ++j)
           tr2 += M(i,j)*M(j,i);
       scalar_type i2 = (tr*tr-tr2)/scalar_type(2);
-      scalar_type det = gmm::lu_det(M);
+      scalar_type det = bgeot::lu_det(&(*(M.begin())), N);
 
       if (det > 0)
         result[0] = i2 / pow(det, scalar_type(2)/scalar_type(3));
@@ -1456,7 +1462,7 @@ namespace getfem {
         for (size_type j = 0; j < N; ++j)
           tr2 += M(i,j)*M(j,i);
       scalar_type i2 = (tr*tr-tr2)/scalar_type(2);
-      scalar_type det = gmm::lu_inverse(M);
+      scalar_type det = bgeot::lu_inverse(&(*(M.begin())), N);
       base_tensor::iterator it = result.begin();
       for (size_type j = 0; j < N; ++j)
         for (size_type i = 0; i < N; ++i, ++it)
@@ -1480,7 +1486,7 @@ namespace getfem {
         for (size_type j = 0; j < N; ++j)
           tr2 += M(i,j)*M(j,i);
       scalar_type i2 = (tr*tr-tr2)/scalar_type(2);
-      scalar_type det = gmm::lu_inverse(M);
+      scalar_type det = bgeot::lu_inverse(&(*(M.begin())), N);
       base_tensor::iterator it = result.begin();
       for (size_type l = 0; l < N; ++l)
         for (size_type k = 0; k < N; ++k)
@@ -1491,7 +1497,7 @@ namespace getfem {
                       - 2.*tr*M(j,i)*((k==l) ? 1. : 0.)/3.
                       + 2.*tr*M(j,i)*M(l,k)/3.
                       - 2.*i2*M(i,k)*M(l,j)/3.
-                      - 2.*((tr*(i==j) ? 1. : 0.)-t[j+N*i]
+                      - 2.*((tr*((i==j) ? 1. : 0.))-t[j+N*i]
                             - 2.*i2*M(j,i)/3)*M(l,k)/3.)
                 / pow(det, scalar_type(2)/scalar_type(3));
     }
@@ -1704,7 +1710,7 @@ namespace getfem {
       gmm::add(gmm::identity_matrix(), F);
       gmm::mult(F, sigma, aux);
       gmm::mult(aux, gmm::transposed(F), sigma);
-      scalar_type det = gmm::lu_det(F);
+      scalar_type det = bgeot::lu_det(&(*(F.begin())), N);
       gmm::scale(sigma, scalar_type(1)/det);
       gmm::copy(sigma.as_vector(), result.as_vector());
     }
@@ -1716,7 +1722,7 @@ namespace getfem {
       base_matrix F(N, N);
       gmm::copy(args[1]->as_vector(), F.as_vector());
       gmm::add(gmm::identity_matrix(), F);
-      scalar_type det = gmm::lu_det(F);
+      scalar_type det = bgeot::lu_det(&(*(F.begin())), N);
 
       base_tensor::iterator it = result.begin();
 
@@ -1738,7 +1744,7 @@ namespace getfem {
           gmm::copy(args[0]->as_vector(), sigma.as_vector());
           gmm::mult(sigma, gmm::transposed(F), aux);
           gmm::mult(F, aux, aux2);
-          gmm::lu_inverse(F);
+          bgeot::lu_inverse(&(*(F.begin())), N);
           for (size_type l = 0; l < N; ++l)
             for (size_type k = 0; k < N; ++k)
               for (size_type j = 0; j < N; ++j)
@@ -1783,7 +1789,7 @@ namespace getfem {
       gmm::add(Gu, E); gmm::add(gmm::transposed(Gu), E);
       gmm::scale(E, scalar_type(0.5));
       gmm::add(gmm::identity_matrix(), Gu);
-      scalar_type det = gmm::lu_det(Gu);
+      scalar_type det = bgeot::lu_det(&(*(Gu.begin())), N);
 
       AHL->sigma(E, sigma, params, det);
       gmm::copy(sigma.as_vector(), result.as_vector());
@@ -1802,7 +1808,7 @@ namespace getfem {
       gmm::add(Gu, E); gmm::add(gmm::transposed(Gu), E);
       gmm::scale(E, scalar_type(0.5));
       gmm::add(gmm::identity_matrix(), Gu);
-      scalar_type det = gmm::lu_det(Gu);
+      scalar_type det = bgeot::lu_det(&(*(Gu.begin())), N);
 
       GMM_ASSERT1(nder == 1, "Sorry, the derivative of this hyperelastic "
                   "law with respect to its parameters is not available.");
@@ -1854,7 +1860,7 @@ namespace getfem {
       gmm::add(Gu, E); gmm::add(gmm::transposed(Gu), E);
       gmm::scale(E, scalar_type(0.5));
       gmm::add(gmm::identity_matrix(), Gu);
-      scalar_type det = gmm::lu_det(Gu); // not necessary here
+      scalar_type det = bgeot::lu_det(&(*(Gu.begin())), N); // not necessary here
 
       result[0] = AHL->strain_energy(E, params, det);
     }
@@ -1871,7 +1877,7 @@ namespace getfem {
       gmm::add(Gu, E); gmm::add(gmm::transposed(Gu), E);
       gmm::scale(E, scalar_type(0.5));
       gmm::add(gmm::identity_matrix(), Gu);
-      scalar_type det = gmm::lu_det(Gu); // not necessary here
+      scalar_type det = bgeot::lu_det(&(*(Gu.begin())), N); // not necessary here
 
       GMM_ASSERT1(nder == 1, "Sorry, Cannot derive the potential with "
                   "respect to law parameters.");
@@ -1896,7 +1902,7 @@ namespace getfem {
       gmm::add(Gu, E); gmm::add(gmm::transposed(Gu), E);
       gmm::scale(E, scalar_type(0.5));
       gmm::add(gmm::identity_matrix(), Gu);
-      scalar_type det = gmm::lu_det(Gu);
+      scalar_type det = bgeot::lu_det(&(*(Gu.begin())), N);
 
       GMM_ASSERT1(nder1 == 1 && nder2 == 1, "Sorry, Cannot derive the "
                   "potential with respect to law parameters.");
diff --git a/src/getfem_omp.cc b/src/getfem_omp.cc
index 9d80ef5..8dea739 100644
--- a/src/getfem_omp.cc
+++ b/src/getfem_omp.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2012-2016 Andriy Andreykiv.
+ Copyright (C) 2012-2017 Andriy Andreykiv.
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem_partial_mesh_fem.cc b/src/getfem_partial_mesh_fem.cc
index 9119a45..b08ad68 100644
--- a/src/getfem_partial_mesh_fem.cc
+++ b/src/getfem_partial_mesh_fem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard
+ Copyright (C) 2006-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -130,7 +130,7 @@ namespace getfem {
     dal::bit_vector kept_dofs;
 
     for (dal::bv_visitor cv(mim.convex_index()); !cv.finished(); ++cv) {
-      bgeot::vectors_to_base_matrix(G, m.points_of_convex(cv));
+      m.points_of_convex(cv, G);
       bgeot::pgeometric_trans pgt = m.trans_of_convex(cv);
       pintegration_method pim = mim.int_method_of_element(cv);
       if (pim == im_none()) continue;
diff --git a/src/getfem_plasticity.cc b/src/getfem_plasticity.cc
index c511a5f..3446e73 100644
--- a/src/getfem_plasticity.cc
+++ b/src/getfem_plasticity.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Konstantinos Poulios, Amandine Cottaz, Yves Renard
+ Copyright (C) 2002-2017 Konstantinos Poulios, Amandine Cottaz, Yves Renard
 
  This file is a part of GetFEM++
 
@@ -326,6 +326,73 @@ namespace getfem {
   };
 
 
+  // Ball Projection operator.
+  struct Ball_projection_operator : public ga_nonlinear_operator {
+    bool result_size(const arg_list &args, bgeot::multi_index &sizes) const {
+      if (args.size() != 2 || args[0]->sizes().size() > 2
+          || args[0]->sizes().size() < 1 || args[1]->size() != 1) return false;
+      if (args[0]->sizes().size() == 1)
+        ga_init_vector(sizes, args[0]->sizes()[0]);
+      else
+        ga_init_matrix(sizes, args[0]->sizes()[0], args[0]->sizes()[1]);
+      return true;
+    }
+
+    // Value : ru/|u| if |u| > r, else u 
+    void value(const arg_list &args, base_tensor &result) const {
+      const base_tensor &t = *args[0];
+      scalar_type r = (*args[1])[0];
+      scalar_type no = gmm::vect_norm2(t.as_vector());
+      if (no > r)
+	gmm::copy(gmm::scaled(t.as_vector(), r/no), result.as_vector());
+      else
+	gmm::copy(t.as_vector(), result.as_vector());
+    }
+
+    // Derivative
+    void derivative(const arg_list &args, size_type n,
+                    base_tensor &result) const {
+      const base_tensor &t = *args[0];
+      size_type N = t.size();
+      scalar_type r = (*args[1])[0];
+      scalar_type no = gmm::vect_norm2(t.as_vector()), rno3 = r/(no*no*no);
+
+      gmm::clear(result.as_vector());
+
+      switch(n) {
+
+      case 1 : // derivative with respect to u
+	if (r > 0) {
+	  if (no <= r) {
+	    for (size_type i = 0; i < N; ++i)
+	      result[i*N+i] += scalar_type(1);
+	  } else {
+	    for (size_type i = 0; i < N; ++i) {
+	      result[i*N+i] += r/no;
+	      for (size_type j = 0; j < N; ++j)
+		result[j*N+i] -= t[i]*t[j]*rno3;
+	    }
+	  }
+	}
+	break;
+      case 2 : // derivative with respect to r
+	if (r > 0 && no > r) {
+	  for (size_type i = 0; i < N; ++i)
+	    result[i] = t[i]/no;
+	}
+	break;
+      default : GMM_ASSERT1(false, "Wrong derivative number");
+      }
+    }
+    
+    // Second derivative : not implemented
+    void second_derivative(const arg_list &/*args*/, size_type, size_type,
+                           base_tensor &/*result*/) const {
+      GMM_ASSERT1(false, "Sorry, second derivative not implemented");
+    }
+  };
+
+
   // Normalized_reg vector/matrix operator : Regularized Vector/matrix divided by its Frobenius norm
   struct normalized_reg_operator : public ga_nonlinear_operator {
     bool result_size(const arg_list &args, bgeot::multi_index &sizes) const {
@@ -484,6 +551,8 @@ namespace getfem {
                                 std::make_shared<normalized_operator>());
     PREDEF_OPERATORS.add_method("Normalized_reg",
                                 std::make_shared<normalized_reg_operator>());
+    PREDEF_OPERATORS.add_method("Ball_projection",
+                                std::make_shared<Ball_projection_operator>());
     PREDEF_OPERATORS.add_method("Von_Mises_projection",
                                 std::make_shared<Von_Mises_projection_operator>());
     return true;
@@ -1111,7 +1180,7 @@ namespace getfem {
     bool hardening = (lawname.find("_hardening") != std::string::npos);
     size_type nhard = hardening ? 2 : 0;
 
-    GMM_ASSERT1(varnames.size() == hardening ? 4 : 3,
+    GMM_ASSERT1(varnames.size() == (hardening ? 4 : 3),
                 "Incorrect number of variables: " << varnames.size());
     GMM_ASSERT1(params.size() >= 3+nhard &&
                 params.size() <= 5+nhard,
@@ -1853,7 +1922,7 @@ namespace getfem {
                                              gmm::sub_interval(0,mf_sigma.nb_dof())),
                              Sigma_n);
 
-      if (pmf_data != NULL) {
+      if (pmf_data) {
         gmm::resize(mu, pmf_data->nb_basic_dof());
         gmm::resize(lambda, pmf_data->nb_basic_dof());
         gmm::resize(threshold, pmf_data->nb_basic_dof());
@@ -1978,7 +2047,7 @@ namespace getfem {
      const mesh_im &mim,
      const mesh_fem &mf_u,
      const mesh_fem &mf_sigma,
-     const mesh_fem &mf_data,
+     const mesh_fem *pmf_data,
      const model_real_plain_vector &u_n,
      const model_real_plain_vector &u_np1,
      const model_real_plain_vector &sigma_n,
@@ -1991,14 +2060,14 @@ namespace getfem {
     GMM_ASSERT1(mf_u.get_qdim() == mf_u.linked_mesh().dim(),
                 "wrong qdim for the mesh_fem");
 
-    elastoplasticity_nonlinear_term gradplast(mim, mf_u, mf_sigma, &mf_data,
+    elastoplasticity_nonlinear_term gradplast(mim, mf_u, mf_sigma, pmf_data,
                                               u_n, u_np1, sigma_n,
                                               threshold, lambda, mu,
                                               t_proj, GRADPROJ, false);
 
     generic_assembly assem;
 
-    if (&(mf_data)!=NULL)
+    if (pmf_data)
       assem.set("lambda=data$1(#3); mu=data$2(#3);"
                 "t=comp(NonLin(#2).vGrad(#1).vGrad(#1).Base(#3))(i,j,:,:,:,:,:,:,i,j,:);"
                 "M(#1,#1)+=  sym(t(k,l,:,l,k,:,m).mu(m)+t(k,l,:,k,l,:,m).mu(m)+t(k,k,:,l,l,:,m).lambda(m))");
@@ -2010,8 +2079,8 @@ namespace getfem {
     assem.push_mi(mim);
     assem.push_mf(mf_u);
     assem.push_mf(mf_sigma);
-    if (&(mf_data)!=NULL)
-      assem.push_mf(mf_data);
+    if (pmf_data)
+      assem.push_mf(*pmf_data);
     assem.push_data(lambda);
     assem.push_data(mu);
     assem.push_nonlinear_term(&gradplast);
@@ -2077,7 +2146,7 @@ namespace getfem {
       if (version & model::BUILD_MATRIX) {
         gmm::clear(matl[0]);
         asm_elastoplasticity_tangent_matrix
-          (matl[0], mim, mf_u, mf_sigma, *mf_data, u_n,
+          (matl[0], mim, mf_u, mf_sigma, mf_data, u_n,
            u_np1, sigma_n, lambda, mu, threshold, *t_proj, rg);
       }
 
@@ -2307,4 +2376,3 @@ namespace getfem {
 
 
 }  /* end of namespace getfem.  */
-
diff --git a/src/getfem_projected_fem.cc b/src/getfem_projected_fem.cc
index b808a7e..10d5534 100644
--- a/src/getfem_projected_fem.cc
+++ b/src/getfem_projected_fem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2012-2016 Yves Renard, Konstantinos Poulios
+ Copyright (C) 2012-2017 Yves Renard, Konstantinos Poulios
 
  This file is a part of GetFEM++
 
@@ -765,7 +765,7 @@ namespace getfem {
 
   void projected_fem::gauss_pts_stats(unsigned &ming, unsigned &maxg,
                                       scalar_type &meang) const {
-    std::vector<unsigned> v(mf_source.linked_mesh().convex_index().last_true()+1);
+    std::vector<unsigned> v(mf_source.linked_mesh().nb_allocated_convex());
     std::map<size_type,elt_projection_data>::const_iterator eit;
     for (eit = elements.begin(); eit != elements.end(); ++eit) {
       std::map<size_type,gausspt_projection_data>::const_iterator git;
@@ -815,7 +815,7 @@ namespace getfem {
       store_values(store_val), blocked_dofs(blocked_dofs_), mi2(2), mi3(3) {
     this->add_dependency(mf_source);
     this->add_dependency(mim_target);
-    is_pol = is_lag = false; es_degree = 5;
+    is_pol = is_lag = is_standard_fem = false; es_degree = 5;
     is_equiv = real_element_defined = true;
     ntarget_dim = mf_source.get_qdim();
 
diff --git a/src/getfem_regular_meshes.cc b/src/getfem_regular_meshes.cc
index 95cfb7a..50d061c 100644
--- a/src/getfem_regular_meshes.cc
+++ b/src/getfem_regular_meshes.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 1999-2016 Yves Renard
+ Copyright (C) 1999-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -100,8 +100,6 @@ namespace getfem
     }
   }
 
-
-
   void parallelepiped_regular_mesh_
   (mesh &me, dim_type N, const base_node &org,
    const base_small_vector *ivect, const size_type *iref, bool linear_gt) {
@@ -140,6 +138,52 @@ namespace getfem
     }
   }
 
+  void parallelepiped_regular_pyramid_mesh_
+  (mesh &me, const base_node &org,
+   const base_small_vector *ivect, const size_type *iref) {
+    dim_type N = 3;
+    bgeot::convex<base_node>
+      pararef = *(bgeot::parallelepiped_of_reference(N));
+    base_node a = org, barycenter(N);
+    size_type i, nbpt = pararef.nb_points();
+
+    for (i = 0; i < nbpt; ++i) {
+      gmm::clear(a);
+      for (dim_type n = 0; n < N; ++n)
+        gmm::add(gmm::scaled(ivect[n],pararef.points()[i][n]),a);
+      //a.addmul(pararef.points()[i][n], ivect[n]);
+      pararef.points()[i] = a;
+      barycenter += a;
+    }
+    barycenter /= double(nbpt);
+
+    std::vector<size_type> tab1(N+1), tab(N), tab3(nbpt);
+    size_type total = 0;
+    std::fill(tab.begin(), tab.end(), 0);
+    while (tab[N-1] != iref[N-1]) {
+      for (a = org, i = 0; i < N; i++)
+        gmm::add(gmm::scaled(ivect[i], scalar_type(tab[i])),a);
+      //a.addmul(scalar_type(tab[i]), ivect[i]);
+
+      for (i = 0; i < nbpt; i++)
+        tab3[i] = me.add_point(a + pararef.points()[i]);
+      size_type ib = me.add_point(a + barycenter);
+      me.add_pyramid(tab3[0],tab3[1],tab3[2],tab3[3],ib);
+      me.add_pyramid(tab3[4],tab3[6],tab3[5],tab3[7],ib);
+      me.add_pyramid(tab3[0],tab3[4],tab3[1],tab3[5],ib);
+      me.add_pyramid(tab3[1],tab3[5],tab3[3],tab3[7],ib);
+      me.add_pyramid(tab3[3],tab3[7],tab3[2],tab3[6],ib);
+      me.add_pyramid(tab3[2],tab3[6],tab3[0],tab3[4],ib);
+
+      for (dim_type l = 0; l < N; l++) {
+        tab[l]++; total++;
+        if (l < N-1 && tab[l] >= iref[l]) { total -= tab[l]; tab[l] = 0; }
+        else break;
+      }
+    }
+  }
+
+
   /* deformation inside a unit square  -- ugly */
   static base_node shake_func(const base_node& x) {
     base_node z(x.size());
@@ -210,6 +254,9 @@ namespace getfem
     } else if (pgt->basic_structure() == bgeot::prism_structure(N)) {
       getfem::parallelepiped_regular_prism_mesh
         (msh, N, org, vtab.begin(), nsubdiv.begin());
+    } else if (pgt->basic_structure() == bgeot::pyramidal_structure(1)) {
+      getfem::parallelepiped_regular_pyramid_mesh
+        (msh, org, vtab.begin(), nsubdiv.begin());
     } else {
       GMM_ASSERT1(false, "cannot build a regular mesh for "
                   << bgeot::name_of_geometric_trans(pgt));
@@ -234,7 +281,7 @@ namespace getfem
     /* apply a continuous deformation + some noise */
     if (noised) noise_unit_mesh(m, nsubdiv, pgt);
 
-    m.optimize_structure();
+    m.optimize_structure(false);
   }
 
 
diff --git a/src/getfem_superlu.cc b/src/getfem_superlu.cc
index faec286..923977b 100644
--- a/src/getfem_superlu.cc
+++ b/src/getfem_superlu.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2004-2016 Julien Pommier
+ Copyright (C) 2004-2017 Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/getfem_torus.cc b/src/getfem_torus.cc
index 448bc89..8680d56 100644
--- a/src/getfem_torus.cc
+++ b/src/getfem_torus.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2014-2016 Liang Jin Lim
+ Copyright (C) 2014-2017 Liang Jin Lim
 
  This file is a part of GetFEM++
 
@@ -18,437 +18,436 @@
  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 ===========================================================================*/
-
-#include "getfem/getfem_torus.h"
-
-namespace bgeot{
-
-  /**torus_structure which extends a 2 dimensional structure with a radial dimension*/
-  class torus_structure : public convex_structure{
-
-    friend pconvex_structure torus_structure_descriptor(pconvex_structure);
-  };
-
-  class torus_reference : public convex_of_reference{
-
-  public :
-    scalar_type is_in(const base_node& point) const{
-      GMM_ASSERT1(point.size() >= 2, "Invalid dimension of pt " << point);
-      base_node point_2d = point;
-      point_2d.resize(2);
-      return ori_ref_convex_->is_in(point_2d);
-    }
-
-    scalar_type is_in_face(bgeot::short_type f, const base_node& point) const{
-      GMM_ASSERT1(point.size() >= 2, "Invalid dimension of pt " << point);
-      base_node point2D = point;
-      point2D.resize(2);
-      return ori_ref_convex_->is_in_face(f, point2D);
-    }  
-    torus_reference(bgeot::pconvex_ref ori_ref_convex){
-      ori_ref_convex_ = ori_ref_convex;
-      cvs = torus_structure_descriptor(ori_ref_convex->structure());
-      convex<base_node>::points().resize(cvs->nb_points());
-      normals_.resize(ori_ref_convex->normals().size());
-
-      const std::vector<base_small_vector> &ori_normals = ori_ref_convex->normals();
-      const stored_point_tab &ori_points = ori_ref_convex->points();
-      for(size_type n = 0; n < ori_normals.size(); ++n){
-       normals_[n] = ori_normals[n];
-       normals_[n].resize(3);
-      }            
-
-      std::copy(ori_points.begin(), ori_points.end(), convex<base_node>::points().begin());
-      for(size_type pt = 0; pt < convex<base_node>::points().size(); ++pt){
-        convex<base_node>::points()[pt].resize(3);
-      }
-      ppoints = store_point_tab(convex<base_node>::points());
-    }
-
-  private:
-    bgeot::pconvex_ref ori_ref_convex_;
-  };
-
-  DAL_SIMPLE_KEY(torus_structure_key, pconvex_structure);
-
-  pconvex_structure torus_structure_descriptor(pconvex_structure ori_structure){
-
-    dal::pstatic_stored_object_key
-      pk = std::make_shared<torus_structure_key>(ori_structure);
-    dal::pstatic_stored_object o = dal::search_stored_object(pk);
-    if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
-
-    auto p = std::make_shared<torus_structure>();
-    pconvex_structure pcvs(p);
-    p->Nc = dim_type(ori_structure->dim() + 1);
-    p->nbpt = ori_structure->nb_points();
-    p->nbf = ori_structure->nb_faces();
-
-    p->faces_struct.resize(p->nbf);
-    p->faces.resize(p->nbf);
-
-    for (short_type j = 0; j < p->nbf; ++j){
-      p->faces_struct[j] = ori_structure->faces_structure()[j];
-      short_type nbIndex = ori_structure->nb_points_of_face(j);
-      p->faces[j].resize(nbIndex);
-      p->faces[j] = ori_structure->ind_points_of_face(j);
-    }
-
-    p->dir_points_.resize(ori_structure->ind_dir_points().size());
-    p->dir_points_ = ori_structure->ind_dir_points();
-
-    p->basic_pcvs = basic_structure(ori_structure);
-
-    dal::add_stored_object(pk, pcvs, dal::PERMANENT_STATIC_OBJECT);
-    return pcvs;
-  }
-
-  DAL_SIMPLE_KEY(torus_reference_key, pconvex_ref);
-
-  pconvex_ref ptorus_reference(pconvex_ref ori_convex_reference)
-  {
-    dal::pstatic_stored_object_key
-      pk = std::make_shared<torus_reference_key>(ori_convex_reference);
-    dal::pstatic_stored_object o = dal::search_stored_object(pk);
-
-    if (o) return std::dynamic_pointer_cast<const bgeot::convex_of_reference>(o);
-    pconvex_ref p = std::make_shared<torus_reference>(ori_convex_reference);
-    dal::add_stored_object(pk, p, p->structure(), p->pspt(),
-			   dal::PERMANENT_STATIC_OBJECT);
-    return p;
-  }
-
-  void torus_geom_trans::poly_vector_val(const base_node &pt, bgeot::base_vector &val) const{
-    base_node pt_2d(pt);
-    pt_2d.resize(2);
-    poriginal_trans_->poly_vector_val(pt_2d, val);
-  }
-
-  void torus_geom_trans::poly_vector_val(const base_node &pt, const bgeot::convex_ind_ct &ind_ct,
-    bgeot::base_vector &val) const{
-      base_node pt_2d(pt);
-      pt_2d.resize(2);
-      poriginal_trans_->poly_vector_val(pt_2d, ind_ct, val);     
-  }
-
-  void torus_geom_trans::poly_vector_grad(const base_node &pt, bgeot::base_matrix &pc) const{
-    base_node pt2D(pt);
-    pt2D.resize(2);
-    bgeot::base_matrix pc2D(nb_points(), 2);
-    poriginal_trans_->poly_vector_grad(pt2D, pc2D);
-
-    bgeot::base_vector base_value;
-    poriginal_trans_->poly_vector_val(pt2D, base_value);
-
-    pc.resize(nb_points(), 3);
-
-    for (size_type i = 0; i < nb_points(); ++i){
-      for (bgeot::dim_type n = 0; n < 2; ++n) pc(i, n) = pc2D(i, n);
-      pc(i, 2) = base_value[i]; // radial direction, pc = base_x;
-    }
-  }
-
-  void torus_geom_trans::poly_vector_grad(const base_node &pt,
-    const bgeot::convex_ind_ct &ind_ct, bgeot::base_matrix &pc) const{
-      base_node pt2D(pt);
-      pt2D.resize(2);
-      bgeot::base_matrix pc2D(ind_ct.size(), 2);
-      poriginal_trans_->poly_vector_grad(pt2D, pc2D);
-      pc.resize(ind_ct.size(), dim());
-      for (size_type i = 0; i < ind_ct.size(); ++i){
-        for (bgeot::dim_type n = 0; n < 2; ++n) pc(i, n) = pc2D(i, n);
-      }
-  }
-
-  void torus_geom_trans::compute_K_matrix
-    (const bgeot::base_matrix &G, const bgeot::base_matrix &pc, bgeot::base_matrix &K) const{
-      bgeot::geometric_trans::compute_K_matrix(G, pc, K);
-      K(2, 2) = 0.0;
-      for (short_type j = 0; j < nb_points(); ++ j) K(2, 2) += G(0, j) * pc(j, 2);
-      for (short_type i = 0; i < 2; ++i) K(2, i) = K(i, 2) = 0;
-  }
-
-  void torus_geom_trans::poly_vector_hess(const base_node & /*pt*/,
-                                          bgeot::base_matrix & /*pc*/) const{
-    GMM_ASSERT1(false, "Sorry, Hessian is not supported in axisymmetric transformation.");
-  }
-
-  torus_geom_trans::torus_geom_trans(pgeometric_trans poriginal_trans) 
-    : poriginal_trans_(poriginal_trans){
-      geometric_trans::is_lin = poriginal_trans_->is_linear();
-      geometric_trans::cvr = ptorus_reference(poriginal_trans_->convex_ref());
-      complexity_ = poriginal_trans_->complexity();
-      fill_standard_vertices();
-  }
-
-  pgeometric_trans torus_geom_trans::get_original_transformation() const{
-    return poriginal_trans_;
-  }
-
-  bool is_torus_structure(pconvex_structure cvs){
-    const torus_structure *cvs_torus = dynamic_cast<const torus_structure *>(cvs.get());
-    return cvs_torus != NULL;
-  }
-
-  DAL_SIMPLE_KEY(torus_geom_trans_key, pgeometric_trans);
-
-  pgeometric_trans torus_geom_trans_descriptor(pgeometric_trans poriginal_trans){
-    dal::pstatic_stored_object_key
-      pk = std::make_shared<torus_geom_trans_key>(poriginal_trans);
-    dal::pstatic_stored_object o = dal::search_stored_object(pk);
-
-    if (o) return std::dynamic_pointer_cast<const torus_geom_trans>(o);
-
-    bgeot::pgeometric_trans p = std::make_shared<torus_geom_trans>(poriginal_trans);
-    dal::add_stored_object(pk, p, dal::PERMANENT_STATIC_OBJECT);
-    return p;
-  }
-
-  bool is_torus_geom_trans(pgeometric_trans pgt){
-    const torus_geom_trans *pgt_torus = dynamic_cast<const torus_geom_trans *>(pgt.get());
-    return pgt_torus != NULL;
-  }
-}
-
-namespace getfem
-{
-
-  void torus_fem::init(){
-    cvr = poriginal_fem_->ref_convex(0);
-    dim_ = cvr->structure()->dim();
-    is_equiv = real_element_defined = true;
-    is_pol = poriginal_fem_->is_polynomial();
-    is_polycomp = poriginal_fem_->is_polynomialcomp();
-    is_lag = poriginal_fem_->is_lagrange();
-    es_degree = poriginal_fem_->estimated_degree();
-    ntarget_dim = 3;
-
-    std::stringstream nm;
-    nm << "FEM_TORUS(" << poriginal_fem_->debug_name() << ")";
-    debug_name_ = nm.str();
-
-    init_cvs_node();
-    GMM_ASSERT1(poriginal_fem_->target_dim() == 1, "Vectorial fems not supported");
-    size_type nb_dof_origin = poriginal_fem_->nb_dof(0);
-    for (size_type k = 0; k < nb_dof_origin; ++k)
-    {
-      for(size_type j = 0; j < 2; ++j){
-        add_node(xfem_dof(poriginal_fem_->dof_types()[k], j), 
-          poriginal_fem_->node_of_dof(0, k));
-      }
-    }
-  }
-
-  size_type torus_fem::index_of_global_dof
-    (size_type /*cv*/, size_type i) const
-  { return i; }
-
-  void torus_fem::base_value(const base_node &, base_tensor &) const
-  { GMM_ASSERT1(false, "No base values, real only element."); }
-
-  void torus_fem::grad_base_value(const base_node &, base_tensor &) const
-  { GMM_ASSERT1(false, "No grad values, real only element."); }
-
-  void torus_fem::hess_base_value(const base_node &, base_tensor &) const{ 
-    GMM_ASSERT1(false, "No hess values, real only element.");
-  }
-
-  void torus_fem::real_base_value(const fem_interpolation_context& c,
-    base_tensor &t, bool) const{
-
-    GMM_ASSERT1(!(poriginal_fem_->is_on_real_element()), "Original FEM must not be real.");
-
-    base_tensor u_orig;
-    poriginal_fem_->base_value(c.xref(), u_orig);
-    if (!(poriginal_fem_->is_equivalent())){ 
-      base_tensor u_temp = u_orig; 
-      u_orig.mat_transp_reduction(u_temp, c.M(), 0); 
-    }
-
-    if(is_scalar_){
-      t = u_orig;
-      return;
-    }
-
-    //expand original base of [nb_base, 1] 
-    //to vectorial form [nb_base * dim_, dim_ + 1]
-    bgeot::multi_index tensor_size(u_orig.sizes());
-    tensor_size[0] *= dim_;
-    tensor_size[1] = ntarget_dim;
-    t.adjust_sizes(tensor_size);
-    for (size_type i = 0; i < u_orig.sizes()[0]; ++i) {
-      for (dim_type j = 0; j < dim_; ++j) {
-        t(i*dim_ + j, j) = u_orig(i, 0);
-      }
-    }
-  }
-
-  void torus_fem::real_grad_base_value
-    (const getfem::fem_interpolation_context& c, base_tensor &t, bool) const 
-  {
-    GMM_ASSERT1(!(poriginal_fem_->is_on_real_element()), "Original FEM must not be real.");
-
-    bgeot::scalar_type radius = c.xreal()[0];
-    GMM_ASSERT1(radius > 0, "Negative radius in axisymmetry gradient calculation!");
-
-    base_tensor u;
-    bgeot::pstored_point_tab ppt = c.pgp()->get_ppoint_tab();
-    getfem::pfem_precomp pfp = getfem::fem_precomp(poriginal_fem_, ppt, 0);
-    base_tensor u_origin = pfp->grad(c.ii());
-    //poriginal_fem_->grad_base_value(c.xref(), u_origin);
-    GMM_ASSERT1(!u_origin.empty(), "Original FEM is unable to provide grad base value!");
-
-    base_tensor n_origin = pfp->val(c.ii());
-    //poriginal_fem_->base_value(c.xref(), n_origin);
-    GMM_ASSERT1(!n_origin.empty(), "Original FEM is unable to provide base value!");
-
-    //expand original grad of [nb_base, 1, dim_] 
-    //to vectorial form [nb_base * dim_, dim_ + 1, dim_ + 1]
-    const bgeot::multi_index &origin_size = u_origin.sizes();
-    bgeot::multi_index tensor_size(origin_size);
-    dim_type dim_size = is_scalar_ ? 1 : dim_;
-    tensor_size[0] *= dim_size;
-    tensor_size[1] = ntarget_dim;
-    tensor_size[2] = dim_ + 1;
-    u.adjust_sizes(tensor_size);
-    for (size_type i = 0; i < origin_size[0]; ++i) { //dof
-      for (dim_type j = 0; j < dim_size; ++j) {
-        for (dim_type k = 0; k < dim_; ++k) {
-          u(i*dim_size+j, j, k) = u_origin(i, 0, k);
-        }
-      }
-    }
-    t = u;
-    t.mat_transp_reduction(u, c.B(), 2);
-
-    if(is_scalar_) return;
-
-    for (size_type i = 0; i < origin_size[0]; ++i) {
-      t(i*dim_size, dim_, dim_) = n_origin[i] / radius;
-    }
-  }
-
-  void torus_fem::real_hess_base_value
-    (const getfem::fem_interpolation_context & /*c*/, base_tensor & /*t*/, bool) const 
-  {
-    GMM_ASSERT1(false, "Hessian not yet implemented in torus fem.");
-  }
-
-  void torus_fem::set_to_scalar(bool is_scalar){
-    if(is_scalar_ == is_scalar) return;
-    
-    is_scalar_ = is_scalar;
-
-    if(is_scalar_){
-      ntarget_dim = 1;
-      dof_types_.clear();
-      init_cvs_node();
-      size_type nb_dof_origin = poriginal_fem_->nb_dof(0);
-      for (size_type k = 0; k < nb_dof_origin; ++k){
-          add_node(poriginal_fem_->dof_types()[k], poriginal_fem_->node_of_dof(0, k));
-      }
-    }else{
-      ntarget_dim = 3;
-      dof_types_.clear();
-      init_cvs_node();
-      size_type nb_dof_origin = poriginal_fem_->nb_dof(0);
-      for (size_type k = 0; k < nb_dof_origin; ++k)
-      {
-        for(size_type j = 0; j < 2; ++j){
-          add_node(xfem_dof(poriginal_fem_->dof_types()[k], j), 
-            poriginal_fem_->node_of_dof(0, k));
-        }
-      }
-    }
-  }
-
-  pfem torus_fem::get_original_pfem() const{return poriginal_fem_;}
-
-  DAL_SIMPLE_KEY(torus_fem_key, bgeot::size_type);
-
-  getfem::pfem new_torus_fem(getfem::pfem pf) {
-    static bgeot::size_type key_count = 0;
-    ++key_count;
-    getfem::pfem pfem_torus = std::make_shared<torus_fem>(pf);
-    dal::pstatic_stored_object_key
-      pk = std::make_shared<torus_fem_key>(key_count);
-    dal::add_stored_object(pk, pfem_torus, pfem_torus->node_tab(0));
-    return pfem_torus;
-  }
-
-  void del_torus_fem(getfem::pfem pf){
-    const torus_fem *ptorus_fem = dynamic_cast<const torus_fem*>(pf.get());
-    if (ptorus_fem != 0) dal::del_stored_object(pf);
-  }
-
-  void torus_mesh_fem::adapt_to_torus_(){
-
-    for (dal::bv_visitor cv(linked_mesh().convex_index()); !cv.finished(); ++cv){
-      pfem poriginal_fem = fem_of_element(cv);
-      if(poriginal_fem == 0) continue;
-
-      del_torus_fem(poriginal_fem);
-
-      pfem pf = new_torus_fem(poriginal_fem);
-      torus_fem *pf_torus = dynamic_cast<torus_fem*>(const_cast<virtual_fem*>(pf.get()));
-      pf_torus->set_to_scalar((Qdim != 3));
-      set_finite_element(cv, pf);
-    }
-    touch();
-  }
-
-  void torus_mesh_fem::enumerate_dof(void) const
-  {
-    const_cast<torus_mesh_fem*>(this)->adapt_to_torus_();
-
-    for (dal::bv_visitor cv(linked_mesh().convex_index()); !cv.finished(); ++cv){
-      pfem pf = fem_of_element(cv);
-      if(pf == 0) continue;
-      torus_fem *pf_torus = dynamic_cast<torus_fem*>(const_cast<virtual_fem*>(pf.get()));
-      if(pf_torus == 0) continue;
-      pf_torus->set_to_scalar((Qdim != 3));
-    }
-
-    mesh_fem::enumerate_dof();
-  }
-
-  torus_mesh::torus_mesh(std::string name) : mesh(std::move(name)){}
-
-  scalar_type torus_mesh::convex_radius_estimate(size_type ic) const
-  {
-    base_matrix G;
-    bgeot::vectors_to_base_matrix(G, points_of_convex(ic));
-    G.resize(2, G.ncols());
-    auto pgt_torus = std::dynamic_pointer_cast<const bgeot::torus_geom_trans>(trans_of_convex(ic));
-    GMM_ASSERT2(pgt_torus, "Internal error, convex is not a torus transformation.");
-    return getfem::convex_radius_estimate(pgt_torus->get_original_transformation(), G);
-  }
-
-  void torus_mesh::adapt(const getfem::mesh &original_mesh){
-    clear();
-    GMM_ASSERT1(original_mesh.dim() == 2, "Adapting torus feature must be a 2d mesh");
-    mesh::copy_from(original_mesh);
-    adapt();
-  }
-
-  void torus_mesh::adapt(){
-
-    bgeot::node_tab node_tab_copy(pts);
-    this->pts.clear();
-    for(size_type pt = 0; pt < node_tab_copy.size(); ++pt){
-      node_tab_copy[pt].resize(3);
-      this->pts.add_node(node_tab_copy[pt]);
-    }
-
-    for(size_type i = 0; i < this->convex_tab.size(); ++i){
-      bgeot::pconvex_structure pstructure 
-        = bgeot::torus_structure_descriptor(convex_tab[i].cstruct);
-      convex_tab[i].cstruct = pstructure;
-    }
-
-    for(size_type i = 0; i < this->gtab.size(); ++i){
-      bgeot::pgeometric_trans pgeom_trans = bgeot::torus_geom_trans_descriptor(gtab[i]);
-      gtab[i] = pgeom_trans;
-    }
-  }
-}
+
+#include "getfem/getfem_torus.h"
+
+namespace bgeot{
+
+  /**torus_structure which extends a 2 dimensional structure with a radial dimension*/
+  class torus_structure : public convex_structure{
+
+    friend pconvex_structure torus_structure_descriptor(pconvex_structure);
+  };
+
+  class torus_reference : public convex_of_reference{
+
+  public :
+    scalar_type is_in(const base_node& point) const{
+      GMM_ASSERT1(point.size() >= 2, "Invalid dimension of pt " << point);
+      base_node point_2d = point;
+      point_2d.resize(2);
+      return ori_ref_convex_->is_in(point_2d);
+    }
+
+    scalar_type is_in_face(bgeot::short_type f, const base_node& point) const{
+      GMM_ASSERT1(point.size() >= 2, "Invalid dimension of pt " << point);
+      base_node point2D = point;
+      point2D.resize(2);
+      return ori_ref_convex_->is_in_face(f, point2D);
+    }  
+    torus_reference(bgeot::pconvex_ref ori_ref_convex){
+      ori_ref_convex_ = ori_ref_convex;
+      cvs = torus_structure_descriptor(ori_ref_convex->structure());
+      convex<base_node>::points().resize(cvs->nb_points());
+      normals_.resize(ori_ref_convex->normals().size());
+
+      const std::vector<base_small_vector> &ori_normals = ori_ref_convex->normals();
+      const stored_point_tab &ori_points = ori_ref_convex->points();
+      for(size_type n = 0; n < ori_normals.size(); ++n){
+       normals_[n] = ori_normals[n];
+       normals_[n].resize(3);
+      }            
+
+      std::copy(ori_points.begin(), ori_points.end(), convex<base_node>::points().begin());
+      for(size_type pt = 0; pt < convex<base_node>::points().size(); ++pt){
+        convex<base_node>::points()[pt].resize(3);
+      }
+      ppoints = store_point_tab(convex<base_node>::points());
+    }
+
+  private:
+    bgeot::pconvex_ref ori_ref_convex_;
+  };
+
+  DAL_SIMPLE_KEY(torus_structure_key, pconvex_structure);
+
+  pconvex_structure torus_structure_descriptor(pconvex_structure ori_structure){
+
+    dal::pstatic_stored_object_key
+      pk = std::make_shared<torus_structure_key>(ori_structure);
+    dal::pstatic_stored_object o = dal::search_stored_object(pk);
+    if (o) return std::dynamic_pointer_cast<const convex_structure>(o);
+
+    auto p = std::make_shared<torus_structure>();
+    pconvex_structure pcvs(p);
+    p->Nc = dim_type(ori_structure->dim() + 1);
+    p->nbpt = ori_structure->nb_points();
+    p->nbf = ori_structure->nb_faces();
+
+    p->faces_struct.resize(p->nbf);
+    p->faces.resize(p->nbf);
+
+    for (short_type j = 0; j < p->nbf; ++j){
+      p->faces_struct[j] = ori_structure->faces_structure()[j];
+      short_type nbIndex = ori_structure->nb_points_of_face(j);
+      p->faces[j].resize(nbIndex);
+      p->faces[j] = ori_structure->ind_points_of_face(j);
+    }
+
+    p->dir_points_.resize(ori_structure->ind_dir_points().size());
+    p->dir_points_ = ori_structure->ind_dir_points();
+
+    p->basic_pcvs = basic_structure(ori_structure);
+
+    dal::add_stored_object(pk, pcvs, dal::PERMANENT_STATIC_OBJECT);
+    return pcvs;
+  }
+
+  DAL_SIMPLE_KEY(torus_reference_key, pconvex_ref);
+
+  pconvex_ref ptorus_reference(pconvex_ref ori_convex_reference)
+  {
+    dal::pstatic_stored_object_key
+      pk = std::make_shared<torus_reference_key>(ori_convex_reference);
+    dal::pstatic_stored_object o = dal::search_stored_object(pk);
+
+    if (o) return std::dynamic_pointer_cast<const bgeot::convex_of_reference>(o);
+    pconvex_ref p = std::make_shared<torus_reference>(ori_convex_reference);
+    dal::add_stored_object(pk, p, p->structure(), p->pspt(),
+			   dal::PERMANENT_STATIC_OBJECT);
+    return p;
+  }
+
+  void torus_geom_trans::poly_vector_val(const base_node &pt, bgeot::base_vector &val) const{
+    base_node pt_2d(pt);
+    pt_2d.resize(2);
+    poriginal_trans_->poly_vector_val(pt_2d, val);
+  }
+
+  void torus_geom_trans::poly_vector_val(const base_node &pt, const bgeot::convex_ind_ct &ind_ct,
+    bgeot::base_vector &val) const{
+      base_node pt_2d(pt);
+      pt_2d.resize(2);
+      poriginal_trans_->poly_vector_val(pt_2d, ind_ct, val);     
+  }
+
+  void torus_geom_trans::poly_vector_grad(const base_node &pt, bgeot::base_matrix &pc) const{
+    base_node pt2D(pt);
+    pt2D.resize(2);
+    bgeot::base_matrix pc2D(nb_points(), 2);
+    poriginal_trans_->poly_vector_grad(pt2D, pc2D);
+
+    bgeot::base_vector base_value;
+    poriginal_trans_->poly_vector_val(pt2D, base_value);
+
+    pc.resize(nb_points(), 3);
+
+    for (size_type i = 0; i < nb_points(); ++i){
+      for (bgeot::dim_type n = 0; n < 2; ++n) pc(i, n) = pc2D(i, n);
+      pc(i, 2) = base_value[i]; // radial direction, pc = base_x;
+    }
+  }
+
+  void torus_geom_trans::poly_vector_grad(const base_node &pt,
+    const bgeot::convex_ind_ct &ind_ct, bgeot::base_matrix &pc) const{
+      base_node pt2D(pt);
+      pt2D.resize(2);
+      bgeot::base_matrix pc2D(ind_ct.size(), 2);
+      poriginal_trans_->poly_vector_grad(pt2D, pc2D);
+      pc.resize(ind_ct.size(), dim());
+      for (size_type i = 0; i < ind_ct.size(); ++i){
+        for (bgeot::dim_type n = 0; n < 2; ++n) pc(i, n) = pc2D(i, n);
+      }
+  }
+
+  void torus_geom_trans::compute_K_matrix
+    (const bgeot::base_matrix &G, const bgeot::base_matrix &pc, bgeot::base_matrix &K) const{
+      bgeot::geometric_trans::compute_K_matrix(G, pc, K);
+      K(2, 2) = 0.0;
+      for (short_type j = 0; j < nb_points(); ++ j) K(2, 2) += G(0, j) * pc(j, 2);
+      for (short_type i = 0; i < 2; ++i) K(2, i) = K(i, 2) = 0;
+  }
+
+  void torus_geom_trans::poly_vector_hess(const base_node & /*pt*/,
+                                          bgeot::base_matrix & /*pc*/) const{
+    GMM_ASSERT1(false, "Sorry, Hessian is not supported in axisymmetric transformation.");
+  }
+
+  torus_geom_trans::torus_geom_trans(pgeometric_trans poriginal_trans) 
+    : poriginal_trans_(poriginal_trans){
+      geometric_trans::is_lin = poriginal_trans_->is_linear();
+      geometric_trans::cvr = ptorus_reference(poriginal_trans_->convex_ref());
+      complexity_ = poriginal_trans_->complexity();
+      fill_standard_vertices();
+  }
+
+  pgeometric_trans torus_geom_trans::get_original_transformation() const{
+    return poriginal_trans_;
+  }
+
+  bool is_torus_structure(pconvex_structure cvs){
+    const torus_structure *cvs_torus = dynamic_cast<const torus_structure *>(cvs.get());
+    return cvs_torus != NULL;
+  }
+
+  DAL_SIMPLE_KEY(torus_geom_trans_key, pgeometric_trans);
+
+  pgeometric_trans torus_geom_trans_descriptor(pgeometric_trans poriginal_trans){
+    dal::pstatic_stored_object_key
+      pk = std::make_shared<torus_geom_trans_key>(poriginal_trans);
+    dal::pstatic_stored_object o = dal::search_stored_object(pk);
+
+    if (o) return std::dynamic_pointer_cast<const torus_geom_trans>(o);
+
+    bgeot::pgeometric_trans p = std::make_shared<torus_geom_trans>(poriginal_trans);
+    dal::add_stored_object(pk, p, dal::PERMANENT_STATIC_OBJECT);
+    return p;
+  }
+
+  bool is_torus_geom_trans(pgeometric_trans pgt){
+    const torus_geom_trans *pgt_torus = dynamic_cast<const torus_geom_trans *>(pgt.get());
+    return pgt_torus != NULL;
+  }
+}
+
+namespace getfem
+{
+
+  void torus_fem::init(){
+    cvr = poriginal_fem_->ref_convex(0);
+    dim_ = cvr->structure()->dim();
+    is_standard_fem = false;
+    is_equiv = real_element_defined = true;
+    is_pol = poriginal_fem_->is_polynomial();
+    is_polycomp = poriginal_fem_->is_polynomialcomp();
+    is_lag = poriginal_fem_->is_lagrange();
+    es_degree = poriginal_fem_->estimated_degree();
+    ntarget_dim = 3;
+
+    std::stringstream nm;
+    nm << "FEM_TORUS(" << poriginal_fem_->debug_name() << ")";
+    debug_name_ = nm.str();
+
+    init_cvs_node();
+    GMM_ASSERT1(poriginal_fem_->target_dim() == 1, "Vectorial fems not supported");
+    size_type nb_dof_origin = poriginal_fem_->nb_dof(0);
+    for (size_type k = 0; k < nb_dof_origin; ++k)
+    {
+      for(size_type j = 0; j < 2; ++j){
+        add_node(xfem_dof(poriginal_fem_->dof_types()[k], j), 
+          poriginal_fem_->node_of_dof(0, k));
+      }
+    }
+  }
+
+  size_type torus_fem::index_of_global_dof
+    (size_type /*cv*/, size_type i) const
+  { return i; }
+
+  void torus_fem::base_value(const base_node &, base_tensor &) const
+  { GMM_ASSERT1(false, "No base values, real only element."); }
+
+  void torus_fem::grad_base_value(const base_node &, base_tensor &) const
+  { GMM_ASSERT1(false, "No grad values, real only element."); }
+
+  void torus_fem::hess_base_value(const base_node &, base_tensor &) const{ 
+    GMM_ASSERT1(false, "No hess values, real only element.");
+  }
+
+  void torus_fem::real_base_value(const fem_interpolation_context& c,
+    base_tensor &t, bool) const{
+
+    GMM_ASSERT1(!(poriginal_fem_->is_on_real_element()), "Original FEM must not be real.");
+
+    base_tensor u_orig;
+    poriginal_fem_->base_value(c.xref(), u_orig);
+    if (!(poriginal_fem_->is_equivalent())){ 
+      base_tensor u_temp = u_orig; 
+      u_orig.mat_transp_reduction(u_temp, c.M(), 0); 
+    }
+
+    if(is_scalar_){
+      t = u_orig;
+      return;
+    }
+
+    //expand original base of [nb_base, 1] 
+    //to vectorial form [nb_base * dim_, dim_ + 1]
+    bgeot::multi_index tensor_size(u_orig.sizes());
+    tensor_size[0] *= dim_;
+    tensor_size[1] = ntarget_dim;
+    t.adjust_sizes(tensor_size);
+    for (size_type i = 0; i < u_orig.sizes()[0]; ++i) {
+      for (dim_type j = 0; j < dim_; ++j) {
+        t(i*dim_ + j, j) = u_orig(i, 0);
+      }
+    }
+  }
+
+  void torus_fem::real_grad_base_value
+    (const getfem::fem_interpolation_context& c, base_tensor &t, bool) const 
+  {
+    GMM_ASSERT1(!(poriginal_fem_->is_on_real_element()), "Original FEM must not be real.");
+
+    bgeot::scalar_type radius = std::abs(c.xreal()[0]);
+    base_tensor u;
+    bgeot::pstored_point_tab ppt = c.pgp()->get_ppoint_tab();
+    getfem::pfem_precomp pfp = getfem::fem_precomp(poriginal_fem_, ppt, 0);
+    base_tensor u_origin = pfp->grad(c.ii());
+    //poriginal_fem_->grad_base_value(c.xref(), u_origin);
+    GMM_ASSERT1(!u_origin.empty(), "Original FEM is unable to provide grad base value!");
+
+    base_tensor n_origin = pfp->val(c.ii());
+    //poriginal_fem_->base_value(c.xref(), n_origin);
+    GMM_ASSERT1(!n_origin.empty(), "Original FEM is unable to provide base value!");
+
+    //expand original grad of [nb_base, 1, dim_] 
+    //to vectorial form [nb_base * dim_, dim_ + 1, dim_ + 1]
+    const bgeot::multi_index &origin_size = u_origin.sizes();
+    bgeot::multi_index tensor_size(origin_size);
+    dim_type dim_size = is_scalar_ ? 1 : dim_;
+    tensor_size[0] *= dim_size;
+    tensor_size[1] = ntarget_dim;
+    tensor_size[2] = dim_ + 1;
+    u.adjust_sizes(tensor_size);
+    for (size_type i = 0; i < origin_size[0]; ++i) { //dof
+      for (dim_type j = 0; j < dim_size; ++j) {
+        for (dim_type k = 0; k < dim_; ++k) {
+          u(i*dim_size+j, j, k) = u_origin(i, 0, k);
+        }
+      }
+    }
+    t = u;
+    t.mat_transp_reduction(u, c.B(), 2);
+
+    if(is_scalar_) return;
+
+    for (size_type i = 0; i < origin_size[0]; ++i) {
+      t(i*dim_size, dim_, dim_) = n_origin[i] / radius;
+    }
+  }
+
+  void torus_fem::real_hess_base_value
+    (const getfem::fem_interpolation_context & /*c*/, base_tensor & /*t*/, bool) const 
+  {
+    GMM_ASSERT1(false, "Hessian not yet implemented in torus fem.");
+  }
+
+  void torus_fem::set_to_scalar(bool is_scalar){
+    if(is_scalar_ == is_scalar) return;
+    
+    is_scalar_ = is_scalar;
+
+    if(is_scalar_){
+      ntarget_dim = 1;
+      dof_types_.clear();
+      init_cvs_node();
+      size_type nb_dof_origin = poriginal_fem_->nb_dof(0);
+      for (size_type k = 0; k < nb_dof_origin; ++k){
+          add_node(poriginal_fem_->dof_types()[k], poriginal_fem_->node_of_dof(0, k));
+      }
+    }else{
+      ntarget_dim = 3;
+      dof_types_.clear();
+      init_cvs_node();
+      size_type nb_dof_origin = poriginal_fem_->nb_dof(0);
+      for (size_type k = 0; k < nb_dof_origin; ++k)
+      {
+        for(size_type j = 0; j < 2; ++j){
+          add_node(xfem_dof(poriginal_fem_->dof_types()[k], j), 
+            poriginal_fem_->node_of_dof(0, k));
+        }
+      }
+    }
+  }
+
+  pfem torus_fem::get_original_pfem() const{return poriginal_fem_;}
+
+  DAL_SIMPLE_KEY(torus_fem_key, bgeot::size_type);
+
+  getfem::pfem new_torus_fem(getfem::pfem pf) {
+    static bgeot::size_type key_count = 0;
+    ++key_count;
+    getfem::pfem pfem_torus = std::make_shared<torus_fem>(pf);
+    dal::pstatic_stored_object_key
+      pk = std::make_shared<torus_fem_key>(key_count);
+    dal::add_stored_object(pk, pfem_torus, pfem_torus->node_tab(0));
+    return pfem_torus;
+  }
+
+  void del_torus_fem(getfem::pfem pf){
+    const torus_fem *ptorus_fem = dynamic_cast<const torus_fem*>(pf.get());
+    if (ptorus_fem != 0) dal::del_stored_object(pf);
+  }
+
+  void torus_mesh_fem::adapt_to_torus_(){
+
+    for (dal::bv_visitor cv(linked_mesh().convex_index()); !cv.finished(); ++cv){
+      pfem poriginal_fem = fem_of_element(cv);
+      if(poriginal_fem == 0) continue;
+
+      del_torus_fem(poriginal_fem);
+
+      pfem pf = new_torus_fem(poriginal_fem);
+      torus_fem *pf_torus = dynamic_cast<torus_fem*>(const_cast<virtual_fem*>(pf.get()));
+      pf_torus->set_to_scalar((Qdim != 3));
+      set_finite_element(cv, pf);
+    }
+    touch();
+  }
+
+  void torus_mesh_fem::enumerate_dof(void) const
+  {
+    const_cast<torus_mesh_fem*>(this)->adapt_to_torus_();
+
+    for (dal::bv_visitor cv(linked_mesh().convex_index()); !cv.finished(); ++cv){
+      pfem pf = fem_of_element(cv);
+      if(pf == 0) continue;
+      torus_fem *pf_torus = dynamic_cast<torus_fem*>(const_cast<virtual_fem*>(pf.get()));
+      if(pf_torus == 0) continue;
+      pf_torus->set_to_scalar((Qdim != 3));
+    }
+
+    mesh_fem::enumerate_dof();
+  }
+
+  torus_mesh::torus_mesh(std::string name) : mesh(std::move(name)){}
+
+  scalar_type torus_mesh::convex_radius_estimate(size_type ic) const
+  {
+    base_matrix G;
+    bgeot::vectors_to_base_matrix(G, points_of_convex(ic));
+    G.resize(2, G.ncols());
+    auto pgt_torus = std::dynamic_pointer_cast<const bgeot::torus_geom_trans>(trans_of_convex(ic));
+    GMM_ASSERT2(pgt_torus, "Internal error, convex is not a torus transformation.");
+    return getfem::convex_radius_estimate(pgt_torus->get_original_transformation(), G);
+  }
+
+  void torus_mesh::adapt(const getfem::mesh &original_mesh){
+    clear();
+    GMM_ASSERT1(original_mesh.dim() == 2, "Adapting torus feature must be a 2d mesh");
+    mesh::copy_from(original_mesh);
+    adapt();
+  }
+
+  void torus_mesh::adapt(){
+
+    bgeot::node_tab node_tab_copy(pts);
+    this->pts.clear();
+    for(size_type pt = 0; pt < node_tab_copy.size(); ++pt){
+      node_tab_copy[pt].resize(3);
+      this->pts.add_node(node_tab_copy[pt]);
+    }
+
+    for(size_type i = 0; i < this->convex_tab.size(); ++i){
+      bgeot::pconvex_structure pstructure 
+        = bgeot::torus_structure_descriptor(convex_tab[i].cstruct);
+      convex_tab[i].cstruct = pstructure;
+    }
+
+    for(size_type i = 0; i < this->gtab.size(); ++i){
+      bgeot::pgeometric_trans pgeom_trans = bgeot::torus_geom_trans_descriptor(gtab[i]);
+      gtab[i] = pgeom_trans;
+    }
+  }
+}
diff --git a/src/gmm/gmm.h b/src/gmm/gmm.h
index 5bb0ce0..feeb299 100644
--- a/src/gmm/gmm.h
+++ b/src/gmm/gmm.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_MUMPS_interface.h b/src/gmm/gmm_MUMPS_interface.h
index 26edc05..bc68777 100644
--- a/src/gmm/gmm_MUMPS_interface.h
+++ b/src/gmm/gmm_MUMPS_interface.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2003-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_algobase.h b/src/gmm/gmm_algobase.h
index b376a97..64a859d 100644
--- a/src/gmm/gmm_algobase.h
+++ b/src/gmm/gmm_algobase.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -110,7 +110,9 @@ namespace gmm {
     int i;
     for ( ; b1 != e1 && b2 != e2; ++b1, ++b2)
       if ((i = c(*b1, *b2)) != 0) return i;
-    if (b1 != e1) return 1; if (b2 != e2) return -1; return 0; 
+    if (b1 != e1) return 1;
+    if (b2 != e2) return -1;
+    return 0; 
   }
 
   template<class CONT, class COMP = gmm::less<typename CONT::value_type> >
diff --git a/src/gmm/gmm_blas.h b/src/gmm/gmm_blas.h
index a9b7fab..b237355 100644
--- a/src/gmm/gmm_blas.h
+++ b/src/gmm/gmm_blas.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -691,7 +691,7 @@ namespace gmm {
     
     std::vector<R> aux(mat_ncols(m));
     for (size_type i = 0; i < mat_nrows(m); ++i) {
-      auto row = mat_const_row(m, i);
+      typename linalg_traits<M>::const_sub_row_type row = mat_const_row(m, i);
       auto it = vect_const_begin(row), ite = vect_const_end(row);
       for (size_type k = 0; it != ite; ++it, ++k)
 	aux[index_of_it(it, k, store_type())] += gmm::abs(*it);
@@ -745,7 +745,7 @@ namespace gmm {
     
     std::vector<R> aux(mat_nrows(m));
     for (size_type i = 0; i < mat_ncols(m); ++i) {
-      auto col = mat_const_col(m, i);
+      typename linalg_traits<M>::const_sub_col_type col = mat_const_col(m, i);
       auto it = vect_const_begin(col), ite = vect_const_end(col);
       for (size_type k = 0; it != ite; ++it, ++k)
 	aux[index_of_it(it, k, store_type())] += gmm::abs(*it);
@@ -950,18 +950,14 @@ namespace gmm {
   void copy_mat_by_row(const L1& l1, L2& l2) {
     size_type nbr = mat_nrows(l1);
     for (size_type i = 0; i < nbr; ++i)
-      copy_vect(mat_const_row(l1, i), mat_row(l2, i),
-      		typename linalg_traits<L1>::storage_type(),
-		typename linalg_traits<L2>::storage_type());
+      copy(mat_const_row(l1, i), mat_row(l2, i));
   }
 
   template <typename L1, typename L2>
   void copy_mat_by_col(const L1 &l1, L2 &l2) {
     size_type nbc = mat_ncols(l1);
     for (size_type i = 0; i < nbc; ++i) {
-      copy_vect(mat_const_col(l1, i), mat_col(l2, i),
-      		typename linalg_traits<L1>::storage_type(),
-		typename linalg_traits<L2>::storage_type());
+      copy(mat_const_col(l1, i), mat_col(l2, i));
     }
   }
 
@@ -1156,9 +1152,13 @@ namespace gmm {
   void copy_vect(const L1& l1, L2& l2, abstract_sparse, abstract_sparse) {
     auto  it  = vect_const_begin(l1), ite = vect_const_end(l1);
     clear(l2);
-    for (; it != ite; ++it)
+    // cout << "copy " << l1 << " of size " << vect_size(l1) << " nnz = " << nnz(l1) << endl;
+    for (; it != ite; ++it) {
+      // cout << "*it = " << *it << endl;
+      // cout << "it.index() = " << it.index() << endl;
       if (*it != (typename linalg_traits<L1>::value_type)(0))
 	l2[it.index()] = *it;
+    }
   }
   
   template <typename L1, typename L2>
@@ -1220,7 +1220,9 @@ namespace gmm {
   template <typename L1, typename L2> inline
     void add_spec(const L1& l1, L2& l2, abstract_matrix) {
     GMM_ASSERT2(mat_nrows(l1)==mat_nrows(l2) && mat_ncols(l1)==mat_ncols(l2),
-                "dimensions mismatch");
+                "dimensions mismatch l1 is " << mat_nrows(l1) << "x"
+		<< mat_ncols(l1) << " and l2 is " << mat_nrows(l2)
+		<< "x" << mat_ncols(l2));
     add(l1, l2, typename linalg_traits<L1>::sub_orientation(),
 	typename linalg_traits<L2>::sub_orientation());
   }
@@ -1950,7 +1952,7 @@ namespace gmm {
       size_type i,j, k = mat_nrows(l1);
       
       for (i = 0; i < k; ++i) {
-	auto r1=mat_const_row(l1, i);
+	typename linalg_traits<L1>::const_sub_row_type r1=mat_const_row(l1, i);
 	for (it2 = it2b, j = 0; it2 != ite; ++it2, ++j)
 	  l3(i,j) = vect_sp(r1, linalg_traits<L2>::col(it2));
       }
@@ -1982,7 +1984,7 @@ namespace gmm {
     clear(l3);
     size_type nn = mat_nrows(l3);
     for (size_type i = 0; i < nn; ++i) {
-      auto rl1 = mat_const_row(l1, i);
+      typename linalg_traits<L1>::const_sub_row_type rl1=mat_const_row(l1, i);
       auto it = vect_const_begin(rl1), ite = vect_const_end(rl1);
       for (; it != ite; ++it)
 	add(scaled(mat_const_row(l2, it.index()), *it), mat_row(l3, i));
@@ -2024,7 +2026,7 @@ namespace gmm {
     clear(l3);
     size_type nn = mat_ncols(l3);
     for (size_type i = 0; i < nn; ++i) {
-      auto rc2 = mat_const_col(l2, i);
+      typename linalg_traits<L2>::const_sub_col_type rc2 = mat_const_col(l2, i);
       auto it = vect_const_begin(rc2), ite = vect_const_end(rc2);
       for (; it != ite; ++it)
 	add(scaled(mat_const_col(l1, it.index()), *it), mat_col(l3, i));
@@ -2075,7 +2077,7 @@ namespace gmm {
     clear(l3);
     size_type nn = mat_ncols(l1);
     for (size_type i = 0; i < nn; ++i) {
-      auto rc1 = mat_const_col(l1, i);
+      typename linalg_traits<L1>::const_sub_col_type rc1 = mat_const_col(l1, i);
       auto it = vect_const_begin(rc1), ite = vect_const_end(rc1);
       for (; it != ite; ++it)
 	add(scaled(mat_const_row(l2, i), *it), mat_row(l3, it.index()));
@@ -2127,7 +2129,7 @@ namespace gmm {
   bool is_symmetric(const MAT &A, magnitude_of_linalg(MAT) tol, 
 		    row_major) {
     for (size_type i = 0; i < mat_nrows(A); ++i) {
-      auto row = mat_const_row(A, i);
+      typename linalg_traits<MAT>::const_sub_row_type row = mat_const_row(A, i);
       auto it = vect_const_begin(row), ite = vect_const_end(row);
       for (; it != ite; ++it)
 	if (gmm::abs(*it - A(it.index(), i)) > tol) return false;
@@ -2139,7 +2141,7 @@ namespace gmm {
   bool is_symmetric(const MAT &A, magnitude_of_linalg(MAT) tol, 
 		    col_major) {
     for (size_type i = 0; i < mat_ncols(A); ++i) {
-      auto col = mat_const_col(A, i);
+      typename linalg_traits<MAT>::const_sub_col_type col = mat_const_col(A, i);
       auto it = vect_const_begin(col), ite = vect_const_end(col);
       for (; it != ite; ++it)
 	if (gmm::abs(*it - A(i, it.index())) > tol) return false;
@@ -2188,7 +2190,7 @@ namespace gmm {
   bool is_hermitian(const MAT &A, magnitude_of_linalg(MAT) tol, 
 		    row_major) {
     for (size_type i = 0; i < mat_nrows(A); ++i) {
-      auto row = mat_const_row(A, i);
+      typename linalg_traits<MAT>::const_sub_row_type row = mat_const_row(A, i);
       auto it = vect_const_begin(row), ite = vect_const_end(row);
       for (; it != ite; ++it)
 	if (gmm::abs(gmm::conj(*it) - A(it.index(), i)) > tol) return false;
@@ -2200,7 +2202,7 @@ namespace gmm {
   bool is_hermitian(const MAT &A, magnitude_of_linalg(MAT) tol, 
 		    col_major) {
     for (size_type i = 0; i < mat_ncols(A); ++i) {
-      auto col = mat_const_col(A, i);
+      typename linalg_traits<MAT>::const_sub_col_type col = mat_const_col(A, i);
       auto it = vect_const_begin(col), ite = vect_const_end(col);
       for (; it != ite; ++it)
 	if (gmm::abs(gmm::conj(*it) - A(i, it.index())) > tol) return false;
diff --git a/src/gmm/gmm_blas_interface.h b/src/gmm/gmm_blas_interface.h
index 407c733..c41ae95 100644
--- a/src/gmm/gmm_blas_interface.h
+++ b/src/gmm/gmm_blas_interface.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -47,6 +47,8 @@
 
 namespace gmm {
 
+  // Use ./configure --enable-blas-interface to activate this interface.
+
 #define GMMLAPACK_TRACE(f) 
   // #define GMMLAPACK_TRACE(f) cout << "function " << f << " called" << endl;
 
@@ -168,16 +170,18 @@ namespace gmm {
     void  sger_(...); void  dger_(...); void  cgerc_(...); void  zgerc_(...); 
   }
 
+#if 1
+
   /* ********************************************************************* */
   /* vect_norm2(x).                                                        */
   /* ********************************************************************* */
 
-  # define nrm2_interface(param1, trans1, blas_name, base_type)            \
-  inline number_traits<base_type >::magnitude_type                         \
-    vect_norm2(param1(base_type)) {                                        \
-    GMMLAPACK_TRACE("nrm2_interface");                                     \
-    int inc(1), n(int(vect_size(x))); trans1(base_type);	       	   \
-    return blas_name(&n, &x[0], &inc);                                     \
+# define nrm2_interface(param1, trans1, blas_name, base_type)		   \
+  inline number_traits<base_type >::magnitude_type			   \
+  vect_norm2(param1(base_type)) {					   \
+    GMMLAPACK_TRACE("nrm2_interface");					   \
+    int inc(1), n(int(vect_size(x))); trans1(base_type);		   \
+    return blas_name(&n, &x[0], &inc);					   \
   }
 
 # define nrm2_p1(base_type) const std::vector<base_type > &x
@@ -192,7 +196,7 @@ namespace gmm {
   /* vect_sp(x, y).                                                        */
   /* ********************************************************************* */
 
-  # define dot_interface(param1, trans1, mult1, param2, trans2, mult2,     \
+# define dot_interface(param1, trans1, mult1, param2, trans2, mult2,	   \
                          blas_name, base_type)                             \
   inline base_type vect_sp(param1(base_type), param2(base_type)) {         \
     GMMLAPACK_TRACE("dot_interface");                                      \
@@ -259,8 +263,8 @@ namespace gmm {
   /* vect_hp(x, y).                                                        */
   /* ********************************************************************* */
 
-  # define dotc_interface(param1, trans1, mult1, param2, trans2, mult2,    \
-                         blas_name, base_type)                             \
+# define dotc_interface(param1, trans1, mult1, param2, trans2, mult2,	   \
+			blas_name, base_type)				   \
   inline base_type vect_hp(param1(base_type), param2(base_type)) {         \
     GMMLAPACK_TRACE("dotc_interface");                                     \
     trans1(base_type); trans2(base_type); int inc(1), n(int(vect_size(y)));\
@@ -328,8 +332,8 @@ namespace gmm {
 # define axpy_interface(param1, trans1, blas_name, base_type)              \
   inline void add(param1(base_type), std::vector<base_type > &y) {         \
     GMMLAPACK_TRACE("axpy_interface");                                     \
-    int inc(1), n(int(vect_size(y))); trans1(base_type);                   \
-    if (n == 0) return;                                                    \
+    int inc(1), n(int(vect_size(y))); trans1(base_type);	 	   \
+    if (n == 0) return;							   \
     blas_name(&n, &a, &x[0], &inc, &y[0], &inc);                           \
   }
 
@@ -691,7 +695,7 @@ namespace gmm {
 
 # define gemm_interface_nt(blas_name, base_type, is_const)                 \
   inline void mult_spec(const dense_matrix<base_type > &A,                 \
-         const transposed_col_ref<is_const<base_type > *> &B_,\
+		     const transposed_col_ref<is_const<base_type > *> &B_, \
          dense_matrix<base_type > &C, r_mult) {                            \
     GMMLAPACK_TRACE("gemm_interface_nt");                                  \
     dense_matrix<base_type > &B                                            \
@@ -722,9 +726,9 @@ namespace gmm {
 
 # define gemm_interface_tt(blas_name, base_type, isA_const, isB_const)     \
   inline void mult_spec(                                                   \
-        const transposed_col_ref<isA_const <base_type > *> &A_,\
-        const transposed_col_ref<isB_const <base_type > *> &B_,\
-        dense_matrix<base_type > &C, r_mult) {                             \
+	       const transposed_col_ref<isA_const <base_type > *> &A_,	   \
+               const transposed_col_ref<isB_const <base_type > *> &B_,	   \
+	       dense_matrix<base_type > &C, r_mult) {			   \
     GMMLAPACK_TRACE("gemm_interface_tt");                                  \
     dense_matrix<base_type > &A                                            \
         = const_cast<dense_matrix<base_type > &>(*(linalg_origin(A_)));    \
@@ -936,6 +940,7 @@ namespace gmm {
   trsv_interface(upper_tri_solve, trsv_lower, gem_p1_c, gem_trans1_c,
 		 ztrsv_, BLAS_Z)
   
+#endif
 }
 
 #endif // GMM_BLAS_INTERFACE_H
diff --git a/src/gmm/gmm_condition_number.h b/src/gmm/gmm_condition_number.h
index 3136f15..0dac20e 100644
--- a/src/gmm/gmm_condition_number.h
+++ b/src/gmm/gmm_condition_number.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2003-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
@@ -60,6 +60,10 @@ namespace gmm {
     typedef typename linalg_traits<MAT>::value_type T;
     typedef typename number_traits<T>::magnitude_type R;
 
+    // Added because of errors in complex with zero det
+    if (sizeof(T) != sizeof(R) && gmm::abs(gmm::lu_det(M)) == R(0))
+      return  gmm::default_max(R());
+      
     size_type m = mat_nrows(M), n = mat_ncols(M);
     emax = emin = R(0);
     std::vector<R> eig(m+n);
diff --git a/src/gmm/gmm_conjugated.h b/src/gmm/gmm_conjugated.h
index d10cd1d..1e3e7fc 100644
--- a/src/gmm/gmm_conjugated.h
+++ b/src/gmm/gmm_conjugated.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -195,40 +195,6 @@ namespace gmm {
     { return gmm::conj(linalg_traits<M>::access(begin_+j, i)); }
   };
 
-  template <typename M>
-  struct linalg_traits<conjugated_row_matrix_const_ref<M> > {
-    typedef conjugated_row_matrix_const_ref<M> this_type;
-    typedef typename linalg_traits<M>::origin_type origin_type;
-    typedef linalg_const is_reference;
-    typedef abstract_matrix linalg_type;
-    typedef typename linalg_traits<M>::value_type value_type;
-    typedef value_type reference;
-    typedef typename linalg_traits<M>::storage_type storage_type;
-    typedef typename linalg_traits<M>::const_sub_row_type vector_type;
-    typedef conjugated_vector_const_ref<vector_type> sub_col_type;
-    typedef conjugated_vector_const_ref<vector_type> const_sub_col_type;
-    typedef conjugated_row_const_iterator<M> col_iterator;
-    typedef conjugated_row_const_iterator<M> const_col_iterator;
-    typedef abstract_null_type const_sub_row_type;
-    typedef abstract_null_type sub_row_type;
-    typedef abstract_null_type const_row_iterator;
-    typedef abstract_null_type row_iterator;
-    typedef col_major sub_orientation;
-    typedef typename linalg_traits<M>::index_sorted index_sorted;
-    static inline size_type ncols(const this_type &m) { return m.nc; }
-    static inline size_type nrows(const this_type &m) { return m.nr; }
-    static inline const_sub_col_type col(const const_col_iterator &it)
-    { return conjugated(linalg_traits<M>::row(it.it)); }
-    static inline const_col_iterator col_begin(const this_type &m)
-    { return const_col_iterator(m.begin_); }
-    static inline const_col_iterator col_end(const this_type &m)
-    { return const_col_iterator(m.end_); }
-    static inline const origin_type* origin(const this_type &m)
-    { return m.origin; }
-    static value_type access(const const_col_iterator &it, size_type i)
-    { return gmm::conj(linalg_traits<M>::access(it.it, i)); }
-  };
-
   template<typename M> std::ostream &operator <<
   (std::ostream &o, const conjugated_row_matrix_const_ref<M>& m)
   { gmm::write(o,m); return o; }
@@ -287,39 +253,7 @@ namespace gmm {
     { return gmm::conj(linalg_traits<M>::access(begin_+i, j)); }
   };
 
-  template <typename M>
-  struct linalg_traits<conjugated_col_matrix_const_ref<M> > {
-    typedef conjugated_col_matrix_const_ref<M> this_type;
-    typedef typename linalg_traits<M>::origin_type origin_type;
-    typedef linalg_const is_reference;
-    typedef abstract_matrix linalg_type;
-    typedef typename linalg_traits<M>::value_type value_type;
-    typedef value_type reference;
-    typedef typename linalg_traits<M>::storage_type storage_type;
-    typedef typename linalg_traits<M>::const_sub_col_type vector_type;
-    typedef conjugated_vector_const_ref<vector_type> sub_row_type;
-    typedef conjugated_vector_const_ref<vector_type> const_sub_row_type;
-    typedef conjugated_col_const_iterator<M> row_iterator;
-    typedef conjugated_col_const_iterator<M> const_row_iterator;
-    typedef abstract_null_type const_sub_col_type;
-    typedef abstract_null_type sub_col_type;
-    typedef abstract_null_type const_col_iterator;
-    typedef abstract_null_type col_iterator;
-    typedef row_major sub_orientation;
-    typedef typename linalg_traits<M>::index_sorted index_sorted;
-    static inline size_type nrows(const this_type &m) { return m.nr; }
-    static inline size_type ncols(const this_type &m) { return m.nc; }
-    static inline const_sub_row_type row(const const_row_iterator &it)
-    { return conjugated(linalg_traits<M>::col(it.it)); }
-    static inline const_row_iterator row_begin(const this_type &m)
-    { return const_row_iterator(m.begin_); }
-    static inline const_row_iterator row_end(const this_type &m)
-    { return const_row_iterator(m.end_); }
-    static inline const origin_type* origin(const this_type &m)
-    { return m.origin; }
-    static value_type access(const const_row_iterator &it, size_type i)
-    { return gmm::conj(linalg_traits<M>::access(it.it, i)); }
-  };
+
 
   template<typename M> std::ostream &operator <<
   (std::ostream &o, const conjugated_col_matrix_const_ref<M>& m)
@@ -387,6 +321,74 @@ namespace gmm {
   template <typename L> inline
   conjugated_col_matrix_const_ref<L> conjugated(const L &v, col_major)
   { return conjugated_col_matrix_const_ref<L>(v); }
+
+  template <typename M>
+  struct linalg_traits<conjugated_row_matrix_const_ref<M> > {
+    typedef conjugated_row_matrix_const_ref<M> this_type;
+    typedef typename linalg_traits<M>::origin_type origin_type;
+    typedef linalg_const is_reference;
+    typedef abstract_matrix linalg_type;
+    typedef typename linalg_traits<M>::value_type value_type;
+    typedef value_type reference;
+    typedef typename linalg_traits<M>::storage_type storage_type;
+    typedef typename org_type<typename linalg_traits<M>::const_sub_row_type>::t vector_type;
+    typedef conjugated_vector_const_ref<vector_type> sub_col_type;
+    typedef conjugated_vector_const_ref<vector_type> const_sub_col_type;
+    typedef conjugated_row_const_iterator<M> col_iterator;
+    typedef conjugated_row_const_iterator<M> const_col_iterator;
+    typedef abstract_null_type const_sub_row_type;
+    typedef abstract_null_type sub_row_type;
+    typedef abstract_null_type const_row_iterator;
+    typedef abstract_null_type row_iterator;
+    typedef col_major sub_orientation;
+    typedef typename linalg_traits<M>::index_sorted index_sorted;
+    static inline size_type ncols(const this_type &m) { return m.nc; }
+    static inline size_type nrows(const this_type &m) { return m.nr; }
+    static inline const_sub_col_type col(const const_col_iterator &it)
+    { return conjugated(linalg_traits<M>::row(it.it)); }
+    static inline const_col_iterator col_begin(const this_type &m)
+    { return const_col_iterator(m.begin_); }
+    static inline const_col_iterator col_end(const this_type &m)
+    { return const_col_iterator(m.end_); }
+    static inline const origin_type* origin(const this_type &m)
+    { return m.origin; }
+    static value_type access(const const_col_iterator &it, size_type i)
+    { return gmm::conj(linalg_traits<M>::access(it.it, i)); }
+  };
+  
+  template <typename M>
+  struct linalg_traits<conjugated_col_matrix_const_ref<M> > {
+    typedef conjugated_col_matrix_const_ref<M> this_type;
+    typedef typename linalg_traits<M>::origin_type origin_type;
+    typedef linalg_const is_reference;
+    typedef abstract_matrix linalg_type;
+    typedef typename linalg_traits<M>::value_type value_type;
+    typedef value_type reference;
+    typedef typename linalg_traits<M>::storage_type storage_type;
+    typedef typename org_type<typename linalg_traits<M>::const_sub_col_type>::t vector_type;
+    typedef conjugated_vector_const_ref<vector_type> sub_row_type;
+    typedef conjugated_vector_const_ref<vector_type> const_sub_row_type;
+    typedef conjugated_col_const_iterator<M> row_iterator;
+    typedef conjugated_col_const_iterator<M> const_row_iterator;
+    typedef abstract_null_type const_sub_col_type;
+    typedef abstract_null_type sub_col_type;
+    typedef abstract_null_type const_col_iterator;
+    typedef abstract_null_type col_iterator;
+    typedef row_major sub_orientation;
+    typedef typename linalg_traits<M>::index_sorted index_sorted;
+    static inline size_type nrows(const this_type &m) { return m.nr; }
+    static inline size_type ncols(const this_type &m) { return m.nc; }
+    static inline const_sub_row_type row(const const_row_iterator &it)
+    { return conjugated(linalg_traits<M>::col(it.it)); }
+    static inline const_row_iterator row_begin(const this_type &m)
+    { return const_row_iterator(m.begin_); }
+    static inline const_row_iterator row_end(const this_type &m)
+    { return const_row_iterator(m.end_); }
+    static inline const origin_type* origin(const this_type &m)
+    { return m.origin; }
+    static value_type access(const const_row_iterator &it, size_type i)
+    { return gmm::conj(linalg_traits<M>::access(it.it, i)); }
+  };
   
   ///@endcond
   
diff --git a/src/gmm/gmm_def.h b/src/gmm/gmm_def.h
index 0848d4c..603c57b 100644
--- a/src/gmm/gmm_def.h
+++ b/src/gmm/gmm_def.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -221,23 +221,33 @@ namespace gmm {
   };
 
   /* ******************************************************************** */
-  /*  types to deal with const object representing a modifiable reference */
+  /* Original type from a pointer or a reference.                         */
+  /* ******************************************************************** */
+
+  template <typename V> struct org_type            { typedef V t; };
+  template <typename V> struct org_type<V *>       { typedef V t; };
+  template <typename V> struct org_type<const V *> { typedef V t; };
+  template <typename V> struct org_type<V &>       { typedef V t; };
+  template <typename V> struct org_type<const V &> { typedef V t; };
+
+  /* ******************************************************************** */
+  /*  Types to deal with const object representing a modifiable reference */
   /* ******************************************************************** */
   
   template <typename PT, typename R> struct mref_type_ 
   { typedef abstract_null_type return_type; };
   template <typename L, typename R> struct mref_type_<L *, R>
-  { typedef L & return_type; };
+  { typedef typename org_type<L>::t & return_type; };
   template <typename L, typename R> struct mref_type_<const L *, R>
-  { typedef const L & return_type; };
+  { typedef const typename org_type<L>::t & return_type; };
   template <typename L> struct mref_type_<L *, linalg_const>
-  { typedef const L & return_type; };
+  { typedef const typename org_type<L>::t & return_type; };
   template <typename L> struct mref_type_<const L *, linalg_const>
-  { typedef const L & return_type; };
+  { typedef const typename org_type<L>::t & return_type; };
   template <typename L> struct mref_type_<const L *, linalg_modifiable>
-  { typedef L & return_type; };
+  { typedef typename org_type<L>::t & return_type; };
   template <typename L> struct mref_type_<L *, linalg_modifiable>
-  { typedef L & return_type; };
+  { typedef typename org_type<L>::t & return_type; };
 
   template <typename PT> struct mref_type {
     typedef typename std::iterator_traits<PT>::value_type L;
@@ -255,7 +265,7 @@ namespace gmm {
   template <typename L, typename R> struct cref_type_
   { typedef abstract_null_type return_type; };
   template <typename L> struct cref_type_<L, linalg_modifiable>
-  { typedef L & return_type; };
+  { typedef typename org_type<L>::t & return_type; };
   template <typename L> struct cref_type {
     typedef typename cref_type_<L, 
       typename linalg_traits<L>::is_reference>::return_type return_type;
@@ -476,6 +486,7 @@ namespace gmm {
 
   template <typename T> class wsvector;
   template <typename T> class rsvector;
+  template <typename T> class dsvector;
   template<typename T> struct sparse_vector_type 
   { typedef wsvector<T> vector_type; };
 
diff --git a/src/gmm/gmm_dense_Householder.h b/src/gmm/gmm_dense_Householder.h
index f36880e..4dcb3cd 100644
--- a/src/gmm/gmm_dense_Householder.h
+++ b/src/gmm/gmm_dense_Householder.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard, Caroline Lecalvez
+ Copyright (C) 2003-2017 Yves Renard, Caroline Lecalvez
 
  This file is a part of GetFEM++
 
@@ -59,7 +59,7 @@ namespace gmm {
     for (size_type i = 0; i < N; ++i, ++itx) {
       typedef typename linalg_traits<Matrix>::sub_row_type row_type;
       row_type row = mat_row(A, i);
-      typename linalg_traits<row_type>::iterator
+      typename linalg_traits<typename org_type<row_type>::t>::iterator
         it = vect_begin(row), ite = vect_end(row);
       typename linalg_traits<VecY>::const_iterator ity = vect_const_begin(y);
       T tx = *itx;
@@ -78,7 +78,7 @@ namespace gmm {
     for (size_type i = 0; i < M; ++i, ++ity) {
       typedef typename linalg_traits<Matrix>::sub_col_type col_type;
       col_type col = mat_col(A, i);
-      typename linalg_traits<col_type>::iterator
+      typename linalg_traits<typename org_type<col_type>::t>::iterator
         it = vect_begin(col), ite = vect_end(col);
       typename linalg_traits<VecX>::const_iterator itx = vect_const_begin(x);
       T ty = *ity;
@@ -112,7 +112,7 @@ namespace gmm {
     for (size_type i = 0; i < N; ++i, ++itx1, ++ity2) {
       typedef typename linalg_traits<Matrix>::sub_row_type row_type;
       row_type row = mat_row(A, i);
-      typename linalg_traits<row_type>::iterator
+      typename linalg_traits<typename org_type<row_type>::t>::iterator
         it = vect_begin(row), ite = vect_end(row);
       typename linalg_traits<VecX>::const_iterator itx2 = vect_const_begin(x);
       typename linalg_traits<VecY>::const_iterator ity1 = vect_const_begin(y);
@@ -134,7 +134,7 @@ namespace gmm {
     for (size_type i = 0; i < M; ++i, ++ity1, ++itx2) {
       typedef typename linalg_traits<Matrix>::sub_col_type col_type;
       col_type col = mat_col(A, i);
-      typename linalg_traits<col_type>::iterator
+      typename linalg_traits<typename org_type<col_type>::t>::iterator
         it = vect_begin(col), ite = vect_end(col);
       typename linalg_traits<VecX>::const_iterator itx1 = vect_const_begin(x);
       typename linalg_traits<VecY>::const_iterator ity2 = vect_const_begin(y);
diff --git a/src/gmm/gmm_dense_lu.h b/src/gmm/gmm_dense_lu.h
index becb9c6..5107abe 100644
--- a/src/gmm/gmm_dense_lu.h
+++ b/src/gmm/gmm_dense_lu.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -112,7 +112,7 @@ namespace gmm {
 	rank_one_update(sub_matrix(A, sub_interval(j+1, M-j-1),
 				 sub_interval(j+1, N-j-1)), c, conjugated(r));
       }
-      ipvt[j] = int_T(j + 1);
+      ipvt[NN-1] = int_T(NN);
     }
     return info;
   }
diff --git a/src/gmm/gmm_dense_matrix_functions.h b/src/gmm/gmm_dense_matrix_functions.h
index 87a2a5e..6005918 100644
--- a/src/gmm/gmm_dense_matrix_functions.h
+++ b/src/gmm/gmm_dense_matrix_functions.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2014-2016 Konstantinos Poulios
+ Copyright (C) 2014-2017 Konstantinos Poulios
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_dense_qr.h b/src/gmm/gmm_dense_qr.h
index ddf7710..9de7dbe 100644
--- a/src/gmm/gmm_dense_qr.h
+++ b/src/gmm/gmm_dense_qr.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_dense_sylvester.h b/src/gmm/gmm_dense_sylvester.h
index 9160088..3b184cc 100644
--- a/src/gmm/gmm_dense_sylvester.h
+++ b/src/gmm/gmm_dense_sylvester.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_domain_decomp.h b/src/gmm/gmm_domain_decomp.h
index 3a3f593..2821f3a 100644
--- a/src/gmm/gmm_domain_decomp.h
+++ b/src/gmm/gmm_domain_decomp.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_except.h b/src/gmm/gmm_except.h
index 8183f82..30b813a 100644
--- a/src/gmm/gmm_except.h
+++ b/src/gmm/gmm_except.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -39,11 +39,11 @@
 #ifndef GMM_EXCEPT_H__
 #define GMM_EXCEPT_H__
 
+#include "gmm_std.h"
+
 //provides external implementation of gmm_exception and logging.
 #ifndef EXTERNAL_EXCEPT_
 
-#include "gmm_std.h"
-
 namespace gmm {
 
 /* *********************************************************************** */
@@ -69,7 +69,7 @@ namespace gmm {
   //               defined.
   //          GMM_ASSERT3 : For internal checks. Hidden by default. Active
   //               only when DEBUG_MODE is defined.
-// __EXCEPTIONS is defined by gcc, _CPPUNWIND is defined by visual c++
+  // __EXCEPTIONS is defined by gcc, _CPPUNWIND is defined by visual c++
 #if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
   inline void short_error_throw(const char *file, int line, const char *func,
 				const char *errormsg) {
@@ -115,7 +115,6 @@ namespace gmm {
 # define GMM_ASSERT1(test, errormsg)		        		\
   { if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
 
-  // inline void GMM_THROW() IS_DEPRECATED;
   inline void GMM_THROW() {}
 #define GMM_THROW(a, b) { GMM_THROW_(a,b); gmm::GMM_THROW(); }
 
@@ -270,7 +269,7 @@ namespace gmm {
       std::cerr << e.what() << std::endl << std::endl;			\
       exit(1);								\
     }									\
-  catch(std::runtime_error e)						\
+  catch(const std::runtime_error &e)					\
     {									\
       std::cerr << "============================================\n";	\
       std::cerr << "|      An error has been detected !!!      |\n";	\
@@ -278,25 +277,25 @@ namespace gmm {
       std::cerr << e.what() << std::endl << std::endl;			\
       exit(1);								\
     }									\
-  catch(std::bad_alloc) {						\
+  catch(const std::bad_alloc &) {					\
     std::cerr << "============================================\n";	\
     std::cerr << "|  A bad allocation has been detected !!!  |\n";	\
     std::cerr << "============================================\n";	\
     exit(1);								\
   }									\
-  catch(std::bad_typeid) {						\
+  catch(const std::bad_typeid &) {					\
     std::cerr << "============================================\n";	\
     std::cerr << "|  A bad typeid     has been detected !!!  |\n";	\
     std::cerr << "============================================\n";	\
     exit(1);								\
   }									\
-  catch(std::bad_exception) {						\
+  catch(const std::bad_exception &) {					\
     std::cerr << "============================================\n";	\
     std::cerr << "|  A bad exception  has been detected !!!  |\n";	\
     std::cerr << "============================================\n";	\
     exit(1);								\
   }									\
-  catch(std::bad_cast) {						\
+  catch(const std::bad_cast &) {					\
     std::cerr << "============================================\n";	\
     std::cerr << "|    A bad cast  has been detected !!!     |\n";	\
     std::cerr << "============================================\n";	\
diff --git a/src/gmm/gmm_inoutput.h b/src/gmm/gmm_inoutput.h
index e80324c..0e27b17 100644
--- a/src/gmm/gmm_inoutput.h
+++ b/src/gmm/gmm_inoutput.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard, Julien Pommier
+ Copyright (C) 2003-2017 Yves Renard, Julien Pommier
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_interface.h b/src/gmm/gmm_interface.h
index fbf1292..a3c66cd 100644
--- a/src/gmm/gmm_interface.h
+++ b/src/gmm/gmm_interface.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -194,6 +194,12 @@ namespace gmm {
   std::ostream &operator << (std::ostream &o, const simple_vector_ref<PT>& v)
   { gmm::write(o,v); return o; }
 
+  template <typename T, typename alloc>
+  simple_vector_ref<const std::vector<T,alloc> *>
+    vref(const std::vector<T, alloc> &vv)
+  { return simple_vector_ref<const std::vector<T,alloc> *>(vv); }
+  
+
   /* ********************************************************************* */
   /*		                                         		   */
   /*		Traits for S.T.L. object                     		   */
@@ -230,13 +236,9 @@ namespace gmm {
     { return it[i]; }
     static void resize(this_type &v, size_type n) { v.resize(n); }
   };
-}
-namespace std {
-  template <typename T> ostream &operator <<
-  (std::ostream &o, const vector<T>& m) { gmm::write(o,m); return o; }
-}
-namespace gmm {
 
+  
+  
   template <typename T>
   inline size_type nnz(const std::vector<T>& l) { return l.size(); }
 
diff --git a/src/gmm/gmm_interface_bgeot.h b/src/gmm/gmm_interface_bgeot.h
index f840b1f..d1d0ae3 100644
--- a/src/gmm/gmm_interface_bgeot.h
+++ b/src/gmm/gmm_interface_bgeot.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_iter.h b/src/gmm/gmm_iter.h
index caddcac..e82d270 100644
--- a/src/gmm/gmm_iter.h
+++ b/src/gmm/gmm_iter.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_iter_solvers.h b/src/gmm/gmm_iter_solvers.h
index 49d0a7a..cb34ef0 100644
--- a/src/gmm/gmm_iter_solvers.h
+++ b/src/gmm/gmm_iter_solvers.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -70,7 +70,8 @@ namespace gmm {
     c = std::max(a, b); a = std::min(a, b); b = c;
     while (d > tol) {
       c = b - (b - a) * (Gb / (Gb - Ga)); /* regula falsi.     */
-      if (c > b) c = b; if (c < a) c = a; 
+      if (c > b) c = b;
+      if (c < a) c = a; 
       Gc = G(c);
       if (Gc*Gb > 0) { b = c; Gb = Gc; } else { a = c; Ga = Gc; }
       c = (b + a) / 2.0 ; Gc = G(c); /* Dichotomie.                       */
diff --git a/src/gmm/gmm_kernel.h b/src/gmm/gmm_kernel.h
index e1f2aa9..ebd2176 100644
--- a/src/gmm/gmm_kernel.h
+++ b/src/gmm/gmm_kernel.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_lapack_interface.h b/src/gmm/gmm_lapack_interface.h
index 6d5d646..7888aea 100644
--- a/src/gmm/gmm_lapack_interface.h
+++ b/src/gmm/gmm_lapack_interface.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -149,14 +149,11 @@ namespace gmm {
   void lu_inverse(const dense_matrix<base_type > &LU,                      \
        std::vector<int> &ipvt, const dense_matrix<base_type > &A_) {       \
     GMMLAPACK_TRACE("getri_interface");                                    \
-    dense_matrix<base_type >&                                              \
-    A = const_cast<dense_matrix<base_type > &>(A_);                        \
-    int n = int(mat_nrows(A)), info, lwork(-1); base_type work1;           \
+    dense_matrix<base_type> &A                                             \
+      = const_cast<dense_matrix<base_type > &>(A_);                        \
+    int n = int(mat_nrows(A)), info, lwork(10000); base_type work[10000];  \
     if (n) {                                                               \
-      gmm::copy(LU, A);                                                    \
-      lapack_name(&n, &A(0,0), &n, &ipvt[0], &work1, &lwork, &info);       \
-      lwork = int(gmm::real(work1));                                       \
-      std::vector<base_type > work(lwork);                                 \
+      std::copy(LU.begin(), LU.end(), A.begin());			   \
       lapack_name(&n, &A(0,0), &n, &ipvt[0], &work[0], &lwork, &info);     \
     }                                                                      \
   }
@@ -199,8 +196,8 @@ namespace gmm {
     GMMLAPACK_TRACE("geqrf_interface2");                                   \
     int m = int(mat_nrows(A)), n = int(mat_ncols(A)), info, lwork(-1);     \
     base_type work1;                                                       \
-    if (m && n) {                                                          \
-      gmm::copy(A, Q);                                                     \
+    if (m && n) {							   \
+      std::copy(A.begin(), A.end(), Q.begin());				   \
       std::vector<base_type > tau(n);                                      \
       lapack_name1(&m, &n, &Q(0,0), &m, &tau[0], &work1  , &lwork, &info); \
       lwork = int(gmm::real(work1));                                       \
diff --git a/src/gmm/gmm_least_squares_cg.h b/src/gmm/gmm_least_squares_cg.h
index f6286a8..71e4466 100644
--- a/src/gmm/gmm_least_squares_cg.h
+++ b/src/gmm/gmm_least_squares_cg.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Benjamin Schleimer
+ Copyright (C) 2002-2017 Yves Renard, Benjamin Schleimer
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_matrix.h b/src/gmm/gmm_matrix.h
index 71455c0..23fb9d2 100644
--- a/src/gmm/gmm_matrix.h
+++ b/src/gmm/gmm_matrix.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -193,8 +193,8 @@ namespace gmm
     typedef typename linalg_traits<V>::value_type value_type;
     typedef typename linalg_traits<V>::reference reference;
     typedef typename linalg_traits<V>::storage_type storage_type;
-    typedef simple_vector_ref<V *> sub_row_type;
-    typedef simple_vector_ref<const V *> const_sub_row_type;
+    typedef V & sub_row_type;
+    typedef const V & const_sub_row_type;
     typedef typename std::vector<V>::iterator row_iterator;
     typedef typename std::vector<V>::const_iterator const_row_iterator;
     typedef abstract_null_type sub_col_type;
@@ -299,8 +299,8 @@ namespace gmm
     typedef typename linalg_traits<V>::value_type value_type;
     typedef typename linalg_traits<V>::reference reference;
     typedef typename linalg_traits<V>::storage_type storage_type;
-    typedef simple_vector_ref<V *> sub_col_type;
-    typedef simple_vector_ref<const V *> const_sub_col_type;
+    typedef V &sub_col_type;
+    typedef const V &const_sub_col_type;
     typedef typename std::vector<V>::iterator col_iterator;
     typedef typename std::vector<V>::const_iterator const_col_iterator;
     typedef abstract_null_type sub_row_type;
@@ -318,9 +318,9 @@ namespace gmm
     static const_col_iterator col_end(const this_type &m)
     { return m.end(); }
     static const_sub_col_type col(const const_col_iterator &it)
-    { return const_sub_col_type(*it); }
+    { return *it; }
     static sub_col_type col(const col_iterator &it) 
-    { return sub_col_type(*it); }
+    { return *it; }
     static origin_type* origin(this_type &m) { return &m; }
     static const origin_type* origin(const this_type &m) { return &m; }
     static void do_clear(this_type &m) { m.clear_mat(); }
@@ -369,6 +369,7 @@ namespace gmm
     const std::vector<T> &as_vector(void) const { return *this; }
 
     void resize(size_type, size_type);
+    void base_resize(size_type, size_type);
     void reshape(size_type, size_type);
     
     void fill(T a, T b = T(0));
@@ -387,6 +388,10 @@ namespace gmm
     nbl = m; nbc = n;
   }
 
+  template<typename T> void dense_matrix<T>::base_resize(size_type m,
+							 size_type n)
+  { std::vector<T>::resize(n*m); nbl = m; nbc = n; }
+  
   template<typename T> void dense_matrix<T>::resize(size_type m, size_type n) {
     if (n*m > nbc*nbl) std::vector<T>::resize(n*m);
     if (m < nbl) {
@@ -546,7 +551,7 @@ namespace gmm
     ir.resize(jc[nc]);
     for (size_type j = 0; j < nc; ++j) {
       col_type col = mat_const_col(B, j);
-      typename linalg_traits<col_type>::const_iterator
+      typename linalg_traits<typename org_type<col_type>::t>::const_iterator
 	it = vect_const_begin(col), ite = vect_const_end(col);
       for (size_type k = 0; it != ite; ++it, ++k) {
 	pr[jc[j]-shift+k] = *it;
@@ -696,7 +701,7 @@ namespace gmm
     ir.resize(jc[nr]);
     for (size_type j = 0; j < nr; ++j) {
       row_type row = mat_const_row(B, j);
-      typename linalg_traits<row_type>::const_iterator
+      typename linalg_traits<typename org_type<row_type>::t>::const_iterator
 	it = vect_const_begin(row), ite = vect_const_end(row);
       for (size_type k = 0; it != ite; ++it, ++k) {
 	pr[jc[j]-shift+k] = *it;
diff --git a/src/gmm/gmm_modified_gram_schmidt.h b/src/gmm/gmm_modified_gram_schmidt.h
index 26fc571..34d54ae 100644
--- a/src/gmm/gmm_modified_gram_schmidt.h
+++ b/src/gmm/gmm_modified_gram_schmidt.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_opt.h b/src/gmm/gmm_opt.h
index 27482d5..e73af41 100644
--- a/src/gmm/gmm_opt.h
+++ b/src/gmm/gmm_opt.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_precond.h b/src/gmm/gmm_precond.h
index 5047d1a..fca4f35 100644
--- a/src/gmm/gmm_precond.h
+++ b/src/gmm/gmm_precond.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_precond_diagonal.h b/src/gmm/gmm_precond_diagonal.h
index 6509085..19d4609 100644
--- a/src/gmm/gmm_precond_diagonal.h
+++ b/src/gmm/gmm_precond_diagonal.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_precond_ildlt.h b/src/gmm/gmm_precond_ildlt.h
index 094c1c5..22484df 100644
--- a/src/gmm/gmm_precond_ildlt.h
+++ b/src/gmm/gmm_precond_ildlt.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -144,7 +144,7 @@ namespace gmm {
       for (Tri_loc = 0, i = 0; i < n; ++i) {
 	typedef typename linalg_traits<M>::const_sub_row_type row_type;
 	row_type row = mat_const_row(A, i);
-        typename linalg_traits<row_type>::const_iterator
+        typename linalg_traits<typename org_type<row_type>::t>::const_iterator
 	  it = vect_const_begin(row), ite = vect_const_end(row);
 
 	if (count) { Tri_val[Tri_loc] = T(0); Tri_ind[Tri_loc] = i; }
diff --git a/src/gmm/gmm_precond_ildltt.h b/src/gmm/gmm_precond_ildltt.h
index 441e223..380106a 100644
--- a/src/gmm/gmm_precond_ildltt.h
+++ b/src/gmm/gmm_precond_ildltt.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_precond_ilu.h b/src/gmm/gmm_precond_ilu.h
index 747f2fc..9256b86 100644
--- a/src/gmm/gmm_precond_ilu.h
+++ b/src/gmm/gmm_precond_ilu.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -142,7 +142,7 @@ namespace gmm {
       for (i = 0; i < n; ++i) {
 	typedef typename linalg_traits<M>::const_sub_row_type row_type;
 	row_type row = mat_const_row(A, i);
-	typename linalg_traits<row_type>::const_iterator
+	typename linalg_traits<typename org_type<row_type>::t>::const_iterator
 	  it = vect_const_begin(row), ite = vect_const_end(row);
 	
 	if (count) { U_val[U_loc] = T(0); U_ind[U_loc] = i; }
diff --git a/src/gmm/gmm_precond_ilut.h b/src/gmm/gmm_precond_ilut.h
index d910d6d..0860324 100644
--- a/src/gmm/gmm_precond_ilut.h
+++ b/src/gmm/gmm_precond_ilut.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_precond_ilutp.h b/src/gmm/gmm_precond_ilutp.h
index f5deac2..d867d60 100644
--- a/src/gmm/gmm_precond_ilutp.h
+++ b/src/gmm/gmm_precond_ilutp.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_precond_mr_approx_inverse.h b/src/gmm/gmm_precond_mr_approx_inverse.h
index 5697d2a..7504f48 100644
--- a/src/gmm/gmm_precond_mr_approx_inverse.h
+++ b/src/gmm/gmm_precond_mr_approx_inverse.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_range_basis.h b/src/gmm/gmm_range_basis.h
index bcd02ca..05a71a0 100644
--- a/src/gmm/gmm_range_basis.h
+++ b/src/gmm/gmm_range_basis.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard
+ Copyright (C) 2009-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_real_part.h b/src/gmm/gmm_real_part.h
index aac595c..c4e61d8 100644
--- a/src/gmm/gmm_real_part.h
+++ b/src/gmm/gmm_real_part.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -237,7 +237,163 @@ namespace gmm {
     typedef typename linalg_traits<VECT>::V_reference ref_t;
     set_to_end(it.it, o, typename linalg_traits<VECT>::pV(), ref_t());
   }
+
+  template <typename PT, typename PART> std::ostream &operator <<
+    (std::ostream &o, const part_vector<PT, PART>& m)
+  { gmm::write(o,m); return o; }
+
+
+  /* ********************************************************************* */
+  /*	Reference to the real or imaginary part of (complex) matrices      */
+  /* ********************************************************************* */
+
+
+  template <typename PT, typename PART> struct  part_row_ref {
+    
+    typedef part_row_ref<PT, PART> this_type;
+    typedef typename std::iterator_traits<PT>::value_type M;
+    typedef M * CPT;
+    typedef typename std::iterator_traits<PT>::reference ref_M;
+    typedef typename select_ref<typename linalg_traits<this_type>
+            ::const_row_iterator, typename linalg_traits<this_type>
+            ::row_iterator, PT>::ref_type iterator;
+    typedef typename linalg_traits<this_type>::value_type value_type;
+    typedef typename linalg_traits<this_type>::reference reference;
+    typedef typename linalg_traits<this_type>::porigin_type porigin_type;
+
+    iterator begin_, end_;
+    porigin_type origin;
+    size_type nr, nc;
+
+    part_row_ref(ref_M m)
+      : begin_(mat_row_begin(m)), end_(mat_row_end(m)),
+	origin(linalg_origin(m)), nr(mat_nrows(m)), nc(mat_ncols(m)) {}
+
+    part_row_ref(const part_row_ref<CPT, PART> &cr) :
+      begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {}
+
+    reference operator()(size_type i, size_type j) const {
+      return reference(ref_or_value_type<reference>::r(
+					 linalg_traits<M>::access(begin_+i, j),
+					 PART(), value_type()));
+    }
+  };
   
+  template<typename PT, typename PART> std::ostream &operator <<
+    (std::ostream &o, const part_row_ref<PT, PART>& m)
+  { gmm::write(o,m); return o; }
+
+  template <typename PT, typename PART> struct  part_col_ref {
+    
+    typedef part_col_ref<PT, PART> this_type;
+    typedef typename std::iterator_traits<PT>::value_type M;
+    typedef M * CPT;
+    typedef typename std::iterator_traits<PT>::reference ref_M;
+    typedef typename select_ref<typename linalg_traits<this_type>
+            ::const_col_iterator, typename linalg_traits<this_type>
+            ::col_iterator, PT>::ref_type iterator;
+    typedef typename linalg_traits<this_type>::value_type value_type;
+    typedef typename linalg_traits<this_type>::reference reference;
+    typedef typename linalg_traits<this_type>::porigin_type porigin_type;
+
+    iterator begin_, end_;
+    porigin_type origin;
+    size_type nr, nc;
+
+    part_col_ref(ref_M m)
+      : begin_(mat_col_begin(m)), end_(mat_col_end(m)),
+	origin(linalg_origin(m)), nr(mat_nrows(m)), nc(mat_ncols(m)) {}
+
+    part_col_ref(const part_col_ref<CPT, PART> &cr) :
+      begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {}
+
+    reference operator()(size_type i, size_type j) const {
+      return reference(ref_or_value_type<reference>::r(
+					 linalg_traits<M>::access(begin_+j, i),
+					 PART(), value_type()));
+    }
+  };
+   
+
+  
+  template<typename PT, typename PART> std::ostream &operator <<
+    (std::ostream &o, const part_col_ref<PT, PART>& m)
+  { gmm::write(o,m); return o; }
+
+  
+
+
+
+
+template <typename TYPE, typename PART, typename PT>
+  struct part_return_ {
+    typedef abstract_null_type return_type;
+  };
+  template <typename PT, typename PART>
+  struct part_return_<row_major, PART, PT> {
+    typedef typename std::iterator_traits<PT>::value_type L;
+    typedef typename select_return<part_row_ref<const L *, PART>,
+		     part_row_ref< L *, PART>, PT>::return_type return_type;
+  };
+  template <typename PT, typename PART>
+  struct part_return_<col_major, PART, PT> {
+    typedef typename std::iterator_traits<PT>::value_type L;
+    typedef typename select_return<part_col_ref<const L *, PART>,
+		     part_col_ref<L *, PART>, PT>::return_type return_type;
+  };
+
+  template <typename PT, typename PART, typename LT> struct part_return__{
+    typedef abstract_null_type return_type;
+  };
+
+  template <typename PT, typename PART>
+  struct part_return__<PT, PART, abstract_matrix> {
+    typedef typename std::iterator_traits<PT>::value_type L;
+    typedef typename part_return_<typename principal_orientation_type<
+      typename linalg_traits<L>::sub_orientation>::potype, PART,
+      PT>::return_type return_type;
+  };
+
+  template <typename PT, typename PART>
+  struct part_return__<PT, PART, abstract_vector> {
+    typedef typename std::iterator_traits<PT>::value_type L;
+    typedef typename select_return<part_vector<const L *, PART>,
+      part_vector<L *, PART>, PT>::return_type return_type;
+  };
+
+  template <typename PT, typename PART> struct part_return {
+    typedef typename std::iterator_traits<PT>::value_type L;
+    typedef typename part_return__<PT, PART,
+      typename linalg_traits<L>::linalg_type>::return_type return_type;
+  };
+
+  template <typename L> inline 
+  typename part_return<const L *, linalg_real_part>::return_type
+  real_part(const L &l) {
+    return typename part_return<const L *, linalg_real_part>::return_type
+      (linalg_cast(const_cast<L &>(l)));
+  }
+
+  template <typename L> inline 
+  typename part_return<L *, linalg_real_part>::return_type
+  real_part(L &l) {
+    return typename part_return<L *, linalg_real_part>::return_type(linalg_cast(l));
+  }
+
+  template <typename L> inline 
+  typename part_return<const L *, linalg_imag_part>::return_type
+  imag_part(const L &l) {
+    return typename part_return<const L *, linalg_imag_part>::return_type
+      (linalg_cast(const_cast<L &>(l)));
+  }
+
+  template <typename L> inline 
+  typename part_return<L *, linalg_imag_part>::return_type
+  imag_part(L &l) {
+    return typename part_return<L *, linalg_imag_part>::return_type(linalg_cast(l));
+  }
+
+
   template <typename PT, typename PART>
   struct linalg_traits<part_vector<PT, PART> > {
     typedef part_vector<PT, PART> this_type;
@@ -323,47 +479,6 @@ namespace gmm {
     { return reference(linalg_traits<V>::access(o, it.it, ite.it,i)); }
   };
 
-  template <typename PT, typename PART> std::ostream &operator <<
-    (std::ostream &o, const part_vector<PT, PART>& m)
-  { gmm::write(o,m); return o; }
-
-
-  /* ********************************************************************* */
-  /*	Reference to the real or imaginary part of (complex) matrices      */
-  /* ********************************************************************* */
-
-
-  template <typename PT, typename PART> struct  part_row_ref {
-    
-    typedef part_row_ref<PT, PART> this_type;
-    typedef typename std::iterator_traits<PT>::value_type M;
-    typedef M * CPT;
-    typedef typename std::iterator_traits<PT>::reference ref_M;
-    typedef typename select_ref<typename linalg_traits<this_type>
-            ::const_row_iterator, typename linalg_traits<this_type>
-            ::row_iterator, PT>::ref_type iterator;
-    typedef typename linalg_traits<this_type>::value_type value_type;
-    typedef typename linalg_traits<this_type>::reference reference;
-    typedef typename linalg_traits<this_type>::porigin_type porigin_type;
-
-    iterator begin_, end_;
-    porigin_type origin;
-    size_type nr, nc;
-
-    part_row_ref(ref_M m)
-      : begin_(mat_row_begin(m)), end_(mat_row_end(m)),
-	origin(linalg_origin(m)), nr(mat_nrows(m)), nc(mat_ncols(m)) {}
-
-    part_row_ref(const part_row_ref<CPT, PART> &cr) :
-      begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {}
-
-    reference operator()(size_type i, size_type j) const {
-      return reference(ref_or_value_type<reference>::r(
-					 linalg_traits<M>::access(begin_+i, j),
-					 PART(), value_type()));
-    }
-  };
-
   template <typename PT, typename PART>
   struct linalg_traits<part_row_ref<PT, PART> > {
     typedef part_row_ref<PT, PART> this_type;
@@ -380,9 +495,9 @@ namespace gmm {
     typedef abstract_null_type const_sub_col_type;
     typedef abstract_null_type col_iterator;
     typedef abstract_null_type const_col_iterator;
-    typedef typename linalg_traits<M>::const_sub_row_type
+    typedef typename org_type<typename linalg_traits<M>::const_sub_row_type>::t
             pre_const_sub_row_type;
-    typedef typename linalg_traits<M>::sub_row_type pre_sub_row_type;
+    typedef typename org_type<typename linalg_traits<M>::sub_row_type>::t pre_sub_row_type;
     typedef part_vector<const pre_const_sub_row_type *, PART>
             const_sub_row_type;
     typedef typename select_ref<abstract_null_type,
@@ -418,47 +533,6 @@ namespace gmm {
 					 PART(), value_type()));
     }
   };
-   
-  template <typename PT, typename PART> 
-  void linalg_traits<part_row_ref<PT, PART> >::do_clear(this_type &v) { 
-    row_iterator it = mat_row_begin(v), ite = mat_row_end(v);
-    for (; it != ite; ++it) clear(row(it));
-  }
-  
-  template<typename PT, typename PART> std::ostream &operator <<
-    (std::ostream &o, const part_row_ref<PT, PART>& m)
-  { gmm::write(o,m); return o; }
-
-  template <typename PT, typename PART> struct  part_col_ref {
-    
-    typedef part_col_ref<PT, PART> this_type;
-    typedef typename std::iterator_traits<PT>::value_type M;
-    typedef M * CPT;
-    typedef typename std::iterator_traits<PT>::reference ref_M;
-    typedef typename select_ref<typename linalg_traits<this_type>
-            ::const_col_iterator, typename linalg_traits<this_type>
-            ::col_iterator, PT>::ref_type iterator;
-    typedef typename linalg_traits<this_type>::value_type value_type;
-    typedef typename linalg_traits<this_type>::reference reference;
-    typedef typename linalg_traits<this_type>::porigin_type porigin_type;
-
-    iterator begin_, end_;
-    porigin_type origin;
-    size_type nr, nc;
-
-    part_col_ref(ref_M m)
-      : begin_(mat_col_begin(m)), end_(mat_col_end(m)),
-	origin(linalg_origin(m)), nr(mat_nrows(m)), nc(mat_ncols(m)) {}
-
-    part_col_ref(const part_col_ref<CPT, PART> &cr) :
-      begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {}
-
-    reference operator()(size_type i, size_type j) const {
-      return reference(ref_or_value_type<reference>::r(
-					 linalg_traits<M>::access(begin_+j, i),
-					 PART(), value_type()));
-    }
-  };
 
   template <typename PT, typename PART>
   struct linalg_traits<part_col_ref<PT, PART> > {
@@ -476,9 +550,9 @@ namespace gmm {
     typedef abstract_null_type const_sub_row_type;
     typedef abstract_null_type row_iterator;
     typedef abstract_null_type const_row_iterator;
-    typedef typename linalg_traits<M>::const_sub_col_type
+    typedef typename org_type<typename linalg_traits<M>::const_sub_col_type>::t
             pre_const_sub_col_type;
-    typedef typename linalg_traits<M>::sub_col_type pre_sub_col_type;
+    typedef typename org_type<typename linalg_traits<M>::sub_col_type>::t pre_sub_col_type;
     typedef part_vector<const pre_const_sub_col_type *, PART>
             const_sub_col_type;
     typedef typename select_ref<abstract_null_type,
@@ -514,92 +588,18 @@ namespace gmm {
 					 PART(), value_type()));
     }
   };
-   
+
   template <typename PT, typename PART> 
   void linalg_traits<part_col_ref<PT, PART> >::do_clear(this_type &v) { 
     col_iterator it = mat_col_begin(v), ite = mat_col_end(v);
     for (; it != ite; ++it) clear(col(it));
   }
   
-  template<typename PT, typename PART> std::ostream &operator <<
-    (std::ostream &o, const part_col_ref<PT, PART>& m)
-  { gmm::write(o,m); return o; }
-
-  
-
-
-
-
-template <typename TYPE, typename PART, typename PT>
-  struct part_return_ {
-    typedef abstract_null_type return_type;
-  };
-  template <typename PT, typename PART>
-  struct part_return_<row_major, PART, PT> {
-    typedef typename std::iterator_traits<PT>::value_type L;
-    typedef typename select_return<part_row_ref<const L *, PART>,
-		     part_row_ref< L *, PART>, PT>::return_type return_type;
-  };
-  template <typename PT, typename PART>
-  struct part_return_<col_major, PART, PT> {
-    typedef typename std::iterator_traits<PT>::value_type L;
-    typedef typename select_return<part_col_ref<const L *, PART>,
-		     part_col_ref<L *, PART>, PT>::return_type return_type;
-  };
-
-  template <typename PT, typename PART, typename LT> struct part_return__{
-    typedef abstract_null_type return_type;
-  };
-
-  template <typename PT, typename PART>
-  struct part_return__<PT, PART, abstract_matrix> {
-    typedef typename std::iterator_traits<PT>::value_type L;
-    typedef typename part_return_<typename principal_orientation_type<
-      typename linalg_traits<L>::sub_orientation>::potype, PART,
-      PT>::return_type return_type;
-  };
-
-  template <typename PT, typename PART>
-  struct part_return__<PT, PART, abstract_vector> {
-    typedef typename std::iterator_traits<PT>::value_type L;
-    typedef typename select_return<part_vector<const L *, PART>,
-      part_vector<L *, PART>, PT>::return_type return_type;
-  };
-
-  template <typename PT, typename PART> struct part_return {
-    typedef typename std::iterator_traits<PT>::value_type L;
-    typedef typename part_return__<PT, PART,
-      typename linalg_traits<L>::linalg_type>::return_type return_type;
-  };
-
-  template <typename L> inline 
-  typename part_return<const L *, linalg_real_part>::return_type
-  real_part(const L &l) {
-    return typename part_return<const L *, linalg_real_part>::return_type
-      (linalg_cast(const_cast<L &>(l)));
-  }
-
-  template <typename L> inline 
-  typename part_return<L *, linalg_real_part>::return_type
-  real_part(L &l) {
-    return typename part_return<L *, linalg_real_part>::return_type(linalg_cast(l));
-  }
-
-  template <typename L> inline 
-  typename part_return<const L *, linalg_imag_part>::return_type
-  imag_part(const L &l) {
-    return typename part_return<const L *, linalg_imag_part>::return_type
-      (linalg_cast(const_cast<L &>(l)));
-  }
-
-  template <typename L> inline 
-  typename part_return<L *, linalg_imag_part>::return_type
-  imag_part(L &l) {
-    return typename part_return<L *, linalg_imag_part>::return_type(linalg_cast(l));
+  template <typename PT, typename PART> 
+  void linalg_traits<part_row_ref<PT, PART> >::do_clear(this_type &v) { 
+    row_iterator it = mat_row_begin(v), ite = mat_row_end(v);
+    for (; it != ite; ++it) clear(row(it));
   }
-
-
-
 }
 
 #endif //  GMM_REAL_PART_H
diff --git a/src/gmm/gmm_ref.h b/src/gmm/gmm_ref.h
index 5d4a696..67af377 100644
--- a/src/gmm/gmm_ref.h
+++ b/src/gmm/gmm_ref.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_scaled.h b/src/gmm/gmm_scaled.h
index 9961483..485af32 100644
--- a/src/gmm/gmm_scaled.h
+++ b/src/gmm/gmm_scaled.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -110,29 +110,6 @@ namespace gmm {
     { return value_type(r) * linalg_traits<V>::access(origin, begin_, end_, i); }
   };
 
-  template <typename V, typename S> struct linalg_traits<scaled_vector_const_ref<V,S> > {
-    typedef scaled_vector_const_ref<V,S> this_type;
-    typedef linalg_const is_reference;
-    typedef abstract_vector linalg_type;
-    typedef typename strongest_numeric_type<S, typename linalg_traits<V>::value_type>::T value_type;
-    typedef typename linalg_traits<V>::origin_type origin_type;
-    typedef value_type reference;
-    typedef abstract_null_type iterator;
-    typedef scaled_const_iterator<typename linalg_traits<V>::const_iterator, S>
-      const_iterator;
-    typedef typename linalg_traits<V>::storage_type storage_type;
-    typedef typename linalg_traits<V>::index_sorted index_sorted;
-    static size_type size(const this_type &v) { return v.size_; }
-    static const_iterator begin(const this_type &v)
-    { return const_iterator(v.begin_, v.r); }
-    static const_iterator end(const this_type &v)
-    { return const_iterator(v.end_, v.r); }
-    static const origin_type* origin(const this_type &v) { return v.origin; }
-    static value_type access(const origin_type *o, const const_iterator &it,
-			     const const_iterator &ite, size_type i)
-    { return it.r * (linalg_traits<V>::access(o, it.it, ite.it, i)); }
-
-  };
 
    template<typename V, typename S> std::ostream &operator <<
      (std::ostream &o, const scaled_vector_const_ref<V,S>& m)
@@ -197,39 +174,6 @@ namespace gmm {
     { return r * linalg_traits<M>::access(begin_+i, j); }
   };
 
-  template <typename M, typename S> struct linalg_traits<scaled_row_matrix_const_ref<M,S> > {
-    typedef scaled_row_matrix_const_ref<M,S> this_type;
-    typedef linalg_const is_reference;
-    typedef abstract_matrix linalg_type;
-    typedef typename linalg_traits<M>::origin_type origin_type;
-    typedef typename strongest_numeric_type<S, typename linalg_traits<M>::value_type>::T value_type;
-    typedef value_type reference;
-    typedef typename linalg_traits<M>::storage_type storage_type;
-    typedef typename linalg_traits<M>::const_sub_row_type vector_type;
-    typedef scaled_vector_const_ref<vector_type,S> sub_row_type;
-    typedef scaled_vector_const_ref<vector_type,S> const_sub_row_type;
-    typedef scaled_row_const_iterator<M,S> row_iterator;
-    typedef scaled_row_const_iterator<M,S> const_row_iterator;
-    typedef abstract_null_type const_sub_col_type;
-    typedef abstract_null_type sub_col_type;
-    typedef abstract_null_type const_col_iterator;
-    typedef abstract_null_type col_iterator;
-    typedef row_major sub_orientation;
-    typedef typename linalg_traits<M>::index_sorted index_sorted;
-    static size_type nrows(const this_type &m)
-    { return m.nr; }
-    static size_type ncols(const this_type &m)
-    { return m.nc; }
-    static const_sub_row_type row(const const_row_iterator &it)
-    { return scaled(linalg_traits<M>::row(it.it), it.r); }
-    static const_row_iterator row_begin(const this_type &m)
-    { return const_row_iterator(m.begin_, m.r); }
-    static const_row_iterator row_end(const this_type &m)
-    { return const_row_iterator(m.end_, m.r); }
-    static const origin_type* origin(const this_type &m) { return m.origin; }
-    static value_type access(const const_row_iterator &it, size_type i)
-    { return it.r * (linalg_traits<M>::access(it.it, i)); }
-  };
 
   template<typename M, typename S> std::ostream &operator <<
     (std::ostream &o, const scaled_row_matrix_const_ref<M,S>& m)
@@ -291,39 +235,7 @@ namespace gmm {
     { return r * linalg_traits<M>::access(begin_+j, i); }
   };
 
-  template <typename M, typename S> struct linalg_traits<scaled_col_matrix_const_ref<M,S> > {
-    typedef scaled_col_matrix_const_ref<M,S> this_type;
-    typedef linalg_const is_reference;
-    typedef abstract_matrix linalg_type;
-    typedef typename strongest_numeric_type<S, typename linalg_traits<M>::value_type>::T value_type;
-    typedef typename linalg_traits<M>::origin_type origin_type;
-    typedef value_type reference;
-    typedef typename linalg_traits<M>::storage_type storage_type;
-    typedef typename linalg_traits<M>::const_sub_col_type vector_type;
-    typedef abstract_null_type sub_col_type;
-    typedef scaled_vector_const_ref<vector_type,S> const_sub_col_type;
-    typedef abstract_null_type  col_iterator;
-    typedef scaled_col_const_iterator<M,S> const_col_iterator;
-    typedef abstract_null_type const_sub_row_type;
-    typedef abstract_null_type sub_row_type;
-    typedef abstract_null_type const_row_iterator;
-    typedef abstract_null_type row_iterator;
-    typedef col_major sub_orientation;
-    typedef typename linalg_traits<M>::index_sorted index_sorted;
-    static size_type ncols(const this_type &m)
-    { return m.nc; }
-    static size_type nrows(const this_type &m)
-    { return m.nr; }
-    static const_sub_col_type col(const const_col_iterator &it)
-    { return scaled(linalg_traits<M>::col(it.it), it.r); }
-    static const_col_iterator col_begin(const this_type &m)
-    { return const_col_iterator(m.begin_, m.r); }
-    static const_col_iterator col_end(const this_type &m)
-    { return const_col_iterator(m.end_, m.r); }
-    static const origin_type* origin(const this_type &m) { return m.origin; }
-    static value_type access(const const_col_iterator &it, size_type i)
-    { return it.r * (linalg_traits<M>::access(it.it, i)); }
-  };
+
 
   template<typename M, typename S> std::ostream &operator <<
     (std::ostream &o, const scaled_col_matrix_const_ref<M,S>& m)
@@ -384,7 +296,7 @@ namespace gmm {
     return scaled_col_matrix_const_ref<M,S>(m, x);
   }
 
-  
+
   /* ******************************************************************** */
   /*	matrix or vector scale                                	          */
   /* ******************************************************************** */
@@ -423,6 +335,100 @@ namespace gmm {
     for ( ; it != ite; ++it) scale(linalg_traits<L>::col(it), a);
   }
 
+  template <typename V, typename S> struct linalg_traits<scaled_vector_const_ref<V,S> > {
+    typedef scaled_vector_const_ref<V,S> this_type;
+    typedef linalg_const is_reference;
+    typedef abstract_vector linalg_type;
+    typedef typename strongest_numeric_type<S, typename linalg_traits<V>::value_type>::T value_type;
+    typedef typename linalg_traits<V>::origin_type origin_type;
+    typedef value_type reference;
+    typedef abstract_null_type iterator;
+    typedef scaled_const_iterator<typename linalg_traits<V>::const_iterator, S>
+      const_iterator;
+    typedef typename linalg_traits<V>::storage_type storage_type;
+    typedef typename linalg_traits<V>::index_sorted index_sorted;
+    static size_type size(const this_type &v) { return v.size_; }
+    static const_iterator begin(const this_type &v)
+    { return const_iterator(v.begin_, v.r); }
+    static const_iterator end(const this_type &v)
+    { return const_iterator(v.end_, v.r); }
+    static const origin_type* origin(const this_type &v) { return v.origin; }
+    static value_type access(const origin_type *o, const const_iterator &it,
+			     const const_iterator &ite, size_type i)
+    { return it.r * (linalg_traits<V>::access(o, it.it, ite.it, i)); }
+
+  };
+
+
+  template <typename M, typename S> struct linalg_traits<scaled_row_matrix_const_ref<M,S> > {
+    typedef scaled_row_matrix_const_ref<M,S> this_type;
+    typedef linalg_const is_reference;
+    typedef abstract_matrix linalg_type;
+    typedef typename linalg_traits<M>::origin_type origin_type;
+    typedef typename strongest_numeric_type<S, typename linalg_traits<M>::value_type>::T value_type;
+    typedef value_type reference;
+    typedef typename linalg_traits<M>::storage_type storage_type;
+    typedef typename org_type<typename linalg_traits<M>::const_sub_row_type>::t vector_type;
+    typedef scaled_vector_const_ref<vector_type,S> sub_row_type;
+    typedef scaled_vector_const_ref<vector_type,S> const_sub_row_type;
+    typedef scaled_row_const_iterator<M,S> row_iterator;
+    typedef scaled_row_const_iterator<M,S> const_row_iterator;
+    typedef abstract_null_type const_sub_col_type;
+    typedef abstract_null_type sub_col_type;
+    typedef abstract_null_type const_col_iterator;
+    typedef abstract_null_type col_iterator;
+    typedef row_major sub_orientation;
+    typedef typename linalg_traits<M>::index_sorted index_sorted;
+    static size_type nrows(const this_type &m)
+    { return m.nr; }
+    static size_type ncols(const this_type &m)
+    { return m.nc; }
+    static const_sub_row_type row(const const_row_iterator &it)
+    { return scaled(linalg_traits<M>::row(it.it), it.r); }
+    static const_row_iterator row_begin(const this_type &m)
+    { return const_row_iterator(m.begin_, m.r); }
+    static const_row_iterator row_end(const this_type &m)
+    { return const_row_iterator(m.end_, m.r); }
+    static const origin_type* origin(const this_type &m) { return m.origin; }
+    static value_type access(const const_row_iterator &it, size_type i)
+    { return it.r * (linalg_traits<M>::access(it.it, i)); }
+  };
+
+  template <typename M, typename S> struct linalg_traits<scaled_col_matrix_const_ref<M,S> > {
+    typedef scaled_col_matrix_const_ref<M,S> this_type;
+    typedef linalg_const is_reference;
+    typedef abstract_matrix linalg_type;
+    typedef typename strongest_numeric_type<S, typename linalg_traits<M>::value_type>::T value_type;
+    typedef typename linalg_traits<M>::origin_type origin_type;
+    typedef value_type reference;
+    typedef typename linalg_traits<M>::storage_type storage_type;
+    typedef typename org_type<typename linalg_traits<M>::const_sub_col_type>::t vector_type;
+    typedef abstract_null_type sub_col_type;
+    typedef scaled_vector_const_ref<vector_type,S> const_sub_col_type;
+    typedef abstract_null_type  col_iterator;
+    typedef scaled_col_const_iterator<M,S> const_col_iterator;
+    typedef abstract_null_type const_sub_row_type;
+    typedef abstract_null_type sub_row_type;
+    typedef abstract_null_type const_row_iterator;
+    typedef abstract_null_type row_iterator;
+    typedef col_major sub_orientation;
+    typedef typename linalg_traits<M>::index_sorted index_sorted;
+    static size_type ncols(const this_type &m)
+    { return m.nc; }
+    static size_type nrows(const this_type &m)
+    { return m.nr; }
+    static const_sub_col_type col(const const_col_iterator &it)
+    { return scaled(linalg_traits<M>::col(it.it), it.r); }
+    static const_col_iterator col_begin(const this_type &m)
+    { return const_col_iterator(m.begin_, m.r); }
+    static const_col_iterator col_end(const this_type &m)
+    { return const_col_iterator(m.end_, m.r); }
+    static const origin_type* origin(const this_type &m) { return m.origin; }
+    static value_type access(const const_col_iterator &it, size_type i)
+    { return it.r * (linalg_traits<M>::access(it.it, i)); }
+  };
+
+
 }
 
 #endif //  GMM_SCALED_H__
diff --git a/src/gmm/gmm_solver_Schwarz_additive.h b/src/gmm/gmm_solver_Schwarz_additive.h
index ab167f5..7f8554b 100644
--- a/src/gmm/gmm_solver_Schwarz_additive.h
+++ b/src/gmm/gmm_solver_Schwarz_additive.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_solver_bfgs.h b/src/gmm/gmm_solver_bfgs.h
index 132d9b9..28a1bc0 100644
--- a/src/gmm/gmm_solver_bfgs.h
+++ b/src/gmm/gmm_solver_bfgs.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2004-2016 Yves Renard
+ Copyright (C) 2004-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_solver_bicgstab.h b/src/gmm/gmm_solver_bicgstab.h
index e4f3ce8..858478f 100644
--- a/src/gmm/gmm_solver_bicgstab.h
+++ b/src/gmm/gmm_solver_bicgstab.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_solver_cg.h b/src/gmm/gmm_solver_cg.h
index 2eb202f..a287678 100644
--- a/src/gmm/gmm_solver_cg.h
+++ b/src/gmm/gmm_solver_cg.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_solver_constrained_cg.h b/src/gmm/gmm_solver_constrained_cg.h
index a621232..44716bf 100644
--- a/src/gmm/gmm_solver_constrained_cg.h
+++ b/src/gmm/gmm_solver_constrained_cg.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_solver_gmres.h b/src/gmm/gmm_solver_gmres.h
index fdc0a31..b124905 100644
--- a/src/gmm/gmm_solver_gmres.h
+++ b/src/gmm/gmm_solver_gmres.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_solver_idgmres.h b/src/gmm/gmm_solver_idgmres.h
index 5cfdf29..79bb906 100644
--- a/src/gmm/gmm_solver_idgmres.h
+++ b/src/gmm/gmm_solver_idgmres.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard, Caroline Lecalvez
+ Copyright (C) 2003-2017 Yves Renard, Caroline Lecalvez
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_solver_qmr.h b/src/gmm/gmm_solver_qmr.h
index e77066a..ca6b8e0 100644
--- a/src/gmm/gmm_solver_qmr.h
+++ b/src/gmm/gmm_solver_qmr.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_std.h b/src/gmm/gmm_std.h
index f433bbb..3de9a4c 100644
--- a/src/gmm/gmm_std.h
+++ b/src/gmm/gmm_std.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -38,6 +38,8 @@
 #ifndef GMM_STD_H__
 #define GMM_STD_H__
 
+#include <getfem/getfem_arch_config.h>
+
 #ifndef __USE_STD_IOSTREAM
 # define __USE_STD_IOSTREAM
 #endif
@@ -74,7 +76,8 @@
 # define SECURE_STRDUP(s) strdup(s)
 #endif
 
-#define GMM_NOPERATION(a) { abs(&(a) != &(a)); }
+inline void GMM_NOPERATION_(int) { }
+#define GMM_NOPERATION(a) { GMM_NOPERATION_(abs(&(a) != &(a))); }
 
 /* ********************************************************************** */
 /*	Compilers detection.						  */
@@ -127,6 +130,7 @@
 #include <sstream>
 #include <numeric>
 #include <memory>
+#include <array>
 #include <locale.h>
 
 namespace std {
diff --git a/src/gmm/gmm_sub_index.h b/src/gmm/gmm_sub_index.h
index 395feb2..f1f0097 100644
--- a/src/gmm/gmm_sub_index.h
+++ b/src/gmm/gmm_sub_index.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_sub_matrix.h b/src/gmm/gmm_sub_matrix.h
index a3de001..e79883c 100644
--- a/src/gmm/gmm_sub_matrix.h
+++ b/src/gmm/gmm_sub_matrix.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -143,11 +143,11 @@ namespace gmm {
     typedef abstract_null_type col_iterator;
     typedef abstract_null_type const_sub_col_type;
     typedef abstract_null_type const_col_iterator;
-    typedef typename sub_vector_type<const typename
-            linalg_traits<M>::const_sub_row_type *, SUBI2>::vector_type
+    typedef typename sub_vector_type<const typename org_type<typename
+	    linalg_traits<M>::const_sub_row_type>::t *, SUBI2>::vector_type
             const_sub_row_type;
     typedef typename select_ref<abstract_null_type, 
-            typename sub_vector_type<typename linalg_traits<M>::sub_row_type *,
+	    typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_row_type>::t *,
 	    SUBI2>::vector_type, PT>::ref_type sub_row_type;
     typedef gen_sub_row_matrix_iterator<typename const_pointer<PT>::pointer,
 	    SUBI1, SUBI2> const_row_iterator;
@@ -290,12 +290,8 @@ namespace gmm {
     typedef abstract_null_type row_iterator;
     typedef abstract_null_type const_sub_row_type;
     typedef abstract_null_type const_row_iterator;
-    typedef typename sub_vector_type<const typename
-            linalg_traits<M>::const_sub_col_type *, SUBI1>::vector_type
-            const_sub_col_type;
-    typedef typename select_ref<abstract_null_type, 
-            typename sub_vector_type<typename linalg_traits<M>::sub_col_type *,
-	    SUBI1>::vector_type, PT>::ref_type sub_col_type;
+    typedef typename sub_vector_type<const typename org_type<typename linalg_traits<M>::const_sub_col_type>::t *, SUBI1>::vector_type const_sub_col_type;
+    typedef typename select_ref<abstract_null_type, typename sub_vector_type<typename org_type<typename linalg_traits<M>::sub_col_type>::t *, SUBI1>::vector_type, PT>::ref_type sub_col_type;
     typedef gen_sub_col_matrix_iterator<typename const_pointer<PT>::pointer,
 	    SUBI1, SUBI2> const_col_iterator;
     typedef typename select_ref<abstract_null_type, 
diff --git a/src/gmm/gmm_sub_vector.h b/src/gmm/gmm_sub_vector.h
index ee71dc5..d35f908 100644
--- a/src/gmm/gmm_sub_vector.h
+++ b/src/gmm/gmm_sub_vector.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_superlu_interface.h b/src/gmm/gmm_superlu_interface.h
index 0470cb5..b732445 100644
--- a/src/gmm/gmm_superlu_interface.h
+++ b/src/gmm/gmm_superlu_interface.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/src/gmm/gmm_transposed.h b/src/gmm/gmm_transposed.h
index b2b2cd5..d9b6a81 100644
--- a/src/gmm/gmm_transposed.h
+++ b/src/gmm/gmm_transposed.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -90,7 +90,7 @@ namespace gmm {
     typedef abstract_null_type const_row_iterator;
     typedef typename linalg_traits<M>::const_sub_row_type const_sub_col_type;
     typedef typename select_ref<abstract_null_type, typename
-            linalg_traits<M>::sub_row_type, PT>::ref_type sub_col_type;
+	    linalg_traits<M>::sub_row_type, PT>::ref_type sub_col_type;
     typedef typename linalg_traits<M>::const_row_iterator const_col_iterator;
     typedef typename select_ref<abstract_null_type, typename
             linalg_traits<M>::row_iterator, PT>::ref_type col_iterator;
@@ -171,7 +171,7 @@ namespace gmm {
     typedef abstract_null_type const_col_iterator;
     typedef typename linalg_traits<M>::const_sub_col_type const_sub_row_type;
     typedef typename select_ref<abstract_null_type, typename
-            linalg_traits<M>::sub_col_type, PT>::ref_type sub_row_type;
+	    linalg_traits<M>::sub_col_type, PT>::ref_type sub_row_type;
     typedef typename linalg_traits<M>::const_col_iterator const_row_iterator;
     typedef typename select_ref<abstract_null_type, typename
             linalg_traits<M>::col_iterator, PT>::ref_type row_iterator;
diff --git a/src/gmm/gmm_tri_solve.h b/src/gmm/gmm_tri_solve.h
index c28f01f..d05520e 100644
--- a/src/gmm/gmm_tri_solve.h
+++ b/src/gmm/gmm_tri_solve.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -44,12 +44,12 @@ namespace gmm {
 
   template <typename TriMatrix, typename VecX>
   void upper_tri_solve__(const TriMatrix& T, VecX& x, size_t k,
-				col_major, abstract_sparse, bool is_unit) {
+			 col_major, abstract_sparse, bool is_unit) {
     typename linalg_traits<TriMatrix>::value_type x_j;
     for (int j = int(k) - 1; j >= 0; --j) {
       typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
       COL c = mat_const_col(T, j);
-      typename linalg_traits<COL>::const_iterator 
+      typename linalg_traits<typename org_type<COL>::t>::const_iterator 
 	it = vect_const_begin(c), ite = vect_const_end(c);
       if (!is_unit) x[j] /= c[j];
       for (x_j = x[j]; it != ite ; ++it)
@@ -59,12 +59,12 @@ namespace gmm {
 
   template <typename TriMatrix, typename VecX>
   void upper_tri_solve__(const TriMatrix& T, VecX& x, size_t k,
-				col_major, abstract_dense, bool is_unit) {
+			 col_major, abstract_dense, bool is_unit) {
     typename linalg_traits<TriMatrix>::value_type x_j;
     for (int j = int(k) - 1; j >= 0; --j) {
       typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
       COL c = mat_const_col(T, j);
-      typename linalg_traits<COL>::const_iterator
+      typename linalg_traits<typename org_type<COL>::t>::const_iterator
 	it = vect_const_begin(c), ite = it + j;
       typename linalg_traits<VecX>::iterator itx = vect_begin(x);
       if (!is_unit) x[j] /= c[j];
@@ -74,14 +74,14 @@ namespace gmm {
 
   template <typename TriMatrix, typename VecX>
   void lower_tri_solve__(const TriMatrix& T, VecX& x, size_t k,
-				col_major, abstract_sparse, bool is_unit) {
+			 col_major, abstract_sparse, bool is_unit) {
     typename linalg_traits<TriMatrix>::value_type x_j;
     // cout << "(lower col)The Tri Matrix = " << T << endl;
     // cout << "k = " << endl;
     for (int j = 0; j < int(k); ++j) {
       typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
       COL c = mat_const_col(T, j);
-      typename linalg_traits<COL>::const_iterator 
+      typename linalg_traits<typename org_type<COL>::t>::const_iterator 
 	it = vect_const_begin(c), ite = vect_const_end(c);
       if (!is_unit) x[j] /= c[j];
       for (x_j = x[j]; it != ite ; ++it)
@@ -91,12 +91,12 @@ namespace gmm {
   
   template <typename TriMatrix, typename VecX>
   void lower_tri_solve__(const TriMatrix& T, VecX& x, size_t k,
-				col_major, abstract_dense, bool is_unit) {
+			 col_major, abstract_dense, bool is_unit) {
     typename linalg_traits<TriMatrix>::value_type x_j;
     for (int j = 0; j < int(k); ++j) {
       typedef typename linalg_traits<TriMatrix>::const_sub_col_type COL;
       COL c = mat_const_col(T, j);
-      typename linalg_traits<COL>::const_iterator 
+      typename linalg_traits<typename org_type<COL>::t>::const_iterator 
 	it = vect_const_begin(c) + (j+1), ite = vect_const_begin(c) + k;
       typename linalg_traits<VecX>::iterator itx = vect_begin(x) + (j+1);
       if (!is_unit) x[j] /= c[j];
@@ -107,7 +107,7 @@ namespace gmm {
 
   template <typename TriMatrix, typename VecX>
   void upper_tri_solve__(const TriMatrix& T, VecX& x, size_t k,
-				row_major, abstract_sparse, bool is_unit) {
+			 row_major, abstract_sparse, bool is_unit) {
     typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
     typename linalg_traits<TriMatrix>::value_type t;
     typename linalg_traits<TriMatrix>::const_row_iterator
@@ -115,7 +115,7 @@ namespace gmm {
     for (int i = int(k) - 1; i >= 0; --i) {
       --itr;
       ROW c = linalg_traits<TriMatrix>::row(itr);
-      typename linalg_traits<ROW>::const_iterator 
+      typename linalg_traits<typename org_type<ROW>::t>::const_iterator 
 	it = vect_const_begin(c), ite = vect_const_end(c);
       for (t = x[i]; it != ite; ++it)
 	if (int(it.index()) > i && it.index() < k) t -= (*it) * x[it.index()];
@@ -125,13 +125,13 @@ namespace gmm {
 
   template <typename TriMatrix, typename VecX>
   void upper_tri_solve__(const TriMatrix& T, VecX& x, size_t k,
-				row_major, abstract_dense, bool is_unit) {
+			 row_major, abstract_dense, bool is_unit) {
     typename linalg_traits<TriMatrix>::value_type t;
    
     for (int i = int(k) - 1; i >= 0; --i) {
       typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
       ROW c = mat_const_row(T, i);
-      typename linalg_traits<ROW>::const_iterator 
+      typename linalg_traits<typename org_type<ROW>::t>::const_iterator 
 	it = vect_const_begin(c) + (i + 1), ite = vect_const_begin(c) + k;
       typename linalg_traits<VecX>::iterator itx = vect_begin(x) + (i+1);
       
@@ -142,13 +142,13 @@ namespace gmm {
 
   template <typename TriMatrix, typename VecX>
   void lower_tri_solve__(const TriMatrix& T, VecX& x, size_t k,
-				row_major, abstract_sparse, bool is_unit) {
+			 row_major, abstract_sparse, bool is_unit) {
     typename linalg_traits<TriMatrix>::value_type t;
    
     for (int i = 0; i < int(k); ++i) {
       typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
       ROW c = mat_const_row(T, i);
-      typename linalg_traits<ROW>::const_iterator 
+      typename linalg_traits<typename org_type<ROW>::t>::const_iterator 
 	it = vect_const_begin(c), ite = vect_const_end(c);
 
       for (t = x[i]; it != ite; ++it)
@@ -159,13 +159,13 @@ namespace gmm {
 
   template <typename TriMatrix, typename VecX>
   void lower_tri_solve__(const TriMatrix& T, VecX& x, size_t k,
-				row_major, abstract_dense, bool is_unit) {
+			 row_major, abstract_dense, bool is_unit) {
     typename linalg_traits<TriMatrix>::value_type t;
    
     for (int i = 0; i < int(k); ++i) {
       typedef typename linalg_traits<TriMatrix>::const_sub_row_type ROW;
       ROW c = mat_const_row(T, i);
-      typename linalg_traits<ROW>::const_iterator 
+      typename linalg_traits<typename org_type<ROW>::t>::const_iterator 
 	it = vect_const_begin(c), ite = it + i;
       typename linalg_traits<VecX>::iterator itx = vect_begin(x);
 
diff --git a/src/gmm/gmm_vector.h b/src/gmm/gmm_vector.h
index a7a2f4e..e69931d 100644
--- a/src/gmm/gmm_vector.h
+++ b/src/gmm/gmm_vector.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard
+ Copyright (C) 2002-2017 Yves Renard
 
  This file is a part of GetFEM++
 
@@ -65,9 +65,9 @@ namespace gmm {
     inline bool operator !=(std::complex<T> v) const
     { return ((*pm).r(l) != v); }
     inline ref_elt_vector &operator +=(T v)
-    { (*pm).w(l,(*pm).r(l) + v); return *this; }
+    { (*pm).wa(l, v); return *this; }
     inline ref_elt_vector &operator -=(T v)
-    { (*pm).w(l,(*pm).r(l) - v); return *this; }
+    { (*pm).wa(l, -v); return *this; }
     inline ref_elt_vector &operator /=(T v)
     { (*pm).w(l,(*pm).r(l) / v); return *this; }
     inline ref_elt_vector &operator *=(T v)
@@ -209,11 +209,474 @@ namespace gmm {
   typename number_traits<T>::magnitude_type
   imag(const ref_elt_vector<T, V> &re) { return gmm::imag(T(re)); }
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* Class dsvector: sparse vector optimized for random write operations   */
+  /* with constant complexity for read and write operations.               */
+  /* Based on distribution sort principle.                                 */
+  /* Cheap for densely populated vectors.                                  */
+  /*                                                                       */
+  /*************************************************************************/
+
+  template<typename T> class dsvector;
+
+  template<typename T> struct dsvector_iterator {
+    size_type i;    // Current index.
+    T* p;           // Pointer to the current position.
+    dsvector<T> *v; // Pointer to the vector.
+    
+    typedef T                   value_type;
+    typedef value_type*         pointer;
+    typedef const value_type*   const_pointer;
+    typedef value_type&         reference;
+    // typedef size_t              size_type;
+    typedef ptrdiff_t           difference_type;
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef dsvector_iterator<T> iterator;
+    
+    reference operator *() const { return *p; }
+    pointer operator->() const { return &(operator*()); }
+
+    iterator &operator ++() {
+      for (size_type k = (i & 15); k < 15; ++k)
+	{ ++p; ++i; if (*p != T(0)) return *this; }
+      v->next_pos(*(const_cast<const_pointer *>(&(p))), i);
+      return *this;
+    }
+    iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; }
+    iterator &operator --() {
+      for (size_type k = (i & 15); k > 0; --k)
+	{ --p; --i; if (*p != T(0)) return *this; }
+      v->previous_pos(p, i);
+      return *this;
+    }
+    iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; }
+
+    bool operator ==(const iterator &it) const
+    { return (i == it.i && p == it.p && v == it.v); }
+    bool operator !=(const iterator &it) const
+    { return !(it == *this); }
+    
+    size_type index(void) const { return i; }
+
+    dsvector_iterator(void) : i(size_type(-1)), p(0), v(0) {}
+    dsvector_iterator(dsvector<T> &w) : i(size_type(-1)), p(0), v(&w) {};
+  };
+
+
+  template<typename T> struct dsvector_const_iterator {
+    size_type i;          // Current index.
+    const T* p;           // Pointer to the current position.
+    const dsvector<T> *v; // Pointer to the vector.
+    
+    typedef T                   value_type;
+    typedef const value_type*   pointer;
+    typedef const value_type&   reference;
+    // typedef size_t           size_type;
+    typedef ptrdiff_t           difference_type;
+    typedef std::bidirectional_iterator_tag iterator_category;
+    typedef dsvector_const_iterator<T> iterator;
+   
+    reference operator *() const { return *p; }
+    pointer operator->() const { return &(operator*()); }
+    iterator &operator ++() {
+      for (size_type k = (i & 15); k < 15; ++k)
+	{ ++p; ++i; if (*p != T(0)) return *this; }
+      v->next_pos(p, i);
+      return *this;
+    }
+    iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; }
+    iterator &operator --() {
+      for (size_type k = (i & 15); k > 0; --k)
+	{ --p; --i; if (*p != T(0)) return *this; }
+      v->previous_pos(p, i);
+      return *this;
+    }
+    iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; }
+
+    bool operator ==(const iterator &it) const
+    { return (i == it.i && p == it.p && v == it.v); }
+    bool operator !=(const iterator &it) const
+    { return !(it == *this); }
+    
+    size_type index(void) const { return i; }
+
+    dsvector_const_iterator(void) : i(size_type(-1)), p(0) {}
+    dsvector_const_iterator(const dsvector_iterator<T> &it)
+      : i(it.i), p(it.p), v(it.v) {}
+    dsvector_const_iterator(const dsvector<T> &w)
+      : i(size_type(-1)), p(0), v(&w) {};
+  };
+
   
+  /**
+     Sparse vector built on distribution sort principle.
+     Read and write access have a constant complexity depending only on the
+     vector size.
+  */
+  template<typename T> class dsvector {
+
+    typedef dsvector_iterator<T>       iterator;
+    typedef dsvector_const_iterator<T> const_iterator;
+    typedef dsvector<T>                this_type;
+    typedef T *                        pointer;
+    typedef const T *                  const_pointer;
+    typedef void *                     void_pointer;
+    typedef const void *               const_void_pointer;
+ 
+  protected:
+    size_type    n;         // Potential vector size
+    size_type    depth;     // Number of row of pointer arrays
+    size_type    mask;      // Mask for the first pointer array
+    size_type    shift;     // Shift for the first pointer array
+    void_pointer root_ptr;  // Root pointer
+
+    const T *read_access(size_type i) const {
+      GMM_ASSERT1(i < n, "index out of range");
+      size_type my_mask = mask, my_shift = shift;
+      void_pointer p = root_ptr;
+      if (!p) return 0;
+      for (size_type k = 0; k < depth; ++k) {
+	p = ((void **)(p))[(i & my_mask) >> my_shift];
+	if (!p) return 0;
+	my_mask = (my_mask >> 4);
+	my_shift -= 4;
+      }
+      GMM_ASSERT1(my_shift == 0, "internal error");
+      GMM_ASSERT1(my_mask == 15, "internal error");
+      return &(((const T *)(p))[i & 15]);
+    }
+
+    T *write_access(size_type i) {
+      GMM_ASSERT1(i < n, "index " << i << " out of range (size " << n << ")");
+      size_type my_mask = mask, my_shift = shift;
+      if (!root_ptr) {
+	if (depth) {
+	  root_ptr = new void_pointer[16];
+	  std::memset(root_ptr, 0, 16*sizeof(void_pointer));
+	} else {
+	  root_ptr = new T[16];
+	  for (size_type l = 0; l < 16; ++l) ((T *)(root_ptr))[l] = T(0);
+	}
+      }
+
+      void_pointer p = root_ptr;
+      for (size_type k = 0; k < depth; ++k) {
+	size_type j = (i & my_mask) >> my_shift;
+	void_pointer q = ((void_pointer *)(p))[j];
+	if (!q) {
+	  if (k+1 != depth) {
+	    q = new void_pointer[16];
+	    std::memset(q, 0, 16*sizeof(void_pointer));
+	  } else {
+	    q = new T[16];
+	    for (size_type l = 0; l < 16; ++l) ((T *)(q))[l] = T(0);
+	  }
+	  ((void_pointer *)(p))[j] = q;
+	}
+	p = q;
+	my_mask = (my_mask >> 4);
+	my_shift -= 4;
+      }
+      GMM_ASSERT1(my_shift == 0, "internal error");
+      GMM_ASSERT1(my_mask == 15, "internal error " << my_mask);
+      return &(((T *)(p))[i & 15]);
+    }
+
+    void init(size_type n_) {
+      n = n_; depth = 0; shift = 0; mask = 1; if (n_) --n_;
+      while (n_) { n_ /= 16; ++depth; shift += 4; mask *= 16; }
+      mask--; if (shift) shift -= 4; if (depth) --depth;
+      root_ptr = 0;
+    }
+
+    void rec_del(void_pointer p, size_type my_depth) {
+      if (my_depth) {
+	for (size_type k = 0; k < 16; ++k)
+	  if (((void_pointer *)(p))[k])
+	    rec_del(((void_pointer *)(p))[k], my_depth-1);
+	delete[] ((void_pointer *)(p));
+      } else {
+	delete[] ((T *)(p));
+      }
+    }
+
+    void rec_clean(void_pointer p, size_type my_depth, double eps) {
+      if (my_depth) {
+	for (size_type k = 0; k < 16; ++k)
+	  if (((void_pointer *)(p))[k])
+	    rec_clean(((void_pointer *)(p))[k], my_depth-1, eps);
+      } else {
+	for (size_type k = 0; k < 16; ++k)
+	  if (gmm::abs(((T *)(p))[k]) <= eps) ((T *)(p))[k] = T(0);
+      }
+    }
+
+    void rec_clean_i(void_pointer p, size_type my_depth, size_type my_mask,
+		     size_type i, size_type base) {
+      if (my_depth) {
+	my_mask = (my_mask >> 4);
+	for (size_type k = 0; k < 16; ++k)
+	  if (((void_pointer *)(p))[k] && (base + (k+1)*(mask+1)) >= i)
+	    rec_clean_i(((void_pointer *)(p))[k], my_depth-1, my_mask,
+			i, base + k*(my_mask+1));
+      } else {
+	for (size_type k = 0; k < 16; ++k)
+	  if (base+k > i) ((T *)(p))[k] = T(0);
+      }
+    }
+ 
+      
+    size_type rec_nnz(void_pointer p, size_type my_depth) const {
+      size_type nn = 0;
+      if (my_depth) {
+	for (size_type k = 0; k < 16; ++k)
+	  if (((void_pointer *)(p))[k])
+	    nn += rec_nnz(((void_pointer *)(p))[k], my_depth-1);
+      } else {
+	for (size_type k = 0; k < 16; ++k)
+	  if (((const T *)(p))[k] != T(0)) nn++;
+      }
+      return nn;
+    }
+
+    void copy_rec(void_pointer &p, const_void_pointer q, size_type my_depth) {
+      if (my_depth) {
+	p = new void_pointer[16];
+	std::memset(p, 0, 16*sizeof(void_pointer));
+	for (size_type l = 0; l < 16; ++l)
+	  if (((const const_void_pointer *)(q))[l])
+	    copy_rec(((void_pointer *)(p))[l],
+		     ((const const_void_pointer *)(q))[l], my_depth-1);
+      } else {
+	p = new T[16];
+	for (size_type l = 0; l < 16; ++l) ((T *)(p))[l] = ((const T *)(q))[l];
+      }
+    }
+
+    void copy(const dsvector<T> &v) {
+      if (root_ptr) rec_del(root_ptr, depth);
+      root_ptr = 0;
+      mask = v.mask; depth = v.depth; n = v.n; shift = v.shift;
+      if (v.root_ptr) copy_rec(root_ptr, v.root_ptr, depth);
+    }
+
+    void next_pos_rec(void_pointer p, size_type my_depth, size_type my_mask,
+		      const_pointer &pp, size_type &i, size_type base) const {
+      size_type ii = i;
+      if (my_depth) {
+	my_mask = (my_mask >> 4);
+	for (size_type k = 0; k < 16; ++k)
+	  if (((void_pointer *)(p))[k] && (base + (k+1)*(my_mask+1)) >= i) {
+	    next_pos_rec(((void_pointer *)(p))[k], my_depth-1, my_mask,
+			 pp, i, base + k*(my_mask+1));
+	    if (i != size_type(-1)) return; else i = ii;
+	}
+	i = size_type(-1); pp = 0;
+      } else {
+	for (size_type k = 0; k < 16; ++k)
+	  if (base+k > i && ((const_pointer)(p))[k] != T(0))
+	    { i = base+k; pp = &(((const_pointer)(p))[k]); return; }
+	i = size_type(-1); pp = 0;
+      }
+    }
+
+    void previous_pos_rec(void_pointer p, size_type my_depth, size_type my_mask,
+			  const_pointer &pp, size_type &i,
+			  size_type base) const {
+      size_type ii = i;
+      if (my_depth) {
+	my_mask = (my_mask >> 4);
+	for (size_type k = 15; k != size_type(-1); --k)
+	  if (((void_pointer *)(p))[k] && ((base + k*(my_mask+1)) < i)) {
+	    previous_pos_rec(((void_pointer *)(p))[k], my_depth-1,
+			     my_mask, pp, i, base + k*(my_mask+1));
+	    if (i != size_type(-1)) return; else i = ii;
+	}
+	i = size_type(-1); pp = 0;
+      } else {
+	for (size_type k = 15; k != size_type(-1); --k)
+	  if (base+k < i && ((const_pointer)(p))[k] != T(0))
+	    { i = base+k; pp = &(((const_pointer)(p))[k]); return; }
+	i = size_type(-1); pp = 0;
+      }
+    }
+    
+    
+  public:
+    void clean(double eps) { if (root_ptr) rec_clean(root_ptr, depth); }
+    void resize(size_type n_) {
+      if (n_ != n) {
+	n = n_;
+	if (n_ < n) { // Depth unchanged (a choice)
+	  if (root_ptr) rec_clean_i(root_ptr, depth, mask, n_, 0);
+	} else {
+	  // may change the depth (add some levels)
+	  size_type my_depth = 0, my_shift = 0, my_mask = 1; if (n_) --n_;
+	  while (n_) { n_ /= 16; ++my_depth; my_shift += 4; my_mask *= 16; }
+	  my_mask--; if (my_shift) my_shift -= 4; if (my_depth) --my_depth;
+	  if (my_depth > depth || depth == 0) {
+	    if (root_ptr) {
+	      for (size_type k = depth; k < my_depth; ++k) {
+		void_pointer *q = new void_pointer [16];
+		std::memset(q, 0, 16*sizeof(void_pointer));
+		q[0] = root_ptr; root_ptr = q;
+	      }
+	    }
+	    mask = my_mask; depth = my_depth; shift = my_shift;
+	  }
+	}
+      }
+    }
+    
+    void clear(void) { if (root_ptr) rec_del(root_ptr, depth); root_ptr = 0; }
+    
+    void next_pos(const_pointer &pp, size_type &i) const {
+      if (!root_ptr || i >= n) { pp = 0, i = size_type(-1); return; }
+      next_pos_rec(root_ptr, depth, mask, pp, i, 0);
+    }
+
+    void previous_pos(const_pointer &pp, size_type &i) const {
+      if (!root_ptr) { pp = 0, i = size_type(-1); return; }
+      if (i == size_type(-1)) { i = n; }
+      previous_pos_rec(root_ptr, depth, mask, pp, i, 0);
+    }
+
+    iterator begin(void) {
+      iterator it(*this); 
+      if (n && root_ptr) {
+	it.i = 0; it.p = const_cast<T *>(read_access(0));
+	if (!(it.p) || *(it.p) == T(0))
+	  next_pos(*(const_cast<const_pointer *>(&(it.p))), it.i);
+      }
+      return it;
+    }
 
+    iterator end(void) { return iterator(*this); }
+
+    const_iterator begin(void) const {
+      const_iterator it(*this);
+      if (n && root_ptr) {
+	it.i = 0; it.p = read_access(0);
+	if (!(it.p) || *(it.p) == T(0)) next_pos(it.p, it.i);
+      }
+      return it;
+    }
+
+    const_iterator end(void) const { return const_iterator(*this); }
+    
+    inline ref_elt_vector<T, dsvector<T> > operator [](size_type c)
+    { return ref_elt_vector<T, dsvector<T> >(this, c); }
+
+    inline void w(size_type c, const T &e) {
+      if (e == T(0)) { if (read_access(c)) *(write_access(c)) = e; }
+      else *(write_access(c)) = e;
+    }
+
+    inline void wa(size_type c, const T &e)
+    { if (e != T(0)) { *(write_access(c)) += e; } }
+
+    inline T r(size_type c) const
+    { const T *p = read_access(c); if (p) return *p; else return T(0); }
+
+    inline T operator [](size_type c) const { return r(c); }
+    
+    size_type nnz(void) const
+    { if (root_ptr) return rec_nnz(root_ptr, depth); else return 0; }
+    size_type size(void) const { return n; }
+
+    void swap(dsvector<T> &v) {
+      std::swap(n, v.n); std::swap(root_ptr, v.root_ptr);
+      std::swap(depth, v.depth); std::swap(shift, v.shift);
+      std::swap(mask, v.mask);
+    }
+    
+    /* Constructors */
+    dsvector(const dsvector<T> &v) { init(0); copy(v); }
+    dsvector<T> &operator =(const dsvector<T> &v) { copy(v); return *this; }
+    explicit dsvector(size_type l){ init(l); }
+    dsvector(void) { init(0); }
+    ~dsvector() { if (root_ptr) rec_del(root_ptr, depth); root_ptr = 0; }
+  };
+
+  template <typename T> struct linalg_traits<dsvector<T>> {
+    typedef dsvector<T> this_type;
+    typedef this_type origin_type;
+    typedef linalg_false is_reference;
+    typedef abstract_vector linalg_type;
+    typedef T value_type;
+    typedef ref_elt_vector<T, dsvector<T> > reference;
+    typedef dsvector_iterator<T>  iterator;
+    typedef dsvector_const_iterator<T> const_iterator;
+    typedef abstract_sparse storage_type;
+    typedef linalg_true index_sorted;
+    static size_type size(const this_type &v) { return v.size(); }
+    static iterator begin(this_type &v) { return v.begin(); }
+    static const_iterator begin(const this_type &v) { return v.begin(); }
+    static iterator end(this_type &v) { return v.end(); }
+    static const_iterator end(const this_type &v) { return v.end(); }
+    static origin_type* origin(this_type &v) { return &v; }
+    static const origin_type* origin(const this_type &v) { return &v; }
+    static void clear(origin_type* o, const iterator &, const iterator &)
+    { o->clear(); }
+    static void do_clear(this_type &v) { v.clear(); }
+    static value_type access(const origin_type *o, const const_iterator &,
+			     const const_iterator &, size_type i)
+    { return (*o)[i]; }
+    static reference access(origin_type *o, const iterator &, const iterator &,
+			    size_type i)
+    { return (*o)[i]; }
+    static void resize(this_type &v, size_type n) { v.resize(n); }
+  };
+
+  template<typename T> std::ostream &operator <<
+  (std::ostream &o, const dsvector<T>& v) { gmm::write(o,v); return o; }
+
+  /******* Optimized operations for dsvector<T> ****************************/
+
+  template <typename T> inline void copy(const dsvector<T> &v1,
+ 					 dsvector<T> &v2) {
+    GMM_ASSERT2(v1.size() == v2.size(), "dimensions mismatch");
+    v2 = v1;
+  }
+  template <typename T> inline void copy(const dsvector<T> &v1,
+					 const dsvector<T> &v2) {
+    GMM_ASSERT2(v1.size() == v2.size(), "dimensions mismatch");
+    v2 = const_cast<dsvector<T> &>(v1);
+  }
+ template <typename T> inline
+  void copy(const dsvector<T> &v1, const simple_vector_ref<dsvector<T> *> &v2){
+    simple_vector_ref<dsvector<T> *>
+      *svr = const_cast<simple_vector_ref<dsvector<T> *> *>(&v2);
+    dsvector<T>
+      *pv = const_cast<dsvector<T> *>((v2.origin));
+    GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch");
+    *pv = v1; svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv);
+  }
+  template <typename T> inline
+  void copy(const simple_vector_ref<const dsvector<T> *> &v1,
+	    dsvector<T> &v2)
+  { copy(*(v1.origin), v2); }
+  template <typename T> inline
+  void copy(const simple_vector_ref<dsvector<T> *> &v1, dsvector<T> &v2)
+  { copy(*(v1.origin), v2); }
+  template <typename T> inline
+  void copy(const simple_vector_ref<dsvector<T> *> &v1,
+	    const simple_vector_ref<dsvector<T> *> &v2)
+  { copy(*(v1.origin), v2); }
+  template <typename T> inline
+  void copy(const simple_vector_ref<const dsvector<T> *> &v1,
+	    const simple_vector_ref<dsvector<T> *> &v2)
+  { copy(*(v1.origin), v2); }
+  
+  template <typename T>
+  inline size_type nnz(const dsvector<T>& l) { return l.nnz(); }
+  
   /*************************************************************************/
   /*                                                                       */
-  /* Class wsvector: sparse vector optimized for random write operations.  */
+  /* Class wsvector: sparse vector optimized for random write operations,  */
+  /* with log(n) complexity for read and write operations.                 */
+  /* Based on std::map                                                     */
   /*                                                                       */
   /*************************************************************************/
   
@@ -284,6 +747,15 @@ namespace gmm {
       else base_type::operator [](c) = e;
     }
 
+    inline void wa(size_type c, const T &e) {
+      GMM_ASSERT2(c < nbl, "out of range");
+      if (e != T(0)) {
+	iterator it = this->lower_bound(c);
+	if (it != this->end() && it->first == c) it->second += e;
+	else base_type::operator [](c) = e;
+      }
+    }
+
     inline T r(size_type c) const {
       GMM_ASSERT2(c < nbl, "out of range");
       const_iterator it = this->lower_bound(c);
@@ -300,7 +772,7 @@ namespace gmm {
     { std::swap(nbl, v.nbl); std::map<size_type, T>::swap(v); }
 				       
 
-    /* Constructeurs */
+    /* Constructors */
     void init(size_type l) { nbl = l; this->clear(); }
     explicit wsvector(size_type l){ init(l); }
     wsvector(void) { init(0); }
@@ -407,7 +879,7 @@ namespace gmm {
 
   template<typename T> struct elt_rsvector_ {
     size_type c; T e;
-    /* e is initialized by default to avoid some false warnings of valgrind..
+    /* e is initialized by default to avoid some false warnings of valgrind.
        (from http://valgrind.org/docs/manual/mc-manual.html:
       
        When memory is read into the CPU's floating point registers, the
@@ -509,6 +981,7 @@ namespace gmm {
     { return ref_elt_vector<T, rsvector<T> >(this, c); }
 
     void w(size_type c, const T &e);
+    void wa(size_type c, const T &e);
     T r(size_type c) const;
     void swap_indices(size_type i, size_type j);
 
@@ -561,7 +1034,7 @@ namespace gmm {
       iterator it = std::lower_bound(this->begin(), this->end(), ev);
       if (it != this->end() && it->c == j) {
 	for (iterator ite = this->end() - 1; it != ite; ++it) *it = *(it+1);
-	base_type_::resize(nb_stored()-1);
+	base_resize(nb_stored()-1);
       }
     }
   }
@@ -580,21 +1053,48 @@ namespace gmm {
     else {
       elt_rsvector_<T> ev(c, e);
       if (nb_stored() == 0) {
-	base_type_::resize(1,ev);
+	base_type_::push_back(ev);
       }
       else {
 	iterator it = std::lower_bound(this->begin(), this->end(), ev);
 	if (it != this->end() && it->c == c) it->e = e;
 	else {
-	  size_type ind = it - this->begin();
-          if (this->nb_stored() - ind > 800)
+	  size_type ind = it - this->begin(), nb = this->nb_stored();
+          if (nb - ind > 1100)
             GMM_WARNING2("Inefficient addition of element in rsvector with "
                          << this->nb_stored() - ind << " non-zero entries");
-	  base_type_::resize(nb_stored()+1, ev);
-	  if (ind != this->nb_stored() - 1) {
+	  base_type_::push_back(ev);
+	  if (ind != nb) {
 	    it = this->begin() + ind;
-	    for (iterator ite = this->end() - 1; ite != it; --ite)
-	      *ite = *(ite-1);
+	    iterator ite = this->end(); --ite; iterator itee = ite; 
+	    for (; ite != it; --ite) { --itee; *ite = *itee; }
+	    *it = ev;
+	  }
+	}
+      }
+    }
+  }
+
+  template <typename T> void rsvector<T>::wa(size_type c, const T &e) {
+    GMM_ASSERT2(c < nbl, "out of range");
+    if (e != T(0)) {
+      elt_rsvector_<T> ev(c, e);
+      if (nb_stored() == 0) {
+	base_type_::push_back(ev);
+      }
+      else {
+	iterator it = std::lower_bound(this->begin(), this->end(), ev);
+	if (it != this->end() && it->c == c) it->e += e;
+	else {
+	  size_type ind = it - this->begin(), nb = this->nb_stored();
+          if (nb - ind > 1100)
+            GMM_WARNING2("Inefficient addition of element in rsvector with "
+                         << this->nb_stored() - ind << " non-zero entries");
+	  base_type_::push_back(ev);
+	  if (ind != nb) {
+	    it = this->begin() + ind;
+	    iterator ite = this->end(); --ite; iterator itee = ite; 
+	    for (; ite != it; --ite) { --itee; *ite = *itee; }
 	    *it = ev;
 	  }
 	}
@@ -603,7 +1103,8 @@ namespace gmm {
   }
   
   template <typename T> T rsvector<T>::r(size_type c) const {
-    GMM_ASSERT2(c < nbl, "out of range. Index " << c << " for a length of " << nbl);
+    GMM_ASSERT2(c < nbl, "out of range. Index " << c 
+		<< " for a length of " << nbl);
     if (nb_stored() != 0) {
       elt_rsvector_<T> ev(c);
       const_iterator it = std::lower_bound(this->begin(), this->end(), ev);
@@ -940,6 +1441,7 @@ namespace gmm {
       { return data.end(); }
 
     void w(size_type c, const T &e);
+    void wa(size_type c, const T &e);
     T r(size_type c) const {
       GMM_ASSERT2(c < size_, "out of range");
       if (c < shift || c >= shift + data.size()) return T(0);
@@ -983,11 +1485,35 @@ namespace gmm {
       shift = c;
     }
     else if (c >= shift + s) {
-      data.resize(c - shift + 1);
-      std::fill(data.begin() + s, data.end(), T(0));
+      data.resize(c - shift + 1, T(0));
+      // std::fill(data.begin() + s, data.end(), T(0));
     }
     data[c - shift] = e;
   }
+
+  template<typename T>  void slvector<T>::wa(size_type c, const T &e) {
+    GMM_ASSERT2(c < size_, "out of range");
+    size_type s = data.size();
+    if (!s) { data.resize(1, e); shift = c; return; }
+    else if (c < shift) {
+      data.resize(s + shift - c); 
+      typename std::vector<T>::iterator it = data.begin(),it2=data.end()-1;
+      typename std::vector<T>::iterator it3 = it2 - shift + c;
+      for (; it3 >= it; --it3, --it2) *it2 = *it3;
+      std::fill(it, it + shift - c, T(0));
+      shift = c;
+      data[c - shift] = e;
+      return;
+    }
+    else if (c >= shift + s) {
+      data.resize(c - shift + 1, T(0));
+      data[c - shift] = e;
+      return;
+      // std::fill(data.begin() + s, data.end(), T(0));
+    }
+    data[c - shift] += e;
+  }
+  
   
   template <typename T> struct linalg_traits<slvector<T> > {
     typedef slvector<T> this_type;
diff --git a/src/gmm/gmm_vector_to_matrix.h b/src/gmm/gmm_vector_to_matrix.h
index 3640846..83fc0c5 100644
--- a/src/gmm/gmm_vector_to_matrix.h
+++ b/src/gmm/gmm_vector_to_matrix.h
@@ -1,7 +1,7 @@
 /* -*- c++ -*- (enables emacs c++ mode) */
 /*===========================================================================
 
- Copyright (C) 2003-2016 Yves Renard
+ Copyright (C) 2003-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/superlu/BLAS.c b/superlu/BLAS.c
index 08e334e..4a31245 100644
--- a/superlu/BLAS.c
+++ b/superlu/BLAS.c
@@ -1,8 +1,46 @@
-/* BLAS.f -- translated by f2c (version 20020621).
+/* BLAS.f -- translated by f2c
    You must link the resulting object file with the libraries:
 	-lf2c -lm   (in that order)
 
    the f2c-ed file has been slightly modified (removal of lsame_, added r_sign)
+
+   Original fortran source files are distributed along with this package in the sub-directory BLAS
+*/
+
+/*
+
+  The reference BLAS is a freely-available software package. It is available from netlib via anonymous ftp
+  and the World Wide Web. Thus, it can be included in commercial software packages (and has been). We only
+  ask that proper credit be given to the authors.
+
+  Like all software, it is copyrighted. It is not trademarked, but we do ask the following:
+
+  If you modify the source for these routines we ask that you change the name of the routine and comment
+  the changes made to the original.
+
+  We will gladly answer any questions regarding the software. If a modification is done, however, it is the
+  responsibility of the person who modified the routine to provide support.
+
+  see https://www.openhub.net/licenses/blas
+*/
+
+/* Copyright (C) 2004-2006 Julien Pommier
+
+  This file is a part of GetFEM++
+
+  GetFEM++  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 along with the GCC Runtime Library
+  Exception either version 3.1 or (at your option) any later version.
+  This program  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 and GCC Runtime Library Exception for more details.
+  You  should  have received a copy of the GNU Lesser General Public License
+  along  with  this program;  if not, write to the Free Software Foundation,
+  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 */
 
 #include "BLAS_f2c.h"
diff --git a/superlu/BLAS/License.txt b/superlu/BLAS/License.txt
new file mode 100644
index 0000000..b7ca013
--- /dev/null
+++ b/superlu/BLAS/License.txt
@@ -0,0 +1,14 @@
+  The reference BLAS is a freely-available software package. It is available from netlib via anonymous ftp
+  and the World Wide Web. Thus, it can be included in commercial software packages (and has been). We only
+  ask that proper credit be given to the authors.
+
+  Like all software, it is copyrighted. It is not trademarked, but we do ask the following:
+
+  If you modify the source for these routines we ask that you change the name of the routine and comment
+  the changes made to the original.
+
+  We will gladly answer any questions regarding the software. If a modification is done, however, it is the
+  responsibility of the person who modified the routine to provide support.
+
+  see https://www.openhub.net/licenses/blas
+
diff --git a/superlu/BLAS/caxpy.f b/superlu/BLAS/caxpy.f
new file mode 100644
index 0000000..7ee7774
--- /dev/null
+++ b/superlu/BLAS/caxpy.f
@@ -0,0 +1,102 @@
+*> \brief \b CAXPY
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CAXPY(N,CA,CX,INCX,CY,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX CA
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX CX(*),CY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    CAXPY constant times a vector plus a vector.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CAXPY(N,CA,CX,INCX,CY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX CA
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY
+*     ..
+*     .. External Functions ..
+      REAL SCABS1
+      EXTERNAL SCABS1
+*     ..
+      IF (N.LE.0) RETURN
+      IF (SCABS1(CA).EQ.0.0E+0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1,N
+            CY(I) = CY(I) + CA*CX(I)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            CY(IY) = CY(IY) + CA*CX(IX)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+*
+      RETURN
+      END
diff --git a/superlu/BLAS/ccopy.f b/superlu/BLAS/ccopy.f
new file mode 100644
index 0000000..eeb5f29
--- /dev/null
+++ b/superlu/BLAS/ccopy.f
@@ -0,0 +1,94 @@
+*> \brief \b CCOPY
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CCOPY(N,CX,INCX,CY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX CX(*),CY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    CCOPY copies a vector x to a vector y.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CCOPY(N,CX,INCX,CY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1,N
+            CY(I) = CX(I)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            CY(IY) = CX(IX)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/cdotc.f b/superlu/BLAS/cdotc.f
new file mode 100644
index 0000000..cd34169
--- /dev/null
+++ b/superlu/BLAS/cdotc.f
@@ -0,0 +1,103 @@
+*> \brief \b CDOTC
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       COMPLEX FUNCTION CDOTC(N,CX,INCX,CY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX CX(*),CY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CDOTC forms the dot product of two complex vectors
+*>      CDOTC = X^H * Y
+*>
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack,  3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      COMPLEX FUNCTION CDOTC(N,CX,INCX,CY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      COMPLEX CTEMP
+      INTEGER I,IX,IY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG
+*     ..
+      CTEMP = (0.0,0.0)
+      CDOTC = (0.0,0.0)
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1,N
+            CTEMP = CTEMP + CONJG(CX(I))*CY(I)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            CTEMP = CTEMP + CONJG(CX(IX))*CY(IY)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      CDOTC = CTEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/cdotu.f b/superlu/BLAS/cdotu.f
new file mode 100644
index 0000000..1e127bc
--- /dev/null
+++ b/superlu/BLAS/cdotu.f
@@ -0,0 +1,100 @@
+*> \brief \b CDOTU
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       COMPLEX FUNCTION CDOTU(N,CX,INCX,CY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX CX(*),CY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CDOTU forms the dot product of two complex vectors
+*>      CDOTU = X^T * Y
+*>
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      COMPLEX FUNCTION CDOTU(N,CX,INCX,CY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      COMPLEX CTEMP
+      INTEGER I,IX,IY
+*     ..
+      CTEMP = (0.0,0.0)
+      CDOTU = (0.0,0.0)
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1,N
+            CTEMP = CTEMP + CX(I)*CY(I)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            CTEMP = CTEMP + CX(IX)*CY(IY)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      CDOTU = CTEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/cgbmv.f b/superlu/BLAS/cgbmv.f
new file mode 100644
index 0000000..de12852
--- /dev/null
+++ b/superlu/BLAS/cgbmv.f
@@ -0,0 +1,390 @@
+*> \brief \b CGBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CGBMV(TRANS,M,N,KL,KU,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER INCX,INCY,KL,KU,LDA,M,N
+*       CHARACTER TRANS
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CGBMV  performs one of the matrix-vector operations
+*>
+*>    y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,   or
+*>
+*>    y := alpha*A**H*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are vectors and A is an
+*> m by n band matrix, with kl sub-diagonals and ku super-diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*>
+*>              TRANS = 'T' or 't'   y := alpha*A**T*x + beta*y.
+*>
+*>              TRANS = 'C' or 'c'   y := alpha*A**H*x + beta*y.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] KL
+*> \verbatim
+*>          KL is INTEGER
+*>           On entry, KL specifies the number of sub-diagonals of the
+*>           matrix A. KL must satisfy  0 .le. KL.
+*> \endverbatim
+*>
+*> \param[in] KU
+*> \verbatim
+*>          KU is INTEGER
+*>           On entry, KU specifies the number of super-diagonals of the
+*>           matrix A. KU must satisfy  0 .le. KU.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading ( kl + ku + 1 ) by n part of the
+*>           array A must contain the matrix of coefficients, supplied
+*>           column by column, with the leading diagonal of the matrix in
+*>           row ( ku + 1 ) of the array, the first super-diagonal
+*>           starting at position 2 in row ku, the first sub-diagonal
+*>           starting at position 1 in row ( ku + 2 ), and so on.
+*>           Elements in the array A that do not correspond to elements
+*>           in the band matrix (such as the top left ku by ku triangle)
+*>           are not referenced.
+*>           The following program segment will transfer a band matrix
+*>           from conventional full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    K = KU + 1 - J
+*>                    DO 10, I = MAX( 1, J - KU ), MIN( M, J + KL )
+*>                       A( K + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( kl + ku + 1 ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX array of DIMENSION at least
+*>           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*>           Before entry, the incremented array Y must contain the
+*>           vector y. On exit, Y is overwritten by the updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CGBMV(TRANS,M,N,KL,KU,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER INCX,INCY,KL,KU,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KUP1,KX,KY,LENX,LENY
+      LOGICAL NOCONJ
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (KL.LT.0) THEN
+          INFO = 4
+      ELSE IF (KU.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (KL+KU+1)) THEN
+          INFO = 8
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 10
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CGBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the band part of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      KUP1 = KU + 1
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  K = KUP1 - J
+                  DO 50 I = MAX(1,J-KU),MIN(M,J+KL)
+                      Y(I) = Y(I) + TEMP*A(K+I,J)
+   50             CONTINUE
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  IY = KY
+                  K = KUP1 - J
+                  DO 70 I = MAX(1,J-KU),MIN(M,J+KL)
+                      Y(IY) = Y(IY) + TEMP*A(K+I,J)
+                      IY = IY + INCY
+   70             CONTINUE
+                  JX = JX + INCX
+                  IF (J.GT.KU) KY = KY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A**T*x + y  or  y := alpha*A**H*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 110 J = 1,N
+                  TEMP = ZERO
+                  K = KUP1 - J
+                  IF (NOCONJ) THEN
+                      DO 90 I = MAX(1,J-KU),MIN(M,J+KL)
+                          TEMP = TEMP + A(K+I,J)*X(I)
+   90                 CONTINUE
+                  ELSE
+                      DO 100 I = MAX(1,J-KU),MIN(M,J+KL)
+                          TEMP = TEMP + CONJG(A(K+I,J))*X(I)
+  100                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  110         CONTINUE
+          ELSE
+              DO 140 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  K = KUP1 - J
+                  IF (NOCONJ) THEN
+                      DO 120 I = MAX(1,J-KU),MIN(M,J+KL)
+                          TEMP = TEMP + A(K+I,J)*X(IX)
+                          IX = IX + INCX
+  120                 CONTINUE
+                  ELSE
+                      DO 130 I = MAX(1,J-KU),MIN(M,J+KL)
+                          TEMP = TEMP + CONJG(A(K+I,J))*X(IX)
+                          IX = IX + INCX
+  130                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+                  IF (J.GT.KU) KX = KX + INCX
+  140         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CGBMV .
+*
+      END
diff --git a/superlu/BLAS/cgemm.f b/superlu/BLAS/cgemm.f
new file mode 100644
index 0000000..018ffad
--- /dev/null
+++ b/superlu/BLAS/cgemm.f
@@ -0,0 +1,483 @@
+*> \brief \b CGEMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER K,LDA,LDB,LDC,M,N
+*       CHARACTER TRANSA,TRANSB
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CGEMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*op( A )*op( B ) + beta*C,
+*>
+*> where  op( X ) is one of
+*>
+*>    op( X ) = X   or   op( X ) = X**T   or   op( X ) = X**H,
+*>
+*> alpha and beta are scalars, and A, B and C are matrices, with op( A )
+*> an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n',  op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't',  op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c',  op( A ) = A**H.
+*> \endverbatim
+*>
+*> \param[in] TRANSB
+*> \verbatim
+*>          TRANSB is CHARACTER*1
+*>           On entry, TRANSB specifies the form of op( B ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSB = 'N' or 'n',  op( B ) = B.
+*>
+*>              TRANSB = 'T' or 't',  op( B ) = B**T.
+*>
+*>              TRANSB = 'C' or 'c',  op( B ) = B**H.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies  the number  of rows  of the  matrix
+*>           op( A )  and of the  matrix  C.  M  must  be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N  specifies the number  of columns of the matrix
+*>           op( B ) and the number of columns of the matrix C. N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry,  K  specifies  the number of columns of the matrix
+*>           op( A ) and the number of rows of the matrix op( B ). K must
+*>           be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANSA = 'N' or 'n',  and is  m  otherwise.
+*>           Before entry with  TRANSA = 'N' or 'n',  the leading  m by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by m  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. When  TRANSA = 'N' or 'n' then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX array of DIMENSION ( LDB, kb ), where kb is
+*>           n  when  TRANSB = 'N' or 'n',  and is  k  otherwise.
+*>           Before entry with  TRANSB = 'N' or 'n',  the leading  k by n
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  n by k  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in the calling (sub) program. When  TRANSB = 'N' or 'n' then
+*>           LDB must be at least  max( 1, k ), otherwise  LDB must be at
+*>           least  max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n  matrix
+*>           ( alpha*op( A )*op( B ) + beta*C ).
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,M,N
+      CHARACTER TRANSA,TRANSB
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,J,L,NCOLA,NROWA,NROWB
+      LOGICAL CONJA,CONJB,NOTA,NOTB
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not
+*     conjugated or transposed, set  CONJA and CONJB  as true if  A  and
+*     B  respectively are to be  transposed but  not conjugated  and set
+*     NROWA, NCOLA and  NROWB  as the number of rows and  columns  of  A
+*     and the number of rows of  B  respectively.
+*
+      NOTA = LSAME(TRANSA,'N')
+      NOTB = LSAME(TRANSB,'N')
+      CONJA = LSAME(TRANSA,'C')
+      CONJB = LSAME(TRANSB,'C')
+      IF (NOTA) THEN
+          NROWA = M
+          NCOLA = K
+      ELSE
+          NROWA = K
+          NCOLA = M
+      END IF
+      IF (NOTB) THEN
+          NROWB = K
+      ELSE
+          NROWB = N
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.NOTA) .AND. (.NOT.CONJA) .AND.
+     +    (.NOT.LSAME(TRANSA,'T'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.NOTB) .AND. (.NOT.CONJB) .AND.
+     +         (.NOT.LSAME(TRANSB,'T'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 8
+      ELSE IF (LDB.LT.MAX(1,NROWB)) THEN
+          INFO = 10
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CGEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (NOTB) THEN
+          IF (NOTA) THEN
+*
+*           Form  C := alpha*A*B + beta*C.
+*
+              DO 90 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 50 I = 1,M
+                          C(I,J) = ZERO
+   50                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 60 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+   60                 CONTINUE
+                  END IF
+                  DO 80 L = 1,K
+                      TEMP = ALPHA*B(L,J)
+                      DO 70 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+   70                 CONTINUE
+   80             CONTINUE
+   90         CONTINUE
+          ELSE IF (CONJA) THEN
+*
+*           Form  C := alpha*A**H*B + beta*C.
+*
+              DO 120 J = 1,N
+                  DO 110 I = 1,M
+                      TEMP = ZERO
+                      DO 100 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*B(L,J)
+  100                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  110             CONTINUE
+  120         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**T*B + beta*C
+*
+              DO 150 J = 1,N
+                  DO 140 I = 1,M
+                      TEMP = ZERO
+                      DO 130 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(L,J)
+  130                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  140             CONTINUE
+  150         CONTINUE
+          END IF
+      ELSE IF (NOTA) THEN
+          IF (CONJB) THEN
+*
+*           Form  C := alpha*A*B**H + beta*C.
+*
+              DO 200 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 160 I = 1,M
+                          C(I,J) = ZERO
+  160                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 170 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+  170                 CONTINUE
+                  END IF
+                  DO 190 L = 1,K
+                      TEMP = ALPHA*CONJG(B(J,L))
+                      DO 180 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+  180                 CONTINUE
+  190             CONTINUE
+  200         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A*B**T + beta*C
+*
+              DO 250 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 210 I = 1,M
+                          C(I,J) = ZERO
+  210                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 220 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+  220                 CONTINUE
+                  END IF
+                  DO 240 L = 1,K
+                      TEMP = ALPHA*B(J,L)
+                      DO 230 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+  230                 CONTINUE
+  240             CONTINUE
+  250         CONTINUE
+          END IF
+      ELSE IF (CONJA) THEN
+          IF (CONJB) THEN
+*
+*           Form  C := alpha*A**H*B**H + beta*C.
+*
+              DO 280 J = 1,N
+                  DO 270 I = 1,M
+                      TEMP = ZERO
+                      DO 260 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*CONJG(B(J,L))
+  260                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  270             CONTINUE
+  280         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**H*B**T + beta*C
+*
+              DO 310 J = 1,N
+                  DO 300 I = 1,M
+                      TEMP = ZERO
+                      DO 290 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*B(J,L)
+  290                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  300             CONTINUE
+  310         CONTINUE
+          END IF
+      ELSE
+          IF (CONJB) THEN
+*
+*           Form  C := alpha*A**T*B**H + beta*C
+*
+              DO 340 J = 1,N
+                  DO 330 I = 1,M
+                      TEMP = ZERO
+                      DO 320 L = 1,K
+                          TEMP = TEMP + A(L,I)*CONJG(B(J,L))
+  320                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  330             CONTINUE
+  340         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**T*B**T + beta*C
+*
+              DO 370 J = 1,N
+                  DO 360 I = 1,M
+                      TEMP = ZERO
+                      DO 350 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(J,L)
+  350                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  360             CONTINUE
+  370         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CGEMM .
+*
+      END
diff --git a/superlu/BLAS/cgemv.f b/superlu/BLAS/cgemv.f
new file mode 100644
index 0000000..aeb9409
--- /dev/null
+++ b/superlu/BLAS/cgemv.f
@@ -0,0 +1,350 @@
+*> \brief \b CGEMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER INCX,INCY,LDA,M,N
+*       CHARACTER TRANS
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CGEMV performs one of the matrix-vector operations
+*>
+*>    y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,   or
+*>
+*>    y := alpha*A**H*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are vectors and A is an
+*> m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*>
+*>              TRANS = 'T' or 't'   y := alpha*A**T*x + beta*y.
+*>
+*>              TRANS = 'C' or 'c'   y := alpha*A**H*x + beta*y.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX array of DIMENSION at least
+*>           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*>           Before entry with BETA non-zero, the incremented array Y
+*>           must contain the vector y. On exit, Y is overwritten by the
+*>           updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER INCX,INCY,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY,LENX,LENY
+      LOGICAL NOCONJ
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CGEMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  DO 50 I = 1,M
+                      Y(I) = Y(I) + TEMP*A(I,J)
+   50             CONTINUE
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  IY = KY
+                  DO 70 I = 1,M
+                      Y(IY) = Y(IY) + TEMP*A(I,J)
+                      IY = IY + INCY
+   70             CONTINUE
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A**T*x + y  or  y := alpha*A**H*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 110 J = 1,N
+                  TEMP = ZERO
+                  IF (NOCONJ) THEN
+                      DO 90 I = 1,M
+                          TEMP = TEMP + A(I,J)*X(I)
+   90                 CONTINUE
+                  ELSE
+                      DO 100 I = 1,M
+                          TEMP = TEMP + CONJG(A(I,J))*X(I)
+  100                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  110         CONTINUE
+          ELSE
+              DO 140 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  IF (NOCONJ) THEN
+                      DO 120 I = 1,M
+                          TEMP = TEMP + A(I,J)*X(IX)
+                          IX = IX + INCX
+  120                 CONTINUE
+                  ELSE
+                      DO 130 I = 1,M
+                          TEMP = TEMP + CONJG(A(I,J))*X(IX)
+                          IX = IX + INCX
+  130                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  140         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CGEMV .
+*
+      END
diff --git a/superlu/BLAS/cgerc.f b/superlu/BLAS/cgerc.f
new file mode 100644
index 0000000..e730edf
--- /dev/null
+++ b/superlu/BLAS/cgerc.f
@@ -0,0 +1,227 @@
+*> \brief \b CGERC
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CGERC(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA
+*       INTEGER INCX,INCY,LDA,M,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CGERC  performs the rank 1 operation
+*>
+*>    A := alpha*x*y**H + A,
+*>
+*> where alpha is a scalar, x is an m element vector, y is an n element
+*> vector and A is an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the m
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients. On exit, A is
+*>           overwritten by the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CGERC(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER INCX,INCY,LDA,M,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JY,KX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (M.LT.0) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CGERC ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (INCY.GT.0) THEN
+          JY = 1
+      ELSE
+          JY = 1 - (N-1)*INCY
+      END IF
+      IF (INCX.EQ.1) THEN
+          DO 20 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*CONJG(Y(JY))
+                  DO 10 I = 1,M
+                      A(I,J) = A(I,J) + X(I)*TEMP
+   10             CONTINUE
+              END IF
+              JY = JY + INCY
+   20     CONTINUE
+      ELSE
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (M-1)*INCX
+          END IF
+          DO 40 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*CONJG(Y(JY))
+                  IX = KX
+                  DO 30 I = 1,M
+                      A(I,J) = A(I,J) + X(IX)*TEMP
+                      IX = IX + INCX
+   30             CONTINUE
+              END IF
+              JY = JY + INCY
+   40     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CGERC .
+*
+      END
diff --git a/superlu/BLAS/cgeru.f b/superlu/BLAS/cgeru.f
new file mode 100644
index 0000000..bc7540f
--- /dev/null
+++ b/superlu/BLAS/cgeru.f
@@ -0,0 +1,227 @@
+*> \brief \b CGERU
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CGERU(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA
+*       INTEGER INCX,INCY,LDA,M,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CGERU  performs the rank 1 operation
+*>
+*>    A := alpha*x*y**T + A,
+*>
+*> where alpha is a scalar, x is an m element vector, y is an n element
+*> vector and A is an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the m
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients. On exit, A is
+*>           overwritten by the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CGERU(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER INCX,INCY,LDA,M,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JY,KX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (M.LT.0) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CGERU ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (INCY.GT.0) THEN
+          JY = 1
+      ELSE
+          JY = 1 - (N-1)*INCY
+      END IF
+      IF (INCX.EQ.1) THEN
+          DO 20 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  DO 10 I = 1,M
+                      A(I,J) = A(I,J) + X(I)*TEMP
+   10             CONTINUE
+              END IF
+              JY = JY + INCY
+   20     CONTINUE
+      ELSE
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (M-1)*INCX
+          END IF
+          DO 40 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  IX = KX
+                  DO 30 I = 1,M
+                      A(I,J) = A(I,J) + X(IX)*TEMP
+                      IX = IX + INCX
+   30             CONTINUE
+              END IF
+              JY = JY + INCY
+   40     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CGERU .
+*
+      END
diff --git a/superlu/BLAS/chbmv.f b/superlu/BLAS/chbmv.f
new file mode 100644
index 0000000..435c8dd
--- /dev/null
+++ b/superlu/BLAS/chbmv.f
@@ -0,0 +1,380 @@
+*> \brief \b CHBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER INCX,INCY,K,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHBMV  performs the matrix-vector  operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n hermitian band matrix, with k super-diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the band matrix A is being supplied as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  being supplied.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  being supplied.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry, K specifies the number of super-diagonals of the
+*>           matrix A. K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the hermitian matrix, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer the upper
+*>           triangular part of a hermitian band matrix from conventional
+*>           full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the hermitian matrix, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer the lower
+*>           triangular part of a hermitian band matrix from conventional
+*>           full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set and are assumed to be zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the
+*>           vector y. On exit, Y is overwritten by the updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER INCX,INCY,K,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KPLUS1,KX,KY,L
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,MIN,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (K.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of the array A
+*     are accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when upper triangle of A is stored.
+*
+          KPLUS1 = K + 1
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  L = KPLUS1 - J
+                  DO 50 I = MAX(1,J-K),J - 1
+                      Y(I) = Y(I) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + CONJG(A(L+I,J))*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*REAL(A(KPLUS1,J)) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  L = KPLUS1 - J
+                  DO 70 I = MAX(1,J-K),J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + CONJG(A(L+I,J))*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*REAL(A(KPLUS1,J)) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  IF (J.GT.K) THEN
+                      KX = KX + INCX
+                      KY = KY + INCY
+                  END IF
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when lower triangle of A is stored.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*REAL(A(1,J))
+                  L = 1 - J
+                  DO 90 I = J + 1,MIN(N,J+K)
+                      Y(I) = Y(I) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + CONJG(A(L+I,J))*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*REAL(A(1,J))
+                  L = 1 - J
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,MIN(N,J+K)
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + CONJG(A(L+I,J))*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHBMV .
+*
+      END
diff --git a/superlu/BLAS/chemm.f b/superlu/BLAS/chemm.f
new file mode 100644
index 0000000..834b209
--- /dev/null
+++ b/superlu/BLAS/chemm.f
@@ -0,0 +1,371 @@
+*> \brief \b CHEMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHEMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER LDA,LDB,LDC,M,N
+*       CHARACTER SIDE,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHEMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*A*B + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*B*A + beta*C,
+*>
+*> where alpha and beta are scalars, A is an hermitian matrix and  B and
+*> C are m by n matrices.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE  specifies whether  the  hermitian matrix  A
+*>           appears on the  left or right  in the  operation as follows:
+*>
+*>              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*>
+*>              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of  the  hermitian  matrix   A  is  to  be
+*>           referenced as follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*>                                  hermitian matrix is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*>                                  hermitian matrix is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies the number of rows of the matrix  C.
+*>           M  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix C.
+*>           N  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, ka ), where ka is
+*>           m  when  SIDE = 'L' or 'l'  and is n  otherwise.
+*>           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*>           the array  A  must contain the  hermitian matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  hermitian matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  m by m  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  hermitian
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*>           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*>           the array  A  must contain the  hermitian matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  hermitian matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  n by n  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  hermitian
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*>           Note that the imaginary parts  of the diagonal elements need
+*>           not be set, they are assumed to be zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the  calling (sub) program. When  SIDE = 'L' or 'l'  then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX array of DIMENSION ( LDB, n ).
+*>           Before entry, the leading  m by n part of the array  B  must
+*>           contain the matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n updated
+*>           matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHEMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*CONJG(A(K,I))
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*REAL(A(I,I)) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*REAL(A(I,I)) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*CONJG(A(K,I))
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*REAL(A(I,I)) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*REAL(A(I,I)) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*REAL(A(J,J))
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*CONJG(A(J,K))
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*CONJG(A(J,K))
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CHEMM .
+*
+      END
diff --git a/superlu/BLAS/chemv.f b/superlu/BLAS/chemv.f
new file mode 100644
index 0000000..2150929
--- /dev/null
+++ b/superlu/BLAS/chemv.f
@@ -0,0 +1,337 @@
+*> \brief \b CHEMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHEMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER INCX,INCY,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHEMV  performs the matrix-vector  operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n hermitian matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the hermitian matrix and the strictly
+*>           lower triangular part of A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the hermitian matrix and the strictly
+*>           upper triangular part of A is not referenced.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set and are assumed to be zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y. On exit, Y is overwritten by the updated
+*>           vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHEMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 5
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHEMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when A is stored in upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + CONJG(A(I,J))*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*REAL(A(J,J)) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 I = 1,J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + CONJG(A(I,J))*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*REAL(A(J,J)) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when A is stored in lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*REAL(A(J,J))
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + CONJG(A(I,J))*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*REAL(A(J,J))
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,N
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + CONJG(A(I,J))*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHEMV .
+*
+      END
diff --git a/superlu/BLAS/cher.f b/superlu/BLAS/cher.f
new file mode 100644
index 0000000..78a4e0b
--- /dev/null
+++ b/superlu/BLAS/cher.f
@@ -0,0 +1,278 @@
+*> \brief \b CHER
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHER(UPLO,N,ALPHA,X,INCX,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA
+*       INTEGER INCX,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHER   performs the hermitian rank 1 operation
+*>
+*>    A := alpha*x*x**H + A,
+*>
+*> where alpha is a real scalar, x is an n element vector and A is an
+*> n by n hermitian matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the hermitian matrix and the strictly
+*>           lower triangular part of A is not referenced. On exit, the
+*>           upper triangular part of the array A is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the hermitian matrix and the strictly
+*>           upper triangular part of A is not referenced. On exit, the
+*>           lower triangular part of the array A is overwritten by the
+*>           lower triangular part of the updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set, they are assumed to be zero, and on exit they
+*>           are set to zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHER(UPLO,N,ALPHA,X,INCX,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHER  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.REAL(ZERO))) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in upper triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(J))
+                      DO 10 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   10                 CONTINUE
+                      A(J,J) = REAL(A(J,J)) + REAL(X(J)*TEMP)
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(JX))
+                      IX = KX
+                      DO 30 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                      A(J,J) = REAL(A(J,J)) + REAL(X(JX)*TEMP)
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+                  JX = JX + INCX
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in lower triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(J))
+                      A(J,J) = REAL(A(J,J)) + REAL(TEMP*X(J))
+                      DO 50 I = J + 1,N
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   50                 CONTINUE
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(JX))
+                      A(J,J) = REAL(A(J,J)) + REAL(TEMP*X(JX))
+                      IX = JX
+                      DO 70 I = J + 1,N
+                          IX = IX + INCX
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+   70                 CONTINUE
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHER  .
+*
+      END
diff --git a/superlu/BLAS/cher2.f b/superlu/BLAS/cher2.f
new file mode 100644
index 0000000..fd65f97
--- /dev/null
+++ b/superlu/BLAS/cher2.f
@@ -0,0 +1,317 @@
+*> \brief \b CHER2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHER2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA
+*       INTEGER INCX,INCY,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHER2  performs the hermitian rank 2 operation
+*>
+*>    A := alpha*x*y**H + conjg( alpha )*y*x**H + A,
+*>
+*> where alpha is a scalar, x and y are n element vectors and A is an n
+*> by n hermitian matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the hermitian matrix and the strictly
+*>           lower triangular part of A is not referenced. On exit, the
+*>           upper triangular part of the array A is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the hermitian matrix and the strictly
+*>           upper triangular part of A is not referenced. On exit, the
+*>           lower triangular part of the array A is overwritten by the
+*>           lower triangular part of the updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set, they are assumed to be zero, and on exit they
+*>           are set to zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHER2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHER2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(J))
+                      TEMP2 = CONJG(ALPHA*X(J))
+                      DO 10 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   10                 CONTINUE
+                      A(J,J) = REAL(A(J,J)) +
+     +                         REAL(X(J)*TEMP1+Y(J)*TEMP2)
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(JY))
+                      TEMP2 = CONJG(ALPHA*X(JX))
+                      IX = KX
+                      IY = KY
+                      DO 30 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                      A(J,J) = REAL(A(J,J)) +
+     +                         REAL(X(JX)*TEMP1+Y(JY)*TEMP2)
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(J))
+                      TEMP2 = CONJG(ALPHA*X(J))
+                      A(J,J) = REAL(A(J,J)) +
+     +                         REAL(X(J)*TEMP1+Y(J)*TEMP2)
+                      DO 50 I = J + 1,N
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   50                 CONTINUE
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(JY))
+                      TEMP2 = CONJG(ALPHA*X(JX))
+                      A(J,J) = REAL(A(J,J)) +
+     +                         REAL(X(JX)*TEMP1+Y(JY)*TEMP2)
+                      IX = JX
+                      IY = JY
+                      DO 70 I = J + 1,N
+                          IX = IX + INCX
+                          IY = IY + INCY
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+   70                 CONTINUE
+                  ELSE
+                      A(J,J) = REAL(A(J,J))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHER2 .
+*
+      END
diff --git a/superlu/BLAS/cher2k.f b/superlu/BLAS/cher2k.f
new file mode 100644
index 0000000..ace3c5d
--- /dev/null
+++ b/superlu/BLAS/cher2k.f
@@ -0,0 +1,442 @@
+*> \brief \b CHER2K
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHER2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA
+*       REAL BETA
+*       INTEGER K,LDA,LDB,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHER2K  performs one of the hermitian rank 2k operations
+*>
+*>    C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C,
+*>
+*> where  alpha and beta  are scalars with  beta  real,  C is an  n by n
+*> hermitian matrix and  A and B  are  n by k matrices in the first case
+*> and  k by n  matrices in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'    C := alpha*A*B**H          +
+*>                                         conjg( alpha )*B*A**H +
+*>                                         beta*C.
+*>
+*>              TRANS = 'C' or 'c'    C := alpha*A**H*B          +
+*>                                         conjg( alpha )*B**H*A +
+*>                                         beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns  of the  matrices  A and B,  and on  entry  with
+*>           TRANS = 'C' or 'c',  K  specifies  the number of rows of the
+*>           matrices  A and B.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX array of DIMENSION ( LDB, kb ), where kb is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  k by n  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  hermitian matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  hermitian matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set,  they are assumed to be zero,  and on exit they
+*>           are set to zero.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*>
+*>  -- Modified 8-Nov-93 to set C(J,J) to REAL( C(J,J) ) when BETA = 1.
+*>     Ed Anderson, Cray Research Inc.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHER2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      REAL BETA
+      INTEGER K,LDA,LDB,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,REAL
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE
+      PARAMETER (ONE=1.0E+0)
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHER2K',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.REAL(ZERO)) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.REAL(ZERO)) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      C(J,J) = BETA*REAL(C(J,J))
+                      DO 70 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*B**H + conjg( alpha )*B*A**H +
+*                   C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.REAL(ZERO)) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+                  ELSE
+                      C(J,J) = REAL(C(J,J))
+                  END IF
+                  DO 120 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*CONJG(B(J,L))
+                          TEMP2 = CONJG(ALPHA*A(J,L))
+                          DO 110 I = 1,J - 1
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  110                     CONTINUE
+                          C(J,J) = REAL(C(J,J)) +
+     +                             REAL(A(J,L)*TEMP1+B(J,L)*TEMP2)
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.REAL(ZERO)) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+                  ELSE
+                      C(J,J) = REAL(C(J,J))
+                  END IF
+                  DO 170 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*CONJG(B(J,L))
+                          TEMP2 = CONJG(ALPHA*A(J,L))
+                          DO 160 I = J + 1,N
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  160                     CONTINUE
+                          C(J,J) = REAL(C(J,J)) +
+     +                             REAL(A(J,L)*TEMP1+B(J,L)*TEMP2)
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**H*B + conjg( alpha )*B**H*A +
+*                   C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 190 L = 1,K
+                          TEMP1 = TEMP1 + CONJG(A(L,I))*B(L,J)
+                          TEMP2 = TEMP2 + CONJG(B(L,I))*A(L,J)
+  190                 CONTINUE
+                      IF (I.EQ.J) THEN
+                          IF (BETA.EQ.REAL(ZERO)) THEN
+                              C(J,J) = REAL(ALPHA*TEMP1+
+     +                                 CONJG(ALPHA)*TEMP2)
+                          ELSE
+                              C(J,J) = BETA*REAL(C(J,J)) +
+     +                                 REAL(ALPHA*TEMP1+
+     +                                 CONJG(ALPHA)*TEMP2)
+                          END IF
+                      ELSE
+                          IF (BETA.EQ.REAL(ZERO)) THEN
+                              C(I,J) = ALPHA*TEMP1 + CONJG(ALPHA)*TEMP2
+                          ELSE
+                              C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                                 CONJG(ALPHA)*TEMP2
+                          END IF
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 220 L = 1,K
+                          TEMP1 = TEMP1 + CONJG(A(L,I))*B(L,J)
+                          TEMP2 = TEMP2 + CONJG(B(L,I))*A(L,J)
+  220                 CONTINUE
+                      IF (I.EQ.J) THEN
+                          IF (BETA.EQ.REAL(ZERO)) THEN
+                              C(J,J) = REAL(ALPHA*TEMP1+
+     +                                 CONJG(ALPHA)*TEMP2)
+                          ELSE
+                              C(J,J) = BETA*REAL(C(J,J)) +
+     +                                 REAL(ALPHA*TEMP1+
+     +                                 CONJG(ALPHA)*TEMP2)
+                          END IF
+                      ELSE
+                          IF (BETA.EQ.REAL(ZERO)) THEN
+                              C(I,J) = ALPHA*TEMP1 + CONJG(ALPHA)*TEMP2
+                          ELSE
+                              C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                                 CONJG(ALPHA)*TEMP2
+                          END IF
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHER2K.
+*
+      END
diff --git a/superlu/BLAS/cherk.f b/superlu/BLAS/cherk.f
new file mode 100644
index 0000000..1c47e57
--- /dev/null
+++ b/superlu/BLAS/cherk.f
@@ -0,0 +1,396 @@
+*> \brief \b CHERK
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHERK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER K,LDA,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHERK  performs one of the hermitian rank k operations
+*>
+*>    C := alpha*A*A**H + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**H*A + beta*C,
+*>
+*> where  alpha and beta  are  real scalars,  C is an  n by n  hermitian
+*> matrix and  A  is an  n by k  matrix in the  first case and a  k by n
+*> matrix in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   C := alpha*A*A**H + beta*C.
+*>
+*>              TRANS = 'C' or 'c'   C := alpha*A**H*A + beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns   of  the   matrix   A,   and  on   entry   with
+*>           TRANS = 'C' or 'c',  K  specifies  the number of rows of the
+*>           matrix A.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  hermitian matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  hermitian matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set,  they are assumed to be zero,  and on exit they
+*>           are set to zero.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*>
+*>  -- Modified 8-Nov-93 to set C(J,J) to REAL( C(J,J) ) when BETA = 1.
+*>     Ed Anderson, Cray Research Inc.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHERK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CMPLX,CONJG,MAX,REAL
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      REAL RTEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHERK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      C(J,J) = BETA*REAL(C(J,J))
+                      DO 70 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*A**H + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                      C(J,J) = BETA*REAL(C(J,J))
+                  ELSE
+                      C(J,J) = REAL(C(J,J))
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.CMPLX(ZERO)) THEN
+                          TEMP = ALPHA*CONJG(A(J,L))
+                          DO 110 I = 1,J - 1
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                          C(J,J) = REAL(C(J,J)) + REAL(TEMP*A(I,L))
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      C(J,J) = BETA*REAL(C(J,J))
+                      DO 150 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  ELSE
+                      C(J,J) = REAL(C(J,J))
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.CMPLX(ZERO)) THEN
+                          TEMP = ALPHA*CONJG(A(J,L))
+                          C(J,J) = REAL(C(J,J)) + REAL(TEMP*A(J,L))
+                          DO 160 I = J + 1,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**H*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 220 J = 1,N
+                  DO 200 I = 1,J - 1
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+                  RTEMP = ZERO
+                  DO 210 L = 1,K
+                      RTEMP = RTEMP + CONJG(A(L,J))*A(L,J)
+  210             CONTINUE
+                  IF (BETA.EQ.ZERO) THEN
+                      C(J,J) = ALPHA*RTEMP
+                  ELSE
+                      C(J,J) = ALPHA*RTEMP + BETA*REAL(C(J,J))
+                  END IF
+  220         CONTINUE
+          ELSE
+              DO 260 J = 1,N
+                  RTEMP = ZERO
+                  DO 230 L = 1,K
+                      RTEMP = RTEMP + CONJG(A(L,J))*A(L,J)
+  230             CONTINUE
+                  IF (BETA.EQ.ZERO) THEN
+                      C(J,J) = ALPHA*RTEMP
+                  ELSE
+                      C(J,J) = ALPHA*RTEMP + BETA*REAL(C(J,J))
+                  END IF
+                  DO 250 I = J + 1,N
+                      TEMP = ZERO
+                      DO 240 L = 1,K
+                          TEMP = TEMP + CONJG(A(L,I))*A(L,J)
+  240                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  250             CONTINUE
+  260         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHERK .
+*
+      END
diff --git a/superlu/BLAS/chpmv.f b/superlu/BLAS/chpmv.f
new file mode 100644
index 0000000..b182bfb
--- /dev/null
+++ b/superlu/BLAS/chpmv.f
@@ -0,0 +1,338 @@
+*> \brief \b CHPMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER INCX,INCY,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX AP(*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHPMV  performs the matrix-vector operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n hermitian matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is COMPLEX array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set and are assumed to be zero.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y. On exit, Y is overwritten by the updated
+*>           vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER INCX,INCY,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX AP(*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 6
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHPMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when AP contains the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  K = KK
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + CONJG(AP(K))*X(I)
+                      K = K + 1
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*REAL(AP(KK+J-1)) + ALPHA*TEMP2
+                  KK = KK + J
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 K = KK,KK + J - 2
+                      Y(IY) = Y(IY) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + CONJG(AP(K))*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*REAL(AP(KK+J-1)) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + J
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when AP contains the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*REAL(AP(KK))
+                  K = KK + 1
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + CONJG(AP(K))*X(I)
+                      K = K + 1
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+                  KK = KK + (N-J+1)
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*REAL(AP(KK))
+                  IX = JX
+                  IY = JY
+                  DO 110 K = KK + 1,KK + N - J
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + CONJG(AP(K))*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + (N-J+1)
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHPMV .
+*
+      END
diff --git a/superlu/BLAS/chpr.f b/superlu/BLAS/chpr.f
new file mode 100644
index 0000000..6212c04
--- /dev/null
+++ b/superlu/BLAS/chpr.f
@@ -0,0 +1,279 @@
+*> \brief \b CHPR
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHPR(UPLO,N,ALPHA,X,INCX,AP)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA
+*       INTEGER INCX,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHPR    performs the hermitian rank 1 operation
+*>
+*>    A := alpha*x*x**H + A,
+*>
+*> where alpha is a real scalar, x is an n element vector and A is an
+*> n by n hermitian matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] AP
+*> \verbatim
+*>          AP is COMPLEX array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the upper triangular part of the
+*>           updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the lower triangular part of the
+*>           updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set, they are assumed to be zero, and on exit they
+*>           are set to zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHPR(UPLO,N,ALPHA,X,INCX,AP)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHPR  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.REAL(ZERO))) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when upper triangle is stored in AP.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(J))
+                      K = KK
+                      DO 10 I = 1,J - 1
+                          AP(K) = AP(K) + X(I)*TEMP
+                          K = K + 1
+   10                 CONTINUE
+                      AP(KK+J-1) = REAL(AP(KK+J-1)) + REAL(X(J)*TEMP)
+                  ELSE
+                      AP(KK+J-1) = REAL(AP(KK+J-1))
+                  END IF
+                  KK = KK + J
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(JX))
+                      IX = KX
+                      DO 30 K = KK,KK + J - 2
+                          AP(K) = AP(K) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                      AP(KK+J-1) = REAL(AP(KK+J-1)) + REAL(X(JX)*TEMP)
+                  ELSE
+                      AP(KK+J-1) = REAL(AP(KK+J-1))
+                  END IF
+                  JX = JX + INCX
+                  KK = KK + J
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when lower triangle is stored in AP.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(J))
+                      AP(KK) = REAL(AP(KK)) + REAL(TEMP*X(J))
+                      K = KK + 1
+                      DO 50 I = J + 1,N
+                          AP(K) = AP(K) + X(I)*TEMP
+                          K = K + 1
+   50                 CONTINUE
+                  ELSE
+                      AP(KK) = REAL(AP(KK))
+                  END IF
+                  KK = KK + N - J + 1
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*CONJG(X(JX))
+                      AP(KK) = REAL(AP(KK)) + REAL(TEMP*X(JX))
+                      IX = JX
+                      DO 70 K = KK + 1,KK + N - J
+                          IX = IX + INCX
+                          AP(K) = AP(K) + X(IX)*TEMP
+   70                 CONTINUE
+                  ELSE
+                      AP(KK) = REAL(AP(KK))
+                  END IF
+                  JX = JX + INCX
+                  KK = KK + N - J + 1
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHPR  .
+*
+      END
diff --git a/superlu/BLAS/chpr2.f b/superlu/BLAS/chpr2.f
new file mode 100644
index 0000000..3ca388a
--- /dev/null
+++ b/superlu/BLAS/chpr2.f
@@ -0,0 +1,318 @@
+*> \brief \b CHPR2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CHPR2(UPLO,N,ALPHA,X,INCX,Y,INCY,AP)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA
+*       INTEGER INCX,INCY,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX AP(*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CHPR2  performs the hermitian rank 2 operation
+*>
+*>    A := alpha*x*y**H + conjg( alpha )*y*x**H + A,
+*>
+*> where alpha is a scalar, x and y are n element vectors and A is an
+*> n by n hermitian matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] AP
+*> \verbatim
+*>          AP is COMPLEX array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the upper triangular part of the
+*>           updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the lower triangular part of the
+*>           updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set, they are assumed to be zero, and on exit they
+*>           are set to zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CHPR2(UPLO,N,ALPHA,X,INCX,Y,INCY,AP)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER INCX,INCY,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX AP(*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,REAL
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CHPR2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when upper triangle is stored in AP.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(J))
+                      TEMP2 = CONJG(ALPHA*X(J))
+                      K = KK
+                      DO 10 I = 1,J - 1
+                          AP(K) = AP(K) + X(I)*TEMP1 + Y(I)*TEMP2
+                          K = K + 1
+   10                 CONTINUE
+                      AP(KK+J-1) = REAL(AP(KK+J-1)) +
+     +                             REAL(X(J)*TEMP1+Y(J)*TEMP2)
+                  ELSE
+                      AP(KK+J-1) = REAL(AP(KK+J-1))
+                  END IF
+                  KK = KK + J
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(JY))
+                      TEMP2 = CONJG(ALPHA*X(JX))
+                      IX = KX
+                      IY = KY
+                      DO 30 K = KK,KK + J - 2
+                          AP(K) = AP(K) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                      AP(KK+J-1) = REAL(AP(KK+J-1)) +
+     +                             REAL(X(JX)*TEMP1+Y(JY)*TEMP2)
+                  ELSE
+                      AP(KK+J-1) = REAL(AP(KK+J-1))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + J
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when lower triangle is stored in AP.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(J))
+                      TEMP2 = CONJG(ALPHA*X(J))
+                      AP(KK) = REAL(AP(KK)) +
+     +                         REAL(X(J)*TEMP1+Y(J)*TEMP2)
+                      K = KK + 1
+                      DO 50 I = J + 1,N
+                          AP(K) = AP(K) + X(I)*TEMP1 + Y(I)*TEMP2
+                          K = K + 1
+   50                 CONTINUE
+                  ELSE
+                      AP(KK) = REAL(AP(KK))
+                  END IF
+                  KK = KK + N - J + 1
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*CONJG(Y(JY))
+                      TEMP2 = CONJG(ALPHA*X(JX))
+                      AP(KK) = REAL(AP(KK)) +
+     +                         REAL(X(JX)*TEMP1+Y(JY)*TEMP2)
+                      IX = JX
+                      IY = JY
+                      DO 70 K = KK + 1,KK + N - J
+                          IX = IX + INCX
+                          IY = IY + INCY
+                          AP(K) = AP(K) + X(IX)*TEMP1 + Y(IY)*TEMP2
+   70                 CONTINUE
+                  ELSE
+                      AP(KK) = REAL(AP(KK))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + N - J + 1
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CHPR2 .
+*
+      END
diff --git a/superlu/BLAS/crotg.f b/superlu/BLAS/crotg.f
new file mode 100644
index 0000000..1cdb662
--- /dev/null
+++ b/superlu/BLAS/crotg.f
@@ -0,0 +1,74 @@
+*> \brief \b CROTG
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CROTG(CA,CB,C,S)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX CA,CB,S
+*       REAL C
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CROTG determines a complex Givens rotation.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level1
+*
+*  =====================================================================
+      SUBROUTINE CROTG(CA,CB,C,S)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX CA,CB,S
+      REAL C
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      COMPLEX ALPHA
+      REAL NORM,SCALE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CABS,CONJG,SQRT
+*     ..
+      IF (CABS(CA).EQ.0.) THEN
+         C = 0.
+         S = (1.,0.)
+         CA = CB
+      ELSE
+         SCALE = CABS(CA) + CABS(CB)
+         NORM = SCALE*SQRT((CABS(CA/SCALE))**2+ (CABS(CB/SCALE))**2)
+         ALPHA = CA/CABS(CA)
+         C = CABS(CA)/NORM
+         S = ALPHA*CONJG(CB)/NORM
+         CA = ALPHA*NORM
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/cscal.f b/superlu/BLAS/cscal.f
new file mode 100644
index 0000000..1405a97
--- /dev/null
+++ b/superlu/BLAS/cscal.f
@@ -0,0 +1,91 @@
+*> \brief \b CSCAL
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CSCAL(N,CA,CX,INCX)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX CA
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX CX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    CSCAL scales a vector by a constant.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack,  3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CSCAL(N,CA,CX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX CA
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,NINCX
+*     ..
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         DO I = 1,N
+            CX(I) = CA*CX(I)
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            CX(I) = CA*CX(I)
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/csrot.f b/superlu/BLAS/csrot.f
new file mode 100644
index 0000000..aa8564e
--- /dev/null
+++ b/superlu/BLAS/csrot.f
@@ -0,0 +1,153 @@
+*> \brief \b CSROT
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CSROT( N, CX, INCX, CY, INCY, C, S )
+*
+*       .. Scalar Arguments ..
+*       INTEGER           INCX, INCY, N
+*       REAL              C, S
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX           CX( * ), CY( * )
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CSROT applies a plane rotation, where the cos and sin (c and s) are real
+*> and the vectors cx and cy are complex.
+*> jack dongarra, linpack, 3/11/78.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the vectors cx and cy.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in,out] CX
+*> \verbatim
+*>          CX is COMPLEX array, dimension at least
+*>           ( 1 + ( N - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array CX must contain the n
+*>           element vector cx. On exit, CX is overwritten by the updated
+*>           vector cx.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           CX. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] CY
+*> \verbatim
+*>          CY is COMPLEX array, dimension at least
+*>           ( 1 + ( N - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array CY must contain the n
+*>           element vector cy. On exit, CY is overwritten by the updated
+*>           vector cy.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           CY. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in] C
+*> \verbatim
+*>          C is REAL
+*>           On entry, C specifies the cosine, cos.
+*> \endverbatim
+*>
+*> \param[in] S
+*> \verbatim
+*>          S is REAL
+*>           On entry, S specifies the sine, sin.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level1
+*
+*  =====================================================================
+      SUBROUTINE CSROT( N, CX, INCX, CY, INCY, C, S )
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER           INCX, INCY, N
+      REAL              C, S
+*     ..
+*     .. Array Arguments ..
+      COMPLEX           CX( * ), CY( * )
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER           I, IX, IY
+      COMPLEX           CTEMP
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.0 )
+     $   RETURN
+      IF( INCX.EQ.1 .AND. INCY.EQ.1 ) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1, N
+            CTEMP = C*CX( I ) + S*CY( I )
+            CY( I ) = C*CY( I ) - S*CX( I )
+            CX( I ) = CTEMP
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments not equal
+*          to 1
+*
+         IX = 1
+         IY = 1
+         IF( INCX.LT.0 )
+     $      IX = ( -N+1 )*INCX + 1
+         IF( INCY.LT.0 )
+     $      IY = ( -N+1 )*INCY + 1
+         DO I = 1, N
+            CTEMP = C*CX( IX ) + S*CY( IY )
+            CY( IY ) = C*CY( IY ) - S*CX( IX )
+            CX( IX ) = CTEMP
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/csscal.f b/superlu/BLAS/csscal.f
new file mode 100644
index 0000000..dc02654
--- /dev/null
+++ b/superlu/BLAS/csscal.f
@@ -0,0 +1,94 @@
+*> \brief \b CSSCAL
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CSSCAL(N,SA,CX,INCX)
+*
+*       .. Scalar Arguments ..
+*       REAL SA
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX CX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    CSSCAL scales a complex vector by a real constant.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CSSCAL(N,SA,CX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL SA
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC AIMAG,CMPLX,REAL
+*     ..
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         DO I = 1,N
+            CX(I) = CMPLX(SA*REAL(CX(I)),SA*AIMAG(CX(I)))
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            CX(I) = CMPLX(SA*REAL(CX(I)),SA*AIMAG(CX(I)))
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/cswap.f b/superlu/BLAS/cswap.f
new file mode 100644
index 0000000..369a294
--- /dev/null
+++ b/superlu/BLAS/cswap.f
@@ -0,0 +1,98 @@
+*> \brief \b CSWAP
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CSWAP(N,CX,INCX,CY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX CX(*),CY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>   CSWAP interchanges two vectors.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CSWAP(N,CX,INCX,CY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*),CY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      COMPLEX CTEMP
+      INTEGER I,IX,IY
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*       code for both increments equal to 1
+         DO I = 1,N
+            CTEMP = CX(I)
+            CX(I) = CY(I)
+            CY(I) = CTEMP
+         END DO
+      ELSE
+*
+*       code for unequal increments or equal increments not equal
+*         to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            CTEMP = CX(IX)
+            CX(IX) = CY(IY)
+            CY(IY) = CTEMP
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/csymm.f b/superlu/BLAS/csymm.f
new file mode 100644
index 0000000..906a572
--- /dev/null
+++ b/superlu/BLAS/csymm.f
@@ -0,0 +1,369 @@
+*> \brief \b CSYMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER LDA,LDB,LDC,M,N
+*       CHARACTER SIDE,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CSYMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*A*B + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*B*A + beta*C,
+*>
+*> where  alpha and beta are scalars, A is a symmetric matrix and  B and
+*> C are m by n matrices.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE  specifies whether  the  symmetric matrix  A
+*>           appears on the  left or right  in the  operation as follows:
+*>
+*>              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*>
+*>              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of  the  symmetric  matrix   A  is  to  be
+*>           referenced as follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*>                                  symmetric matrix is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*>                                  symmetric matrix is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies the number of rows of the matrix  C.
+*>           M  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix C.
+*>           N  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, ka ), where ka is
+*>           m  when  SIDE = 'L' or 'l'  and is n  otherwise.
+*>           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*>           the array  A  must contain the  symmetric matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  symmetric matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  m by m  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  symmetric
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*>           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*>           the array  A  must contain the  symmetric matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  symmetric matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  n by n  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  symmetric
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the  calling (sub) program. When  SIDE = 'L' or 'l'  then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX array of DIMENSION ( LDB, n ).
+*>           Before entry, the leading  m by n part of the array  B  must
+*>           contain the matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n updated
+*>           matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CSYMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*A(J,J)
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*A(J,K)
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(J,K)
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of CSYMM .
+*
+      END
diff --git a/superlu/BLAS/csyr2k.f b/superlu/BLAS/csyr2k.f
new file mode 100644
index 0000000..1fdeadc
--- /dev/null
+++ b/superlu/BLAS/csyr2k.f
@@ -0,0 +1,396 @@
+*> \brief \b CSYR2K
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CSYR2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER K,LDA,LDB,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CSYR2K  performs one of the symmetric rank 2k operations
+*>
+*>    C := alpha*A*B**T + alpha*B*A**T + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**T*B + alpha*B**T*A + beta*C,
+*>
+*> where  alpha and beta  are scalars,  C is an  n by n symmetric matrix
+*> and  A and B  are  n by k  matrices  in the  first  case  and  k by n
+*> matrices in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'    C := alpha*A*B**T + alpha*B*A**T +
+*>                                         beta*C.
+*>
+*>              TRANS = 'T' or 't'    C := alpha*A**T*B + alpha*B**T*A +
+*>                                         beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns  of the  matrices  A and B,  and on  entry  with
+*>           TRANS = 'T' or 't',  K  specifies  the number of rows of the
+*>           matrices  A and B.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX array of DIMENSION ( LDB, kb ), where kb is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  k by n  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CSYR2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP1,TEMP2
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CSYR2K',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*B**T + alpha*B*A**T + C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**T*B + alpha*B**T*A + C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 190 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 220 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CSYR2K.
+*
+      END
diff --git a/superlu/BLAS/csyrk.f b/superlu/BLAS/csyrk.f
new file mode 100644
index 0000000..c4494c5
--- /dev/null
+++ b/superlu/BLAS/csyrk.f
@@ -0,0 +1,363 @@
+*> \brief \b CSYRK
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA,BETA
+*       INTEGER K,LDA,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CSYRK  performs one of the symmetric rank k operations
+*>
+*>    C := alpha*A*A**T + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**T*A + beta*C,
+*>
+*> where  alpha and beta  are scalars,  C is an  n by n symmetric matrix
+*> and  A  is an  n by k  matrix in the first case and a  k by n  matrix
+*> in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   C := alpha*A*A**T + beta*C.
+*>
+*>              TRANS = 'T' or 't'   C := alpha*A**T*A + beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns   of  the   matrix   A,   and  on   entry   with
+*>           TRANS = 'T' or 't',  K  specifies  the number of rows of the
+*>           matrix A.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CSYRK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*A**T + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**T*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP = ZERO
+                      DO 220 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CSYRK .
+*
+      END
diff --git a/superlu/BLAS/ctbmv.f b/superlu/BLAS/ctbmv.f
new file mode 100644
index 0000000..1513c1a
--- /dev/null
+++ b/superlu/BLAS/ctbmv.f
@@ -0,0 +1,429 @@
+*> \brief \b CTBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CTBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,K,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CTBMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,   or   x := A**H*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular band matrix, with ( k + 1 ) diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**H*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with UPLO = 'U' or 'u', K specifies the number of
+*>           super-diagonals of the matrix A.
+*>           On entry with UPLO = 'L' or 'l', K specifies the number of
+*>           sub-diagonals of the matrix A.
+*>           K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer an upper
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer a lower
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that when DIAG = 'U' or 'u' the elements of the array A
+*>           corresponding to the diagonal elements of the matrix are not
+*>           referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CTBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX   too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*         Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          L = KPLUS1 - J
+                          DO 10 I = MAX(1,J-K),J - 1
+                              X(I) = X(I) + TEMP*A(L+I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(KPLUS1,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          L = KPLUS1 - J
+                          DO 30 I = MAX(1,J-K),J - 1
+                              X(IX) = X(IX) + TEMP*A(L+I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(KPLUS1,J)
+                      END IF
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          L = 1 - J
+                          DO 50 I = MIN(N,J+K),J + 1,-1
+                              X(I) = X(I) + TEMP*A(L+I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(1,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          L = 1 - J
+                          DO 70 I = MIN(N,J+K),J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(L+I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(1,J)
+                      END IF
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x  or  x := A**H*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = N,1,-1
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)
+                          DO 90 I = J - 1,MAX(1,J-K),-1
+                              TEMP = TEMP + A(L+I,J)*X(I)
+   90                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(KPLUS1,J))
+                          DO 100 I = J - 1,MAX(1,J-K),-1
+                              TEMP = TEMP + CONJG(A(L+I,J))*X(I)
+  100                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 140 J = N,1,-1
+                      TEMP = X(JX)
+                      KX = KX - INCX
+                      IX = KX
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)
+                          DO 120 I = J - 1,MAX(1,J-K),-1
+                              TEMP = TEMP + A(L+I,J)*X(IX)
+                              IX = IX - INCX
+  120                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(KPLUS1,J))
+                          DO 130 I = J - 1,MAX(1,J-K),-1
+                              TEMP = TEMP + CONJG(A(L+I,J))*X(IX)
+                              IX = IX - INCX
+  130                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = 1,N
+                      TEMP = X(J)
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(1,J)
+                          DO 150 I = J + 1,MIN(N,J+K)
+                              TEMP = TEMP + A(L+I,J)*X(I)
+  150                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(1,J))
+                          DO 160 I = J + 1,MIN(N,J+K)
+                              TEMP = TEMP + CONJG(A(L+I,J))*X(I)
+  160                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 200 J = 1,N
+                      TEMP = X(JX)
+                      KX = KX + INCX
+                      IX = KX
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(1,J)
+                          DO 180 I = J + 1,MIN(N,J+K)
+                              TEMP = TEMP + A(L+I,J)*X(IX)
+                              IX = IX + INCX
+  180                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(1,J))
+                          DO 190 I = J + 1,MIN(N,J+K)
+                              TEMP = TEMP + CONJG(A(L+I,J))*X(IX)
+                              IX = IX + INCX
+  190                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTBMV .
+*
+      END
diff --git a/superlu/BLAS/ctbsv.f b/superlu/BLAS/ctbsv.f
new file mode 100644
index 0000000..f4cc330
--- /dev/null
+++ b/superlu/BLAS/ctbsv.f
@@ -0,0 +1,432 @@
+*> \brief \b CTBSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CTBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,K,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CTBSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,   or   A**H*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular band matrix, with ( k + 1 )
+*> diagonals.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**H*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with UPLO = 'U' or 'u', K specifies the number of
+*>           super-diagonals of the matrix A.
+*>           On entry with UPLO = 'L' or 'l', K specifies the number of
+*>           sub-diagonals of the matrix A.
+*>           K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer an upper
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer a lower
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that when DIAG = 'U' or 'u' the elements of the array A
+*>           corresponding to the diagonal elements of the matrix are not
+*>           referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CTBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTBSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed by sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(KPLUS1,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,MAX(1,J-K),-1
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 40 J = N,1,-1
+                      KX = KX - INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(KPLUS1,J)
+                          TEMP = X(JX)
+                          DO 30 I = J - 1,MAX(1,J-K),-1
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX - INCX
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          L = 1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(1,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,MIN(N,J+K)
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      KX = KX + INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = 1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(1,J)
+                          TEMP = X(JX)
+                          DO 70 I = J + 1,MIN(N,J+K)
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX + INCX
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x  or  x := inv( A**H )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = 1,N
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          DO 90 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - A(L+I,J)*X(I)
+   90                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      ELSE
+                          DO 100 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - CONJG(A(L+I,J))*X(I)
+  100                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(KPLUS1,J))
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 140 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          DO 120 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - A(L+I,J)*X(IX)
+                              IX = IX + INCX
+  120                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      ELSE
+                          DO 130 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - CONJG(A(L+I,J))*X(IX)
+                              IX = IX + INCX
+  130                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(KPLUS1,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = N,1,-1
+                      TEMP = X(J)
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          DO 150 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - A(L+I,J)*X(I)
+  150                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      ELSE
+                          DO 160 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - CONJG(A(L+I,J))*X(I)
+  160                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(1,J))
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 200 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          DO 180 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - A(L+I,J)*X(IX)
+                              IX = IX - INCX
+  180                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      ELSE
+                          DO 190 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - CONJG(A(L+I,J))*X(IX)
+                              IX = IX - INCX
+  190                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(1,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTBSV .
+*
+      END
diff --git a/superlu/BLAS/ctpmv.f b/superlu/BLAS/ctpmv.f
new file mode 100644
index 0000000..4582acc
--- /dev/null
+++ b/superlu/BLAS/ctpmv.f
@@ -0,0 +1,388 @@
+*> \brief \b CTPMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CTPMV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CTPMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,   or   x := A**H*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**H*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is COMPLEX array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 )
+*>           respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 )
+*>           respectively, and so on.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CTPMV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTPMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of AP are
+*     accessed sequentially with one pass through AP.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x:= A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          K = KK
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*AP(K)
+                              K = K + 1
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*AP(KK+J-1)
+                      END IF
+                      KK = KK + J
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 K = KK,KK + J - 2
+                              X(IX) = X(IX) + TEMP*AP(K)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*AP(KK+J-1)
+                      END IF
+                      JX = JX + INCX
+                      KK = KK + J
+   40             CONTINUE
+              END IF
+          ELSE
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          K = KK
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*AP(K)
+                              K = K - 1
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*AP(KK-N+J)
+                      END IF
+                      KK = KK - (N-J+1)
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 K = KK,KK - (N- (J+1)),-1
+                              X(IX) = X(IX) + TEMP*AP(K)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*AP(KK-N+J)
+                      END IF
+                      JX = JX - INCX
+                      KK = KK - (N-J+1)
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x  or  x := A**H*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = N,1,-1
+                      TEMP = X(J)
+                      K = KK - 1
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*AP(KK)
+                          DO 90 I = J - 1,1,-1
+                              TEMP = TEMP + AP(K)*X(I)
+                              K = K - 1
+   90                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(AP(KK))
+                          DO 100 I = J - 1,1,-1
+                              TEMP = TEMP + CONJG(AP(K))*X(I)
+                              K = K - 1
+  100                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+                      KK = KK - J
+  110             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 140 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*AP(KK)
+                          DO 120 K = KK - 1,KK - J + 1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + AP(K)*X(IX)
+  120                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(AP(KK))
+                          DO 130 K = KK - 1,KK - J + 1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + CONJG(AP(K))*X(IX)
+  130                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      KK = KK - J
+  140             CONTINUE
+              END IF
+          ELSE
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = 1,N
+                      TEMP = X(J)
+                      K = KK + 1
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*AP(KK)
+                          DO 150 I = J + 1,N
+                              TEMP = TEMP + AP(K)*X(I)
+                              K = K + 1
+  150                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(AP(KK))
+                          DO 160 I = J + 1,N
+                              TEMP = TEMP + CONJG(AP(K))*X(I)
+                              K = K + 1
+  160                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+                      KK = KK + (N-J+1)
+  170             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 200 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*AP(KK)
+                          DO 180 K = KK + 1,KK + N - J
+                              IX = IX + INCX
+                              TEMP = TEMP + AP(K)*X(IX)
+  180                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(AP(KK))
+                          DO 190 K = KK + 1,KK + N - J
+                              IX = IX + INCX
+                              TEMP = TEMP + CONJG(AP(K))*X(IX)
+  190                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      KK = KK + (N-J+1)
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTPMV .
+*
+      END
diff --git a/superlu/BLAS/ctpsv.f b/superlu/BLAS/ctpsv.f
new file mode 100644
index 0000000..2fcd19b
--- /dev/null
+++ b/superlu/BLAS/ctpsv.f
@@ -0,0 +1,390 @@
+*> \brief \b CTPSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CTPSV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CTPSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,   or   A**H*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular matrix, supplied in packed form.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**H*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is COMPLEX array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 )
+*>           respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 )
+*>           respectively, and so on.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CTPSV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTPSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of AP are
+*     accessed sequentially with one pass through AP.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/AP(KK)
+                          TEMP = X(J)
+                          K = KK - 1
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*AP(K)
+                              K = K - 1
+   10                     CONTINUE
+                      END IF
+                      KK = KK - J
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/AP(KK)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 K = KK - 1,KK - J + 1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*AP(K)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+                      KK = KK - J
+   40             CONTINUE
+              END IF
+          ELSE
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/AP(KK)
+                          TEMP = X(J)
+                          K = KK + 1
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*AP(K)
+                              K = K + 1
+   50                     CONTINUE
+                      END IF
+                      KK = KK + (N-J+1)
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/AP(KK)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 K = KK + 1,KK + N - J
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*AP(K)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+                      KK = KK + (N-J+1)
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x  or  x := inv( A**H )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = 1,N
+                      TEMP = X(J)
+                      K = KK
+                      IF (NOCONJ) THEN
+                          DO 90 I = 1,J - 1
+                              TEMP = TEMP - AP(K)*X(I)
+                              K = K + 1
+   90                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/AP(KK+J-1)
+                      ELSE
+                          DO 100 I = 1,J - 1
+                              TEMP = TEMP - CONJG(AP(K))*X(I)
+                              K = K + 1
+  100                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(AP(KK+J-1))
+                      END IF
+                      X(J) = TEMP
+                      KK = KK + J
+  110             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 140 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      IF (NOCONJ) THEN
+                          DO 120 K = KK,KK + J - 2
+                              TEMP = TEMP - AP(K)*X(IX)
+                              IX = IX + INCX
+  120                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/AP(KK+J-1)
+                      ELSE
+                          DO 130 K = KK,KK + J - 2
+                              TEMP = TEMP - CONJG(AP(K))*X(IX)
+                              IX = IX + INCX
+  130                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(AP(KK+J-1))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      KK = KK + J
+  140             CONTINUE
+              END IF
+          ELSE
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = N,1,-1
+                      TEMP = X(J)
+                      K = KK
+                      IF (NOCONJ) THEN
+                          DO 150 I = N,J + 1,-1
+                              TEMP = TEMP - AP(K)*X(I)
+                              K = K - 1
+  150                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/AP(KK-N+J)
+                      ELSE
+                          DO 160 I = N,J + 1,-1
+                              TEMP = TEMP - CONJG(AP(K))*X(I)
+                              K = K - 1
+  160                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(AP(KK-N+J))
+                      END IF
+                      X(J) = TEMP
+                      KK = KK - (N-J+1)
+  170             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 200 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      IF (NOCONJ) THEN
+                          DO 180 K = KK,KK - (N- (J+1)),-1
+                              TEMP = TEMP - AP(K)*X(IX)
+                              IX = IX - INCX
+  180                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/AP(KK-N+J)
+                      ELSE
+                          DO 190 K = KK,KK - (N- (J+1)),-1
+                              TEMP = TEMP - CONJG(AP(K))*X(IX)
+                              IX = IX - INCX
+  190                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(AP(KK-N+J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      KK = KK - (N-J+1)
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTPSV .
+*
+      END
diff --git a/superlu/BLAS/ctrmm.f b/superlu/BLAS/ctrmm.f
new file mode 100644
index 0000000..a23fb27
--- /dev/null
+++ b/superlu/BLAS/ctrmm.f
@@ -0,0 +1,452 @@
+*> \brief \b CTRMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CTRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA
+*       INTEGER LDA,LDB,M,N
+*       CHARACTER DIAG,SIDE,TRANSA,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),B(LDB,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CTRMM  performs one of the matrix-matrix operations
+*>
+*>    B := alpha*op( A )*B,   or   B := alpha*B*op( A )
+*>
+*> where  alpha  is a scalar,  B  is an m by n matrix,  A  is a unit, or
+*> non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*>
+*>    op( A ) = A   or   op( A ) = A**T   or   op( A ) = A**H.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE specifies whether  op( A ) multiplies B from
+*>           the left or right as follows:
+*>
+*>              SIDE = 'L' or 'l'   B := alpha*op( A )*B.
+*>
+*>              SIDE = 'R' or 'r'   B := alpha*B*op( A ).
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix A is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n'   op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't'   op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c'   op( A ) = A**H.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit triangular
+*>           as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of B. M must be at
+*>           least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of B.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*>           zero then  A is not referenced and  B need not be set before
+*>           entry.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, k ), where k is m
+*>           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*>           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*>           upper triangular part of the array  A must contain the upper
+*>           triangular matrix  and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*>           lower triangular part of the array  A must contain the lower
+*>           triangular matrix  and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*>           A  are not referenced either,  but are assumed to be  unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*>           then LDA must be at least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] B
+*> \verbatim
+*>          B is COMPLEX array of DIMENSION ( LDB, n ).
+*>           Before entry,  the leading  m by n part of the array  B must
+*>           contain the matrix  B,  and  on exit  is overwritten  by the
+*>           transformed matrix.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CTRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOCONJ,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOCONJ = LSAME(TRANSA,'T')
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTRMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*A*B.
+*
+              IF (UPPER) THEN
+                  DO 50 J = 1,N
+                      DO 40 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              DO 30 I = 1,K - 1
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   30                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP*A(K,K)
+                              B(K,J) = TEMP
+                          END IF
+   40                 CONTINUE
+   50             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              B(K,J) = TEMP
+                              IF (NOUNIT) B(K,J) = B(K,J)*A(K,K)
+                              DO 60 I = K + 1,M
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   60                         CONTINUE
+                          END IF
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*A**T*B   or   B := alpha*A**H*B.
+*
+              IF (UPPER) THEN
+                  DO 120 J = 1,N
+                      DO 110 I = M,1,-1
+                          TEMP = B(I,J)
+                          IF (NOCONJ) THEN
+                              IF (NOUNIT) TEMP = TEMP*A(I,I)
+                              DO 90 K = 1,I - 1
+                                  TEMP = TEMP + A(K,I)*B(K,J)
+   90                         CONTINUE
+                          ELSE
+                              IF (NOUNIT) TEMP = TEMP*CONJG(A(I,I))
+                              DO 100 K = 1,I - 1
+                                  TEMP = TEMP + CONJG(A(K,I))*B(K,J)
+  100                         CONTINUE
+                          END IF
+                          B(I,J) = ALPHA*TEMP
+  110                 CONTINUE
+  120             CONTINUE
+              ELSE
+                  DO 160 J = 1,N
+                      DO 150 I = 1,M
+                          TEMP = B(I,J)
+                          IF (NOCONJ) THEN
+                              IF (NOUNIT) TEMP = TEMP*A(I,I)
+                              DO 130 K = I + 1,M
+                                  TEMP = TEMP + A(K,I)*B(K,J)
+  130                         CONTINUE
+                          ELSE
+                              IF (NOUNIT) TEMP = TEMP*CONJG(A(I,I))
+                              DO 140 K = I + 1,M
+                                  TEMP = TEMP + CONJG(A(K,I))*B(K,J)
+  140                         CONTINUE
+                          END IF
+                          B(I,J) = ALPHA*TEMP
+  150                 CONTINUE
+  160             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*A.
+*
+              IF (UPPER) THEN
+                  DO 200 J = N,1,-1
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 170 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  170                 CONTINUE
+                      DO 190 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 180 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  180                         CONTINUE
+                          END IF
+  190                 CONTINUE
+  200             CONTINUE
+              ELSE
+                  DO 240 J = 1,N
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 210 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  210                 CONTINUE
+                      DO 230 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 220 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  220                         CONTINUE
+                          END IF
+  230                 CONTINUE
+  240             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*A**T   or   B := alpha*B*A**H.
+*
+              IF (UPPER) THEN
+                  DO 280 K = 1,N
+                      DO 260 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = ALPHA*A(J,K)
+                              ELSE
+                                  TEMP = ALPHA*CONJG(A(J,K))
+                              END IF
+                              DO 250 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  250                         CONTINUE
+                          END IF
+  260                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = TEMP*A(K,K)
+                          ELSE
+                              TEMP = TEMP*CONJG(A(K,K))
+                          END IF
+                      END IF
+                      IF (TEMP.NE.ONE) THEN
+                          DO 270 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  270                     CONTINUE
+                      END IF
+  280             CONTINUE
+              ELSE
+                  DO 320 K = N,1,-1
+                      DO 300 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = ALPHA*A(J,K)
+                              ELSE
+                                  TEMP = ALPHA*CONJG(A(J,K))
+                              END IF
+                              DO 290 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  290                         CONTINUE
+                          END IF
+  300                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = TEMP*A(K,K)
+                          ELSE
+                              TEMP = TEMP*CONJG(A(K,K))
+                          END IF
+                      END IF
+                      IF (TEMP.NE.ONE) THEN
+                          DO 310 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  310                     CONTINUE
+                      END IF
+  320             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTRMM .
+*
+      END
diff --git a/superlu/BLAS/ctrmv.f b/superlu/BLAS/ctrmv.f
new file mode 100644
index 0000000..8795e87
--- /dev/null
+++ b/superlu/BLAS/ctrmv.f
@@ -0,0 +1,373 @@
+*> \brief \b CTRMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CTRMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,   or   x := A**H*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**H*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular matrix and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular matrix and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced either, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTRMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*A(I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 I = 1,J - 1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*A(I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 I = N,J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x  or  x := A**H*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 90 I = J - 1,1,-1
+                              TEMP = TEMP + A(I,J)*X(I)
+   90                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(J,J))
+                          DO 100 I = J - 1,1,-1
+                              TEMP = TEMP + CONJG(A(I,J))*X(I)
+  100                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 140 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 120 I = J - 1,1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + A(I,J)*X(IX)
+  120                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(J,J))
+                          DO 130 I = J - 1,1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + CONJG(A(I,J))*X(IX)
+  130                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = 1,N
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 150 I = J + 1,N
+                              TEMP = TEMP + A(I,J)*X(I)
+  150                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(J,J))
+                          DO 160 I = J + 1,N
+                              TEMP = TEMP + CONJG(A(I,J))*X(I)
+  160                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 200 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 180 I = J + 1,N
+                              IX = IX + INCX
+                              TEMP = TEMP + A(I,J)*X(IX)
+  180                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*CONJG(A(J,J))
+                          DO 190 I = J + 1,N
+                              IX = IX + INCX
+                              TEMP = TEMP + CONJG(A(I,J))*X(IX)
+  190                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTRMV .
+*
+      END
diff --git a/superlu/BLAS/ctrsm.f b/superlu/BLAS/ctrsm.f
new file mode 100644
index 0000000..7ee5c94
--- /dev/null
+++ b/superlu/BLAS/ctrsm.f
@@ -0,0 +1,477 @@
+*> \brief \b CTRSM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX ALPHA
+*       INTEGER LDA,LDB,M,N
+*       CHARACTER DIAG,SIDE,TRANSA,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),B(LDB,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CTRSM  solves one of the matrix equations
+*>
+*>    op( A )*X = alpha*B,   or   X*op( A ) = alpha*B,
+*>
+*> where alpha is a scalar, X and B are m by n matrices, A is a unit, or
+*> non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*>
+*>    op( A ) = A   or   op( A ) = A**T   or   op( A ) = A**H.
+*>
+*> The matrix X is overwritten on B.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry, SIDE specifies whether op( A ) appears on the left
+*>           or right of X as follows:
+*>
+*>              SIDE = 'L' or 'l'   op( A )*X = alpha*B.
+*>
+*>              SIDE = 'R' or 'r'   X*op( A ) = alpha*B.
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix A is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n'   op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't'   op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c'   op( A ) = A**H.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit triangular
+*>           as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of B. M must be at
+*>           least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of B.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX
+*>           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*>           zero then  A is not referenced and  B need not be set before
+*>           entry.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, k ),
+*>           where k is m when SIDE = 'L' or 'l'
+*>             and k is n when SIDE = 'R' or 'r'.
+*>           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*>           upper triangular part of the array  A must contain the upper
+*>           triangular matrix  and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*>           lower triangular part of the array  A must contain the lower
+*>           triangular matrix  and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*>           A  are not referenced either,  but are assumed to be  unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*>           then LDA must be at least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] B
+*> \verbatim
+*>          B is COMPLEX array of DIMENSION ( LDB, n ).
+*>           Before entry,  the leading  m by n part of the array  B must
+*>           contain  the  right-hand  side  matrix  B,  and  on exit  is
+*>           overwritten by the solution matrix  X.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),B(LDB,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOCONJ,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX ONE
+      PARAMETER (ONE= (1.0E+0,0.0E+0))
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOCONJ = LSAME(TRANSA,'T')
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTRSM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*inv( A )*B.
+*
+              IF (UPPER) THEN
+                  DO 60 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 30 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   30                     CONTINUE
+                      END IF
+                      DO 50 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 40 I = 1,K - 1
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   40                         CONTINUE
+                          END IF
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 100 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 70 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   70                     CONTINUE
+                      END IF
+                      DO 90 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 80 I = K + 1,M
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   80                         CONTINUE
+                          END IF
+   90                 CONTINUE
+  100             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*inv( A**T )*B
+*           or    B := alpha*inv( A**H )*B.
+*
+              IF (UPPER) THEN
+                  DO 140 J = 1,N
+                      DO 130 I = 1,M
+                          TEMP = ALPHA*B(I,J)
+                          IF (NOCONJ) THEN
+                              DO 110 K = 1,I - 1
+                                  TEMP = TEMP - A(K,I)*B(K,J)
+  110                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          ELSE
+                              DO 120 K = 1,I - 1
+                                  TEMP = TEMP - CONJG(A(K,I))*B(K,J)
+  120                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/CONJG(A(I,I))
+                          END IF
+                          B(I,J) = TEMP
+  130                 CONTINUE
+  140             CONTINUE
+              ELSE
+                  DO 180 J = 1,N
+                      DO 170 I = M,1,-1
+                          TEMP = ALPHA*B(I,J)
+                          IF (NOCONJ) THEN
+                              DO 150 K = I + 1,M
+                                  TEMP = TEMP - A(K,I)*B(K,J)
+  150                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          ELSE
+                              DO 160 K = I + 1,M
+                                  TEMP = TEMP - CONJG(A(K,I))*B(K,J)
+  160                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/CONJG(A(I,I))
+                          END IF
+                          B(I,J) = TEMP
+  170                 CONTINUE
+  180             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*inv( A ).
+*
+              IF (UPPER) THEN
+                  DO 230 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 190 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  190                     CONTINUE
+                      END IF
+                      DO 210 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 200 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  200                         CONTINUE
+                          END IF
+  210                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 220 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  220                     CONTINUE
+                      END IF
+  230             CONTINUE
+              ELSE
+                  DO 280 J = N,1,-1
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 240 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  240                     CONTINUE
+                      END IF
+                      DO 260 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 250 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  250                         CONTINUE
+                          END IF
+  260                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 270 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  270                     CONTINUE
+                      END IF
+  280             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*inv( A**T )
+*           or    B := alpha*B*inv( A**H ).
+*
+              IF (UPPER) THEN
+                  DO 330 K = N,1,-1
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = ONE/A(K,K)
+                          ELSE
+                              TEMP = ONE/CONJG(A(K,K))
+                          END IF
+                          DO 290 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  290                     CONTINUE
+                      END IF
+                      DO 310 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = A(J,K)
+                              ELSE
+                                  TEMP = CONJG(A(J,K))
+                              END IF
+                              DO 300 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  300                         CONTINUE
+                          END IF
+  310                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 320 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  320                     CONTINUE
+                      END IF
+  330             CONTINUE
+              ELSE
+                  DO 380 K = 1,N
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = ONE/A(K,K)
+                          ELSE
+                              TEMP = ONE/CONJG(A(K,K))
+                          END IF
+                          DO 340 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  340                     CONTINUE
+                      END IF
+                      DO 360 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = A(J,K)
+                              ELSE
+                                  TEMP = CONJG(A(J,K))
+                              END IF
+                              DO 350 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  350                         CONTINUE
+                          END IF
+  360                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 370 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  370                     CONTINUE
+                      END IF
+  380             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTRSM .
+*
+      END
diff --git a/superlu/BLAS/ctrsv.f b/superlu/BLAS/ctrsv.f
new file mode 100644
index 0000000..7981a21
--- /dev/null
+++ b/superlu/BLAS/ctrsv.f
@@ -0,0 +1,375 @@
+*> \brief \b CTRSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE CTRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> CTRSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,   or   A**H*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular matrix.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**H*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular matrix and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular matrix and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced either, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is COMPLEX array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE CTRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX ZERO
+      PARAMETER (ZERO= (0.0E+0,0.0E+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('CTRSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*A(I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 I = J - 1,1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*A(I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 I = J + 1,N
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x  or  x := inv( A**H )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = 1,N
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          DO 90 I = 1,J - 1
+                              TEMP = TEMP - A(I,J)*X(I)
+   90                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 100 I = 1,J - 1
+                              TEMP = TEMP - CONJG(A(I,J))*X(I)
+  100                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(J,J))
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 140 J = 1,N
+                      IX = KX
+                      TEMP = X(JX)
+                      IF (NOCONJ) THEN
+                          DO 120 I = 1,J - 1
+                              TEMP = TEMP - A(I,J)*X(IX)
+                              IX = IX + INCX
+  120                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 130 I = 1,J - 1
+                              TEMP = TEMP - CONJG(A(I,J))*X(IX)
+                              IX = IX + INCX
+  130                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(J,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          DO 150 I = N,J + 1,-1
+                              TEMP = TEMP - A(I,J)*X(I)
+  150                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 160 I = N,J + 1,-1
+                              TEMP = TEMP - CONJG(A(I,J))*X(I)
+  160                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(J,J))
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 200 J = N,1,-1
+                      IX = KX
+                      TEMP = X(JX)
+                      IF (NOCONJ) THEN
+                          DO 180 I = N,J + 1,-1
+                              TEMP = TEMP - A(I,J)*X(IX)
+                              IX = IX - INCX
+  180                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 190 I = N,J + 1,-1
+                              TEMP = TEMP - CONJG(A(I,J))*X(IX)
+                              IX = IX - INCX
+  190                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/CONJG(A(J,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of CTRSV .
+*
+      END
diff --git a/superlu/BLAS/dasum.f b/superlu/BLAS/dasum.f
new file mode 100644
index 0000000..fd3d910
--- /dev/null
+++ b/superlu/BLAS/dasum.f
@@ -0,0 +1,111 @@
+*> \brief \b DASUM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       DOUBLE PRECISION FUNCTION DASUM(N,DX,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    DASUM takes the sum of the absolute values.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      DOUBLE PRECISION FUNCTION DASUM(N,DX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION DTEMP
+      INTEGER I,M,MP1,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DABS,MOD
+*     ..
+      DASUM = 0.0d0
+      DTEMP = 0.0d0
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*        code for increment equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,6)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               DTEMP = DTEMP + DABS(DX(I))
+            END DO
+            IF (N.LT.6) THEN
+               DASUM = DTEMP
+               RETURN
+            END IF
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,6
+            DTEMP = DTEMP + DABS(DX(I)) + DABS(DX(I+1)) +
+     $              DABS(DX(I+2)) + DABS(DX(I+3)) +
+     $              DABS(DX(I+4)) + DABS(DX(I+5))
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            DTEMP = DTEMP + DABS(DX(I))
+         END DO
+      END IF
+      DASUM = DTEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/daxpy.f b/superlu/BLAS/daxpy.f
new file mode 100644
index 0000000..5203e50
--- /dev/null
+++ b/superlu/BLAS/daxpy.f
@@ -0,0 +1,115 @@
+*> \brief \b DAXPY
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DAXPY(N,DA,DX,INCX,DY,INCY)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION DA
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DX(*),DY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    DAXPY constant times a vector plus a vector.
+*>    uses unrolled loops for increments equal to one.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DAXPY(N,DA,DX,INCX,DY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION DA
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DX(*),DY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0) RETURN
+      IF (DA.EQ.0.0d0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,4)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               DY(I) = DY(I) + DA*DX(I)
+            END DO
+         END IF
+         IF (N.LT.4) RETURN
+         MP1 = M + 1
+         DO I = MP1,N,4
+            DY(I) = DY(I) + DA*DX(I)
+            DY(I+1) = DY(I+1) + DA*DX(I+1)
+            DY(I+2) = DY(I+2) + DA*DX(I+2)
+            DY(I+3) = DY(I+3) + DA*DX(I+3)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+          DY(IY) = DY(IY) + DA*DX(IX)
+          IX = IX + INCX
+          IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/dcabs1.f b/superlu/BLAS/dcabs1.f
new file mode 100644
index 0000000..d71fe7a
--- /dev/null
+++ b/superlu/BLAS/dcabs1.f
@@ -0,0 +1,58 @@
+*> \brief \b DCABS1
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       DOUBLE PRECISION FUNCTION DCABS1(Z)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 Z
+*       ..
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DCABS1 computes |Re(.)| + |Im(.)| of a double complex number
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*  =====================================================================
+      DOUBLE PRECISION FUNCTION DCABS1(Z)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 Z
+*     ..
+*     ..
+*  =====================================================================
+*
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,DBLE,DIMAG
+*
+      DCABS1 = ABS(DBLE(Z)) + ABS(DIMAG(Z))
+      RETURN
+      END
diff --git a/superlu/BLAS/dcopy.f b/superlu/BLAS/dcopy.f
new file mode 100644
index 0000000..bbc38a7
--- /dev/null
+++ b/superlu/BLAS/dcopy.f
@@ -0,0 +1,115 @@
+*> \brief \b DCOPY
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DCOPY(N,DX,INCX,DY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DX(*),DY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    DCOPY copies a vector, x, to a vector, y.
+*>    uses unrolled loops for increments equal to one.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DCOPY(N,DX,INCX,DY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DX(*),DY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,7)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               DY(I) = DX(I)
+            END DO
+            IF (N.LT.7) RETURN
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,7
+            DY(I) = DX(I)
+            DY(I+1) = DX(I+1)
+            DY(I+2) = DX(I+2)
+            DY(I+3) = DX(I+3)
+            DY(I+4) = DX(I+4)
+            DY(I+5) = DX(I+5)
+            DY(I+6) = DX(I+6)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            DY(IY) = DX(IX)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/ddot.f b/superlu/BLAS/ddot.f
new file mode 100644
index 0000000..1aea824
--- /dev/null
+++ b/superlu/BLAS/ddot.f
@@ -0,0 +1,117 @@
+*> \brief \b DDOT
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       DOUBLE PRECISION FUNCTION DDOT(N,DX,INCX,DY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DX(*),DY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    DDOT forms the dot product of two vectors.
+*>    uses unrolled loops for increments equal to one.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      DOUBLE PRECISION FUNCTION DDOT(N,DX,INCX,DY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DX(*),DY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION DTEMP
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      DDOT = 0.0d0
+      DTEMP = 0.0d0
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,5)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               DTEMP = DTEMP + DX(I)*DY(I)
+            END DO
+            IF (N.LT.5) THEN
+               DDOT=DTEMP
+            RETURN
+            END IF
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,5
+          DTEMP = DTEMP + DX(I)*DY(I) + DX(I+1)*DY(I+1) +
+     $            DX(I+2)*DY(I+2) + DX(I+3)*DY(I+3) + DX(I+4)*DY(I+4)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            DTEMP = DTEMP + DX(IX)*DY(IY)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      DDOT = DTEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/dgbmv.f b/superlu/BLAS/dgbmv.f
new file mode 100644
index 0000000..3769e18
--- /dev/null
+++ b/superlu/BLAS/dgbmv.f
@@ -0,0 +1,370 @@
+*> \brief \b DGBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DGBMV(TRANS,M,N,KL,KU,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER INCX,INCY,KL,KU,LDA,M,N
+*       CHARACTER TRANS
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DGBMV  performs one of the matrix-vector operations
+*>
+*>    y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are vectors and A is an
+*> m by n band matrix, with kl sub-diagonals and ku super-diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*>
+*>              TRANS = 'T' or 't'   y := alpha*A**T*x + beta*y.
+*>
+*>              TRANS = 'C' or 'c'   y := alpha*A**T*x + beta*y.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] KL
+*> \verbatim
+*>          KL is INTEGER
+*>           On entry, KL specifies the number of sub-diagonals of the
+*>           matrix A. KL must satisfy  0 .le. KL.
+*> \endverbatim
+*>
+*> \param[in] KU
+*> \verbatim
+*>          KU is INTEGER
+*>           On entry, KU specifies the number of super-diagonals of the
+*>           matrix A. KU must satisfy  0 .le. KU.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading ( kl + ku + 1 ) by n part of the
+*>           array A must contain the matrix of coefficients, supplied
+*>           column by column, with the leading diagonal of the matrix in
+*>           row ( ku + 1 ) of the array, the first super-diagonal
+*>           starting at position 2 in row ku, the first sub-diagonal
+*>           starting at position 1 in row ( ku + 2 ), and so on.
+*>           Elements in the array A that do not correspond to elements
+*>           in the band matrix (such as the top left ku by ku triangle)
+*>           are not referenced.
+*>           The following program segment will transfer a band matrix
+*>           from conventional full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    K = KU + 1 - J
+*>                    DO 10, I = MAX( 1, J - KU ), MIN( M, J + KL )
+*>                       A( K + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( kl + ku + 1 ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is DOUBLE PRECISION array of DIMENSION at least
+*>           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*>           Before entry, the incremented array Y must contain the
+*>           vector y. On exit, Y is overwritten by the updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DGBMV(TRANS,M,N,KL,KU,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER INCX,INCY,KL,KU,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KUP1,KX,KY,LENX,LENY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (KL.LT.0) THEN
+          INFO = 4
+      ELSE IF (KU.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (KL+KU+1)) THEN
+          INFO = 8
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 10
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DGBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the band part of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      KUP1 = KU + 1
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  K = KUP1 - J
+                  DO 50 I = MAX(1,J-KU),MIN(M,J+KL)
+                      Y(I) = Y(I) + TEMP*A(K+I,J)
+   50             CONTINUE
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  IY = KY
+                  K = KUP1 - J
+                  DO 70 I = MAX(1,J-KU),MIN(M,J+KL)
+                      Y(IY) = Y(IY) + TEMP*A(K+I,J)
+                      IY = IY + INCY
+   70             CONTINUE
+                  JX = JX + INCX
+                  IF (J.GT.KU) KY = KY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A**T*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 100 J = 1,N
+                  TEMP = ZERO
+                  K = KUP1 - J
+                  DO 90 I = MAX(1,J-KU),MIN(M,J+KL)
+                      TEMP = TEMP + A(K+I,J)*X(I)
+   90             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  100         CONTINUE
+          ELSE
+              DO 120 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  K = KUP1 - J
+                  DO 110 I = MAX(1,J-KU),MIN(M,J+KL)
+                      TEMP = TEMP + A(K+I,J)*X(IX)
+                      IX = IX + INCX
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+                  IF (J.GT.KU) KX = KX + INCX
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DGBMV .
+*
+      END
diff --git a/superlu/BLAS/dgemm.f b/superlu/BLAS/dgemm.f
new file mode 100644
index 0000000..5c5a2ac
--- /dev/null
+++ b/superlu/BLAS/dgemm.f
@@ -0,0 +1,384 @@
+*> \brief \b DGEMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER K,LDA,LDB,LDC,M,N
+*       CHARACTER TRANSA,TRANSB
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DGEMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*op( A )*op( B ) + beta*C,
+*>
+*> where  op( X ) is one of
+*>
+*>    op( X ) = X   or   op( X ) = X**T,
+*>
+*> alpha and beta are scalars, and A, B and C are matrices, with op( A )
+*> an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n',  op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't',  op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c',  op( A ) = A**T.
+*> \endverbatim
+*>
+*> \param[in] TRANSB
+*> \verbatim
+*>          TRANSB is CHARACTER*1
+*>           On entry, TRANSB specifies the form of op( B ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSB = 'N' or 'n',  op( B ) = B.
+*>
+*>              TRANSB = 'T' or 't',  op( B ) = B**T.
+*>
+*>              TRANSB = 'C' or 'c',  op( B ) = B**T.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies  the number  of rows  of the  matrix
+*>           op( A )  and of the  matrix  C.  M  must  be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N  specifies the number  of columns of the matrix
+*>           op( B ) and the number of columns of the matrix C. N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry,  K  specifies  the number of columns of the matrix
+*>           op( A ) and the number of rows of the matrix op( B ). K must
+*>           be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANSA = 'N' or 'n',  and is  m  otherwise.
+*>           Before entry with  TRANSA = 'N' or 'n',  the leading  m by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by m  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. When  TRANSA = 'N' or 'n' then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is
+*>           n  when  TRANSB = 'N' or 'n',  and is  k  otherwise.
+*>           Before entry with  TRANSB = 'N' or 'n',  the leading  k by n
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  n by k  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in the calling (sub) program. When  TRANSB = 'N' or 'n' then
+*>           LDB must be at least  max( 1, k ), otherwise  LDB must be at
+*>           least  max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is DOUBLE PRECISION array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n  matrix
+*>           ( alpha*op( A )*op( B ) + beta*C ).
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,M,N
+      CHARACTER TRANSA,TRANSB
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,J,L,NCOLA,NROWA,NROWB
+      LOGICAL NOTA,NOTB
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*
+*     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not
+*     transposed and set  NROWA, NCOLA and  NROWB  as the number of rows
+*     and  columns of  A  and the  number of  rows  of  B  respectively.
+*
+      NOTA = LSAME(TRANSA,'N')
+      NOTB = LSAME(TRANSB,'N')
+      IF (NOTA) THEN
+          NROWA = M
+          NCOLA = K
+      ELSE
+          NROWA = K
+          NCOLA = M
+      END IF
+      IF (NOTB) THEN
+          NROWB = K
+      ELSE
+          NROWB = N
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.NOTA) .AND. (.NOT.LSAME(TRANSA,'C')) .AND.
+     +    (.NOT.LSAME(TRANSA,'T'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.NOTB) .AND. (.NOT.LSAME(TRANSB,'C')) .AND.
+     +         (.NOT.LSAME(TRANSB,'T'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 8
+      ELSE IF (LDB.LT.MAX(1,NROWB)) THEN
+          INFO = 10
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DGEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And if  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (NOTB) THEN
+          IF (NOTA) THEN
+*
+*           Form  C := alpha*A*B + beta*C.
+*
+              DO 90 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 50 I = 1,M
+                          C(I,J) = ZERO
+   50                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 60 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+   60                 CONTINUE
+                  END IF
+                  DO 80 L = 1,K
+                      TEMP = ALPHA*B(L,J)
+                      DO 70 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+   70                 CONTINUE
+   80             CONTINUE
+   90         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**T*B + beta*C
+*
+              DO 120 J = 1,N
+                  DO 110 I = 1,M
+                      TEMP = ZERO
+                      DO 100 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(L,J)
+  100                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  110             CONTINUE
+  120         CONTINUE
+          END IF
+      ELSE
+          IF (NOTA) THEN
+*
+*           Form  C := alpha*A*B**T + beta*C
+*
+              DO 170 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 130 I = 1,M
+                          C(I,J) = ZERO
+  130                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 140 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+  140                 CONTINUE
+                  END IF
+                  DO 160 L = 1,K
+                      TEMP = ALPHA*B(J,L)
+                      DO 150 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+  150                 CONTINUE
+  160             CONTINUE
+  170         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**T*B**T + beta*C
+*
+              DO 200 J = 1,N
+                  DO 190 I = 1,M
+                      TEMP = ZERO
+                      DO 180 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(J,L)
+  180                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  190             CONTINUE
+  200         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DGEMM .
+*
+      END
diff --git a/superlu/BLAS/dgemv.f b/superlu/BLAS/dgemv.f
new file mode 100644
index 0000000..dd14c35
--- /dev/null
+++ b/superlu/BLAS/dgemv.f
@@ -0,0 +1,330 @@
+*> \brief \b DGEMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER INCX,INCY,LDA,M,N
+*       CHARACTER TRANS
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DGEMV  performs one of the matrix-vector operations
+*>
+*>    y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are vectors and A is an
+*> m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*>
+*>              TRANS = 'T' or 't'   y := alpha*A**T*x + beta*y.
+*>
+*>              TRANS = 'C' or 'c'   y := alpha*A**T*x + beta*y.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is DOUBLE PRECISION array of DIMENSION at least
+*>           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*>           Before entry with BETA non-zero, the incremented array Y
+*>           must contain the vector y. On exit, Y is overwritten by the
+*>           updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER INCX,INCY,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY,LENX,LENY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DGEMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  DO 50 I = 1,M
+                      Y(I) = Y(I) + TEMP*A(I,J)
+   50             CONTINUE
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  IY = KY
+                  DO 70 I = 1,M
+                      Y(IY) = Y(IY) + TEMP*A(I,J)
+                      IY = IY + INCY
+   70             CONTINUE
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A**T*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 100 J = 1,N
+                  TEMP = ZERO
+                  DO 90 I = 1,M
+                      TEMP = TEMP + A(I,J)*X(I)
+   90             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  100         CONTINUE
+          ELSE
+              DO 120 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  DO 110 I = 1,M
+                      TEMP = TEMP + A(I,J)*X(IX)
+                      IX = IX + INCX
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DGEMV .
+*
+      END
diff --git a/superlu/BLAS/dger.f b/superlu/BLAS/dger.f
new file mode 100644
index 0000000..289141e
--- /dev/null
+++ b/superlu/BLAS/dger.f
@@ -0,0 +1,227 @@
+*> \brief \b DGER
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DGER(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA
+*       INTEGER INCX,INCY,LDA,M,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DGER   performs the rank 1 operation
+*>
+*>    A := alpha*x*y**T + A,
+*>
+*> where alpha is a scalar, x is an m element vector, y is an n element
+*> vector and A is an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the m
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients. On exit, A is
+*>           overwritten by the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DGER(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA
+      INTEGER INCX,INCY,LDA,M,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,J,JY,KX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (M.LT.0) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DGER  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (INCY.GT.0) THEN
+          JY = 1
+      ELSE
+          JY = 1 - (N-1)*INCY
+      END IF
+      IF (INCX.EQ.1) THEN
+          DO 20 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  DO 10 I = 1,M
+                      A(I,J) = A(I,J) + X(I)*TEMP
+   10             CONTINUE
+              END IF
+              JY = JY + INCY
+   20     CONTINUE
+      ELSE
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (M-1)*INCX
+          END IF
+          DO 40 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  IX = KX
+                  DO 30 I = 1,M
+                      A(I,J) = A(I,J) + X(IX)*TEMP
+                      IX = IX + INCX
+   30             CONTINUE
+              END IF
+              JY = JY + INCY
+   40     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DGER  .
+*
+      END
diff --git a/superlu/BLAS/dnrm2.f b/superlu/BLAS/dnrm2.f
new file mode 100644
index 0000000..0d7062f
--- /dev/null
+++ b/superlu/BLAS/dnrm2.f
@@ -0,0 +1,112 @@
+*> \brief \b DNRM2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       DOUBLE PRECISION FUNCTION DNRM2(N,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DNRM2 returns the euclidean norm of a vector via the function
+*> name, so that
+*>
+*>    DNRM2 := sqrt( x'*x )
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  -- This version written on 25-October-1982.
+*>     Modified on 14-October-1993 to inline the call to DLASSQ.
+*>     Sven Hammarling, Nag Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      DOUBLE PRECISION FUNCTION DNRM2(N,X,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION ABSXI,NORM,SCALE,SSQ
+      INTEGER IX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,SQRT
+*     ..
+      IF (N.LT.1 .OR. INCX.LT.1) THEN
+          NORM = ZERO
+      ELSE IF (N.EQ.1) THEN
+          NORM = ABS(X(1))
+      ELSE
+          SCALE = ZERO
+          SSQ = ONE
+*        The following loop is equivalent to this call to the LAPACK
+*        auxiliary routine:
+*        CALL DLASSQ( N, X, INCX, SCALE, SSQ )
+*
+          DO 10 IX = 1,1 + (N-1)*INCX,INCX
+              IF (X(IX).NE.ZERO) THEN
+                  ABSXI = ABS(X(IX))
+                  IF (SCALE.LT.ABSXI) THEN
+                      SSQ = ONE + SSQ* (SCALE/ABSXI)**2
+                      SCALE = ABSXI
+                  ELSE
+                      SSQ = SSQ + (ABSXI/SCALE)**2
+                  END IF
+              END IF
+   10     CONTINUE
+          NORM = SCALE*SQRT(SSQ)
+      END IF
+*
+      DNRM2 = NORM
+      RETURN
+*
+*     End of DNRM2.
+*
+      END
diff --git a/superlu/BLAS/drot.f b/superlu/BLAS/drot.f
new file mode 100644
index 0000000..baaae5c
--- /dev/null
+++ b/superlu/BLAS/drot.f
@@ -0,0 +1,101 @@
+*> \brief \b DROT
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DROT(N,DX,INCX,DY,INCY,C,S)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION C,S
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DX(*),DY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    DROT applies a plane rotation.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DROT(N,DX,INCX,DY,INCY,C,S)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION C,S
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DX(*),DY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION DTEMP
+      INTEGER I,IX,IY
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*       code for both increments equal to 1
+*
+         DO I = 1,N
+            DTEMP = C*DX(I) + S*DY(I)
+            DY(I) = C*DY(I) - S*DX(I)
+            DX(I) = DTEMP
+         END DO
+      ELSE
+*
+*       code for unequal increments or equal increments not equal
+*         to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            DTEMP = C*DX(IX) + S*DY(IY)
+            DY(IY) = C*DY(IY) - S*DX(IX)
+            DX(IX) = DTEMP
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/drotg.f b/superlu/BLAS/drotg.f
new file mode 100644
index 0000000..85d04cd
--- /dev/null
+++ b/superlu/BLAS/drotg.f
@@ -0,0 +1,86 @@
+*> \brief \b DROTG
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DROTG(DA,DB,C,S)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION C,DA,DB,S
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    DROTG construct givens plane rotation.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DROTG(DA,DB,C,S)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION C,DA,DB,S
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION R,ROE,SCALE,Z
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DABS,DSIGN,DSQRT
+*     ..
+      ROE = DB
+      IF (DABS(DA).GT.DABS(DB)) ROE = DA
+      SCALE = DABS(DA) + DABS(DB)
+      IF (SCALE.EQ.0.0d0) THEN
+         C = 1.0d0
+         S = 0.0d0
+         R = 0.0d0
+         Z = 0.0d0
+      ELSE
+         R = SCALE*DSQRT((DA/SCALE)**2+ (DB/SCALE)**2)
+         R = DSIGN(1.0d0,ROE)*R
+         C = DA/R
+         S = DB/R
+         Z = 1.0d0
+         IF (DABS(DA).GT.DABS(DB)) Z = S
+         IF (DABS(DB).GE.DABS(DA) .AND. C.NE.0.0d0) Z = 1.0d0/C
+      END IF
+      DA = R
+      DB = Z
+      RETURN
+      END
diff --git a/superlu/BLAS/drotm.f b/superlu/BLAS/drotm.f
new file mode 100644
index 0000000..b006dbd
--- /dev/null
+++ b/superlu/BLAS/drotm.f
@@ -0,0 +1,202 @@
+*> \brief \b DROTM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DROTM(N,DX,INCX,DY,INCY,DPARAM)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DPARAM(5),DX(*),DY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    APPLY THE MODIFIED GIVENS TRANSFORMATION, H, TO THE 2 BY N MATRIX
+*>
+*>    (DX**T) , WHERE **T INDICATES TRANSPOSE. THE ELEMENTS OF DX ARE IN
+*>    (DY**T)
+*>
+*>    DX(LX+I*INCX), I = 0 TO N-1, WHERE LX = 1 IF INCX .GE. 0, ELSE
+*>    LX = (-INCX)*N, AND SIMILARLY FOR SY USING LY AND INCY.
+*>    WITH DPARAM(1)=DFLAG, H HAS ONE OF THE FOLLOWING FORMS..
+*>
+*>    DFLAG=-1.D0     DFLAG=0.D0        DFLAG=1.D0     DFLAG=-2.D0
+*>
+*>      (DH11  DH12)    (1.D0  DH12)    (DH11  1.D0)    (1.D0  0.D0)
+*>    H=(          )    (          )    (          )    (          )
+*>      (DH21  DH22),   (DH21  1.D0),   (-1.D0 DH22),   (0.D0  1.D0).
+*>    SEE DROTMG FOR A DESCRIPTION OF DATA STORAGE IN DPARAM.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>         number of elements in input vector(s)
+*> \endverbatim
+*>
+*> \param[in,out] DX
+*> \verbatim
+*>          DX is DOUBLE PRECISION array, dimension N
+*>         double precision vector with N elements
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>         storage spacing between elements of DX
+*> \endverbatim
+*>
+*> \param[in,out] DY
+*> \verbatim
+*>          DY is DOUBLE PRECISION array, dimension N
+*>         double precision vector with N elements
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>         storage spacing between elements of DY
+*> \endverbatim
+*>
+*> \param[in,out] DPARAM
+*> \verbatim
+*>          DPARAM is DOUBLE PRECISION array, dimension 5
+*>     DPARAM(1)=DFLAG
+*>     DPARAM(2)=DH11
+*>     DPARAM(3)=DH21
+*>     DPARAM(4)=DH12
+*>     DPARAM(5)=DH22
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*  =====================================================================
+      SUBROUTINE DROTM(N,DX,INCX,DY,INCY,DPARAM)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DPARAM(5),DX(*),DY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION DFLAG,DH11,DH12,DH21,DH22,TWO,W,Z,ZERO
+      INTEGER I,KX,KY,NSTEPS
+*     ..
+*     .. Data statements ..
+      DATA ZERO,TWO/0.D0,2.D0/
+*     ..
+*
+      DFLAG = DPARAM(1)
+      IF (N.LE.0 .OR. (DFLAG+TWO.EQ.ZERO)) RETURN
+      IF (INCX.EQ.INCY.AND.INCX.GT.0) THEN
+*
+         NSTEPS = N*INCX
+         IF (DFLAG.LT.ZERO) THEN
+            DH11 = DPARAM(2)
+            DH12 = DPARAM(4)
+            DH21 = DPARAM(3)
+            DH22 = DPARAM(5)
+            DO I = 1,NSTEPS,INCX
+               W = DX(I)
+               Z = DY(I)
+               DX(I) = W*DH11 + Z*DH12
+               DY(I) = W*DH21 + Z*DH22
+            END DO
+         ELSE IF (DFLAG.EQ.ZERO) THEN
+            DH12 = DPARAM(4)
+            DH21 = DPARAM(3)
+            DO I = 1,NSTEPS,INCX
+               W = DX(I)
+               Z = DY(I)
+               DX(I) = W + Z*DH12
+               DY(I) = W*DH21 + Z
+            END DO
+         ELSE
+            DH11 = DPARAM(2)
+            DH22 = DPARAM(5)
+            DO I = 1,NSTEPS,INCX
+               W = DX(I)
+               Z = DY(I)
+               DX(I) = W*DH11 + Z
+               DY(I) = -W + DH22*Z
+            END DO
+         END IF
+      ELSE
+         KX = 1
+         KY = 1
+         IF (INCX.LT.0) KX = 1 + (1-N)*INCX
+         IF (INCY.LT.0) KY = 1 + (1-N)*INCY
+*
+         IF (DFLAG.LT.ZERO) THEN
+            DH11 = DPARAM(2)
+            DH12 = DPARAM(4)
+            DH21 = DPARAM(3)
+            DH22 = DPARAM(5)
+            DO I = 1,N
+               W = DX(KX)
+               Z = DY(KY)
+               DX(KX) = W*DH11 + Z*DH12
+               DY(KY) = W*DH21 + Z*DH22
+               KX = KX + INCX
+               KY = KY + INCY
+            END DO
+         ELSE IF (DFLAG.EQ.ZERO) THEN
+            DH12 = DPARAM(4)
+            DH21 = DPARAM(3)
+            DO I = 1,N
+               W = DX(KX)
+               Z = DY(KY)
+               DX(KX) = W + Z*DH12
+               DY(KY) = W*DH21 + Z
+               KX = KX + INCX
+               KY = KY + INCY
+            END DO
+         ELSE
+             DH11 = DPARAM(2)
+             DH22 = DPARAM(5)
+             DO I = 1,N
+                W = DX(KX)
+                Z = DY(KY)
+                DX(KX) = W*DH11 + Z
+                DY(KY) = -W + DH22*Z
+                KX = KX + INCX
+                KY = KY + INCY
+            END DO
+         END IF
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/drotmg.f b/superlu/BLAS/drotmg.f
new file mode 100644
index 0000000..1fb025f
--- /dev/null
+++ b/superlu/BLAS/drotmg.f
@@ -0,0 +1,251 @@
+*> \brief \b DROTMG
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DROTMG(DD1,DD2,DX1,DY1,DPARAM)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION DD1,DD2,DX1,DY1
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DPARAM(5)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    CONSTRUCT THE MODIFIED GIVENS TRANSFORMATION MATRIX H WHICH ZEROS
+*>    THE SECOND COMPONENT OF THE 2-VECTOR  (DSQRT(DD1)*DX1,DSQRT(DD2)*>    DY2)**T.
+*>    WITH DPARAM(1)=DFLAG, H HAS ONE OF THE FOLLOWING FORMS..
+*>
+*>    DFLAG=-1.D0     DFLAG=0.D0        DFLAG=1.D0     DFLAG=-2.D0
+*>
+*>      (DH11  DH12)    (1.D0  DH12)    (DH11  1.D0)    (1.D0  0.D0)
+*>    H=(          )    (          )    (          )    (          )
+*>      (DH21  DH22),   (DH21  1.D0),   (-1.D0 DH22),   (0.D0  1.D0).
+*>    LOCATIONS 2-4 OF DPARAM CONTAIN DH11, DH21, DH12, AND DH22
+*>    RESPECTIVELY. (VALUES OF 1.D0, -1.D0, OR 0.D0 IMPLIED BY THE
+*>    VALUE OF DPARAM(1) ARE NOT STORED IN DPARAM.)
+*>
+*>    THE VALUES OF GAMSQ AND RGAMSQ SET IN THE DATA STATEMENT MAY BE
+*>    INEXACT.  THIS IS OK AS THEY ARE ONLY USED FOR TESTING THE SIZE
+*>    OF DD1 AND DD2.  ALL ACTUAL SCALING OF DATA IS DONE USING GAM.
+*>
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in,out] DD1
+*> \verbatim
+*>          DD1 is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in,out] DD2
+*> \verbatim
+*>          DD2 is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in,out] DX1
+*> \verbatim
+*>          DX1 is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in] DY1
+*> \verbatim
+*>          DY1 is DOUBLE PRECISION
+*> \endverbatim
+*>
+*> \param[in,out] DPARAM
+*> \verbatim
+*>          DPARAM is DOUBLE PRECISION array, dimension 5
+*>     DPARAM(1)=DFLAG
+*>     DPARAM(2)=DH11
+*>     DPARAM(3)=DH21
+*>     DPARAM(4)=DH12
+*>     DPARAM(5)=DH22
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*  =====================================================================
+      SUBROUTINE DROTMG(DD1,DD2,DX1,DY1,DPARAM)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION DD1,DD2,DX1,DY1
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DPARAM(5)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION DFLAG,DH11,DH12,DH21,DH22,DP1,DP2,DQ1,DQ2,DTEMP,
+     $                 DU,GAM,GAMSQ,ONE,RGAMSQ,TWO,ZERO
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DABS
+*     ..
+*     .. Data statements ..
+*
+      DATA ZERO,ONE,TWO/0.D0,1.D0,2.D0/
+      DATA GAM,GAMSQ,RGAMSQ/4096.D0,16777216.D0,5.9604645D-8/
+*     ..
+
+      IF (DD1.LT.ZERO) THEN
+*        GO ZERO-H-D-AND-DX1..
+         DFLAG = -ONE
+         DH11 = ZERO
+         DH12 = ZERO
+         DH21 = ZERO
+         DH22 = ZERO
+*
+         DD1 = ZERO
+         DD2 = ZERO
+         DX1 = ZERO
+      ELSE
+*        CASE-DD1-NONNEGATIVE
+         DP2 = DD2*DY1
+         IF (DP2.EQ.ZERO) THEN
+            DFLAG = -TWO
+            DPARAM(1) = DFLAG
+            RETURN
+         END IF
+*        REGULAR-CASE..
+         DP1 = DD1*DX1
+         DQ2 = DP2*DY1
+         DQ1 = DP1*DX1
+*
+         IF (DABS(DQ1).GT.DABS(DQ2)) THEN
+            DH21 = -DY1/DX1
+            DH12 = DP2/DP1
+*
+            DU = ONE - DH12*DH21
+*
+           IF (DU.GT.ZERO) THEN
+             DFLAG = ZERO
+             DD1 = DD1/DU
+             DD2 = DD2/DU
+             DX1 = DX1*DU
+           END IF
+         ELSE
+
+            IF (DQ2.LT.ZERO) THEN
+*              GO ZERO-H-D-AND-DX1..
+               DFLAG = -ONE
+               DH11 = ZERO
+               DH12 = ZERO
+               DH21 = ZERO
+               DH22 = ZERO
+*
+               DD1 = ZERO
+               DD2 = ZERO
+               DX1 = ZERO
+            ELSE
+               DFLAG = ONE
+               DH11 = DP1/DP2
+               DH22 = DX1/DY1
+               DU = ONE + DH11*DH22
+               DTEMP = DD2/DU
+               DD2 = DD1/DU
+               DD1 = DTEMP
+               DX1 = DY1*DU
+            END IF
+         END IF
+
+*     PROCEDURE..SCALE-CHECK
+         IF (DD1.NE.ZERO) THEN
+            DO WHILE ((DD1.LE.RGAMSQ) .OR. (DD1.GE.GAMSQ))
+               IF (DFLAG.EQ.ZERO) THEN
+                  DH11 = ONE
+                  DH22 = ONE
+                  DFLAG = -ONE
+               ELSE
+                  DH21 = -ONE
+                  DH12 = ONE
+                  DFLAG = -ONE
+               END IF
+               IF (DD1.LE.RGAMSQ) THEN
+                  DD1 = DD1*GAM**2
+                  DX1 = DX1/GAM
+                  DH11 = DH11/GAM
+                  DH12 = DH12/GAM
+               ELSE
+                  DD1 = DD1/GAM**2
+                  DX1 = DX1*GAM
+                  DH11 = DH11*GAM
+                  DH12 = DH12*GAM
+               END IF
+            ENDDO
+         END IF
+
+         IF (DD2.NE.ZERO) THEN
+            DO WHILE ( (DABS(DD2).LE.RGAMSQ) .OR. (DABS(DD2).GE.GAMSQ) )
+               IF (DFLAG.EQ.ZERO) THEN
+                  DH11 = ONE
+                  DH22 = ONE
+                  DFLAG = -ONE
+               ELSE
+                  DH21 = -ONE
+                  DH12 = ONE
+                  DFLAG = -ONE
+               END IF
+               IF (DABS(DD2).LE.RGAMSQ) THEN
+                  DD2 = DD2*GAM**2
+                  DH21 = DH21/GAM
+                  DH22 = DH22/GAM
+               ELSE
+                  DD2 = DD2/GAM**2
+                  DH21 = DH21*GAM
+                  DH22 = DH22*GAM
+               END IF
+            END DO
+         END IF
+
+      END IF
+
+      IF (DFLAG.LT.ZERO) THEN
+         DPARAM(2) = DH11
+         DPARAM(3) = DH21
+         DPARAM(4) = DH12
+         DPARAM(5) = DH22
+      ELSE IF (DFLAG.EQ.ZERO) THEN
+         DPARAM(3) = DH21
+         DPARAM(4) = DH12
+      ELSE
+         DPARAM(2) = DH11
+         DPARAM(5) = DH22
+      END IF
+
+      DPARAM(1) = DFLAG
+      RETURN
+      END
+
+
+
+
diff --git a/superlu/BLAS/dsbmv.f b/superlu/BLAS/dsbmv.f
new file mode 100644
index 0000000..aea1213
--- /dev/null
+++ b/superlu/BLAS/dsbmv.f
@@ -0,0 +1,375 @@
+*> \brief \b DSBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER INCX,INCY,K,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSBMV  performs the matrix-vector  operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n symmetric band matrix, with k super-diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the band matrix A is being supplied as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  being supplied.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  being supplied.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry, K specifies the number of super-diagonals of the
+*>           matrix A. K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the symmetric matrix, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer the upper
+*>           triangular part of a symmetric band matrix from conventional
+*>           full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the symmetric matrix, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer the lower
+*>           triangular part of a symmetric band matrix from conventional
+*>           full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is DOUBLE PRECISION array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the
+*>           vector y. On exit, Y is overwritten by the updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER INCX,INCY,K,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KPLUS1,KX,KY,L
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (K.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of the array A
+*     are accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when upper triangle of A is stored.
+*
+          KPLUS1 = K + 1
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  L = KPLUS1 - J
+                  DO 50 I = MAX(1,J-K),J - 1
+                      Y(I) = Y(I) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + A(L+I,J)*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*A(KPLUS1,J) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  L = KPLUS1 - J
+                  DO 70 I = MAX(1,J-K),J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + A(L+I,J)*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*A(KPLUS1,J) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  IF (J.GT.K) THEN
+                      KX = KX + INCX
+                      KY = KY + INCY
+                  END IF
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when lower triangle of A is stored.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*A(1,J)
+                  L = 1 - J
+                  DO 90 I = J + 1,MIN(N,J+K)
+                      Y(I) = Y(I) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + A(L+I,J)*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*A(1,J)
+                  L = 1 - J
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,MIN(N,J+K)
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + A(L+I,J)*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSBMV .
+*
+      END
diff --git a/superlu/BLAS/dscal.f b/superlu/BLAS/dscal.f
new file mode 100644
index 0000000..8bbfec6
--- /dev/null
+++ b/superlu/BLAS/dscal.f
@@ -0,0 +1,110 @@
+*> \brief \b DSCAL
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSCAL(N,DA,DX,INCX)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION DA
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    DSCAL scales a vector by a constant.
+*>    uses unrolled loops for increment equal to one.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSCAL(N,DA,DX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION DA
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,M,MP1,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,5)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               DX(I) = DA*DX(I)
+            END DO
+            IF (N.LT.5) RETURN
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,5
+            DX(I) = DA*DX(I)
+            DX(I+1) = DA*DX(I+1)
+            DX(I+2) = DA*DX(I+2)
+            DX(I+3) = DA*DX(I+3)
+            DX(I+4) = DA*DX(I+4)
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            DX(I) = DA*DX(I)
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/dsdot.f b/superlu/BLAS/dsdot.f
new file mode 100644
index 0000000..f9cb498
--- /dev/null
+++ b/superlu/BLAS/dsdot.f
@@ -0,0 +1,172 @@
+*> \brief \b DSDOT
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       DOUBLE PRECISION FUNCTION DSDOT(N,SX,INCX,SY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*),SY(*)
+*       ..
+*
+*    AUTHORS
+*    =======
+*    Lawson, C. L., (JPL), Hanson, R. J., (SNLA),
+*    Kincaid, D. R., (U. of Texas), Krogh, F. T., (JPL)
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> Compute the inner product of two vectors with extended
+*> precision accumulation and result.
+*>
+*> Returns D.P. dot product accumulated in D.P., for S.P. SX and SY
+*> DSDOT = sum for I = 0 to N-1 of  SX(LX+I*INCX) * SY(LY+I*INCY),
+*> where LX = 1 if INCX .GE. 0, else LX = 1+(1-N)*INCX, and LY is
+*> defined in a similar way using INCY.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>         number of elements in input vector(s)
+*> \endverbatim
+*>
+*> \param[in] SX
+*> \verbatim
+*>          SX is REAL array, dimension(N)
+*>         single precision vector with N elements
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>          storage spacing between elements of SX
+*> \endverbatim
+*>
+*> \param[in] SY
+*> \verbatim
+*>          SY is REAL array, dimension(N)
+*>         single precision vector with N elements
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>         storage spacing between elements of SY
+*> \endverbatim
+*>
+*> \result DSDOT
+*> \verbatim
+*>          DSDOT is DOUBLE PRECISION
+*>         DSDOT  double precision dot product (zero if N.LE.0)
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*> \endverbatim
+*
+*> \par References:
+*  ================
+*>
+*> \verbatim
+*>
+*>
+*>  C. L. Lawson, R. J. Hanson, D. R. Kincaid and F. T.
+*>  Krogh, Basic linear algebra subprograms for Fortran
+*>  usage, Algorithm No. 539, Transactions on Mathematical
+*>  Software 5, 3 (September 1979), pp. 308-323.
+*>
+*>  REVISION HISTORY  (YYMMDD)
+*>
+*>  791001  DATE WRITTEN
+*>  890831  Modified array declarations.  (WRB)
+*>  890831  REVISION DATE from Version 3.2
+*>  891214  Prologue converted to Version 4.0 format.  (BAB)
+*>  920310  Corrected definition of LX in DESCRIPTION.  (WRB)
+*>  920501  Reformatted the REFERENCES section.  (WRB)
+*>  070118  Reformat to LAPACK style (JL)
+*> \endverbatim
+*>
+*  =====================================================================
+      DOUBLE PRECISION FUNCTION DSDOT(N,SX,INCX,SY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  Authors:
+*  ========
+*  Lawson, C. L., (JPL), Hanson, R. J., (SNLA),
+*  Kincaid, D. R., (U. of Texas), Krogh, F. T., (JPL)
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,KX,KY,NS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE
+*     ..
+      DSDOT = 0.0D0
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.INCY .AND. INCX.GT.0) THEN
+*
+*     Code for equal, positive, non-unit increments.
+*
+         NS = N*INCX
+         DO I = 1,NS,INCX
+            DSDOT = DSDOT + DBLE(SX(I))*DBLE(SY(I))
+         END DO
+      ELSE
+*
+*     Code for unequal or nonpositive increments.
+*
+         KX = 1
+         KY = 1
+         IF (INCX.LT.0) KX = 1 + (1-N)*INCX
+         IF (INCY.LT.0) KY = 1 + (1-N)*INCY
+         DO I = 1,N
+            DSDOT = DSDOT + DBLE(SX(KX))*DBLE(SY(KY))
+            KX = KX + INCX
+            KY = KY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/dspmv.f b/superlu/BLAS/dspmv.f
new file mode 100644
index 0000000..72a28fe
--- /dev/null
+++ b/superlu/BLAS/dspmv.f
@@ -0,0 +1,331 @@
+*> \brief \b DSPMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER INCX,INCY,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION AP(*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSPMV  performs the matrix-vector operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n symmetric matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is DOUBLE PRECISION array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y. On exit, Y is overwritten by the updated
+*>           vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER INCX,INCY,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION AP(*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 6
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSPMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when AP contains the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  K = KK
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + AP(K)*X(I)
+                      K = K + 1
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*AP(KK+J-1) + ALPHA*TEMP2
+                  KK = KK + J
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 K = KK,KK + J - 2
+                      Y(IY) = Y(IY) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + AP(K)*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*AP(KK+J-1) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + J
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when AP contains the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*AP(KK)
+                  K = KK + 1
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + AP(K)*X(I)
+                      K = K + 1
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+                  KK = KK + (N-J+1)
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*AP(KK)
+                  IX = JX
+                  IY = JY
+                  DO 110 K = KK + 1,KK + N - J
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + AP(K)*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + (N-J+1)
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSPMV .
+*
+      END
diff --git a/superlu/BLAS/dspr.f b/superlu/BLAS/dspr.f
new file mode 100644
index 0000000..e89f87d
--- /dev/null
+++ b/superlu/BLAS/dspr.f
@@ -0,0 +1,261 @@
+*> \brief \b DSPR
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSPR(UPLO,N,ALPHA,X,INCX,AP)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA
+*       INTEGER INCX,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSPR    performs the symmetric rank 1 operation
+*>
+*>    A := alpha*x*x**T + A,
+*>
+*> where alpha is a real scalar, x is an n element vector and A is an
+*> n by n symmetric matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] AP
+*> \verbatim
+*>          AP is DOUBLE PRECISION array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the upper triangular part of the
+*>           updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the lower triangular part of the
+*>           updated matrix.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSPR(UPLO,N,ALPHA,X,INCX,AP)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA
+      INTEGER INCX,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSPR  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when upper triangle is stored in AP.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      K = KK
+                      DO 10 I = 1,J
+                          AP(K) = AP(K) + X(I)*TEMP
+                          K = K + 1
+   10                 CONTINUE
+                  END IF
+                  KK = KK + J
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = KX
+                      DO 30 K = KK,KK + J - 1
+                          AP(K) = AP(K) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  KK = KK + J
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when lower triangle is stored in AP.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      K = KK
+                      DO 50 I = J,N
+                          AP(K) = AP(K) + X(I)*TEMP
+                          K = K + 1
+   50                 CONTINUE
+                  END IF
+                  KK = KK + N - J + 1
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = JX
+                      DO 70 K = KK,KK + N - J
+                          AP(K) = AP(K) + X(IX)*TEMP
+                          IX = IX + INCX
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  KK = KK + N - J + 1
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSPR  .
+*
+      END
diff --git a/superlu/BLAS/dspr2.f b/superlu/BLAS/dspr2.f
new file mode 100644
index 0000000..4cd416f
--- /dev/null
+++ b/superlu/BLAS/dspr2.f
@@ -0,0 +1,296 @@
+*> \brief \b DSPR2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSPR2(UPLO,N,ALPHA,X,INCX,Y,INCY,AP)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA
+*       INTEGER INCX,INCY,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION AP(*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSPR2  performs the symmetric rank 2 operation
+*>
+*>    A := alpha*x*y**T + alpha*y*x**T + A,
+*>
+*> where alpha is a scalar, x and y are n element vectors and A is an
+*> n by n symmetric matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] AP
+*> \verbatim
+*>          AP is DOUBLE PRECISION array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the upper triangular part of the
+*>           updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the lower triangular part of the
+*>           updated matrix.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSPR2(UPLO,N,ALPHA,X,INCX,Y,INCY,AP)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA
+      INTEGER INCX,INCY,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION AP(*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSPR2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when upper triangle is stored in AP.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      K = KK
+                      DO 10 I = 1,J
+                          AP(K) = AP(K) + X(I)*TEMP1 + Y(I)*TEMP2
+                          K = K + 1
+   10                 CONTINUE
+                  END IF
+                  KK = KK + J
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = KX
+                      IY = KY
+                      DO 30 K = KK,KK + J - 1
+                          AP(K) = AP(K) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + J
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when lower triangle is stored in AP.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      K = KK
+                      DO 50 I = J,N
+                          AP(K) = AP(K) + X(I)*TEMP1 + Y(I)*TEMP2
+                          K = K + 1
+   50                 CONTINUE
+                  END IF
+                  KK = KK + N - J + 1
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = JX
+                      IY = JY
+                      DO 70 K = KK,KK + N - J
+                          AP(K) = AP(K) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + N - J + 1
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSPR2 .
+*
+      END
diff --git a/superlu/BLAS/dswap.f b/superlu/BLAS/dswap.f
new file mode 100644
index 0000000..5bd8f7d
--- /dev/null
+++ b/superlu/BLAS/dswap.f
@@ -0,0 +1,122 @@
+*> \brief \b DSWAP
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSWAP(N,DX,INCX,DY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DX(*),DY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    interchanges two vectors.
+*>    uses unrolled loops for increments equal one.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSWAP(N,DX,INCX,DY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DX(*),DY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION DTEMP
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*       code for both increments equal to 1
+*
+*
+*       clean-up loop
+*
+         M = MOD(N,3)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               DTEMP = DX(I)
+               DX(I) = DY(I)
+               DY(I) = DTEMP
+            END DO
+            IF (N.LT.3) RETURN
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,3
+            DTEMP = DX(I)
+            DX(I) = DY(I)
+            DY(I) = DTEMP
+            DTEMP = DX(I+1)
+            DX(I+1) = DY(I+1)
+            DY(I+1) = DTEMP
+            DTEMP = DX(I+2)
+            DX(I+2) = DY(I+2)
+            DY(I+2) = DTEMP
+         END DO
+      ELSE
+*
+*       code for unequal increments or equal increments not equal
+*         to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            DTEMP = DX(IX)
+            DX(IX) = DY(IY)
+            DY(IY) = DTEMP
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/dsymm.f b/superlu/BLAS/dsymm.f
new file mode 100644
index 0000000..77c797e
--- /dev/null
+++ b/superlu/BLAS/dsymm.f
@@ -0,0 +1,367 @@
+*> \brief \b DSYMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER LDA,LDB,LDC,M,N
+*       CHARACTER SIDE,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSYMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*A*B + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*B*A + beta*C,
+*>
+*> where alpha and beta are scalars,  A is a symmetric matrix and  B and
+*> C are  m by n matrices.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE  specifies whether  the  symmetric matrix  A
+*>           appears on the  left or right  in the  operation as follows:
+*>
+*>              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*>
+*>              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of  the  symmetric  matrix   A  is  to  be
+*>           referenced as follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*>                                  symmetric matrix is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*>                                  symmetric matrix is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies the number of rows of the matrix  C.
+*>           M  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix C.
+*>           N  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is
+*>           m  when  SIDE = 'L' or 'l'  and is  n otherwise.
+*>           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*>           the array  A  must contain the  symmetric matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  symmetric matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  m by m  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  symmetric
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*>           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*>           the array  A  must contain the  symmetric matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  symmetric matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  n by n  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  symmetric
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least  max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is DOUBLE PRECISION array of DIMENSION ( LDB, n ).
+*>           Before entry, the leading  m by n part of the array  B  must
+*>           contain the matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is DOUBLE PRECISION array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n updated
+*>           matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSYMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*A(J,J)
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*A(J,K)
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(J,K)
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of DSYMM .
+*
+      END
diff --git a/superlu/BLAS/dsymv.f b/superlu/BLAS/dsymv.f
new file mode 100644
index 0000000..af2dfd2
--- /dev/null
+++ b/superlu/BLAS/dsymv.f
@@ -0,0 +1,333 @@
+*> \brief \b DSYMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSYMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER INCX,INCY,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSYMV  performs the matrix-vector  operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n symmetric matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the symmetric matrix and the strictly
+*>           lower triangular part of A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the symmetric matrix and the strictly
+*>           upper triangular part of A is not referenced.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y. On exit, Y is overwritten by the updated
+*>           vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSYMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 5
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSYMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when A is stored in upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*A(J,J) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 I = 1,J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*A(J,J) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when A is stored in lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*A(J,J)
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*A(J,J)
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,N
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYMV .
+*
+      END
diff --git a/superlu/BLAS/dsyr.f b/superlu/BLAS/dsyr.f
new file mode 100644
index 0000000..c998ee8
--- /dev/null
+++ b/superlu/BLAS/dsyr.f
@@ -0,0 +1,263 @@
+*> \brief \b DSYR
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSYR(UPLO,N,ALPHA,X,INCX,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA
+*       INTEGER INCX,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSYR   performs the symmetric rank 1 operation
+*>
+*>    A := alpha*x*x**T + A,
+*>
+*> where alpha is a real scalar, x is an n element vector and A is an
+*> n by n symmetric matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the symmetric matrix and the strictly
+*>           lower triangular part of A is not referenced. On exit, the
+*>           upper triangular part of the array A is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the symmetric matrix and the strictly
+*>           upper triangular part of A is not referenced. On exit, the
+*>           lower triangular part of the array A is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSYR(UPLO,N,ALPHA,X,INCX,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA
+      INTEGER INCX,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSYR  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in upper triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      DO 10 I = 1,J
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   10                 CONTINUE
+                  END IF
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = KX
+                      DO 30 I = 1,J
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in lower triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      DO 50 I = J,N
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   50                 CONTINUE
+                  END IF
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = JX
+                      DO 70 I = J,N
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+                          IX = IX + INCX
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYR  .
+*
+      END
diff --git a/superlu/BLAS/dsyr2.f b/superlu/BLAS/dsyr2.f
new file mode 100644
index 0000000..8bfa5fe
--- /dev/null
+++ b/superlu/BLAS/dsyr2.f
@@ -0,0 +1,298 @@
+*> \brief \b DSYR2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSYR2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA
+*       INTEGER INCX,INCY,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSYR2  performs the symmetric rank 2 operation
+*>
+*>    A := alpha*x*y**T + alpha*y*x**T + A,
+*>
+*> where alpha is a scalar, x and y are n element vectors and A is an n
+*> by n symmetric matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the symmetric matrix and the strictly
+*>           lower triangular part of A is not referenced. On exit, the
+*>           upper triangular part of the array A is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the symmetric matrix and the strictly
+*>           upper triangular part of A is not referenced. On exit, the
+*>           lower triangular part of the array A is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSYR2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSYR2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      DO 10 I = 1,J
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   10                 CONTINUE
+                  END IF
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = KX
+                      IY = KY
+                      DO 30 I = 1,J
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      DO 50 I = J,N
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   50                 CONTINUE
+                  END IF
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = JX
+                      IY = JY
+                      DO 70 I = J,N
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYR2 .
+*
+      END
diff --git a/superlu/BLAS/dsyr2k.f b/superlu/BLAS/dsyr2k.f
new file mode 100644
index 0000000..6dd7ca2
--- /dev/null
+++ b/superlu/BLAS/dsyr2k.f
@@ -0,0 +1,399 @@
+*> \brief \b DSYR2K
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSYR2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER K,LDA,LDB,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSYR2K  performs one of the symmetric rank 2k operations
+*>
+*>    C := alpha*A*B**T + alpha*B*A**T + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**T*B + alpha*B**T*A + beta*C,
+*>
+*> where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
+*> and  A and B  are  n by k  matrices  in the  first  case  and  k by n
+*> matrices in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   C := alpha*A*B**T + alpha*B*A**T +
+*>                                        beta*C.
+*>
+*>              TRANS = 'T' or 't'   C := alpha*A**T*B + alpha*B**T*A +
+*>                                        beta*C.
+*>
+*>              TRANS = 'C' or 'c'   C := alpha*A**T*B + alpha*B**T*A +
+*>                                        beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns  of the  matrices  A and B,  and on  entry  with
+*>           TRANS = 'T' or 't' or 'C' or 'c',  K  specifies  the  number
+*>           of rows of the matrices  A and B.  K must be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  k by n  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is DOUBLE PRECISION array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSYR2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP1,TEMP2
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSYR2K',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*B**T + alpha*B*A**T + C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**T*B + alpha*B**T*A + C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 190 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 220 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYR2K.
+*
+      END
diff --git a/superlu/BLAS/dsyrk.f b/superlu/BLAS/dsyrk.f
new file mode 100644
index 0000000..bd70dfb
--- /dev/null
+++ b/superlu/BLAS/dsyrk.f
@@ -0,0 +1,364 @@
+*> \brief \b DSYRK
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER K,LDA,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DSYRK  performs one of the symmetric rank k operations
+*>
+*>    C := alpha*A*A**T + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**T*A + beta*C,
+*>
+*> where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
+*> and  A  is an  n by k  matrix in the first case and a  k by n  matrix
+*> in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   C := alpha*A*A**T + beta*C.
+*>
+*>              TRANS = 'T' or 't'   C := alpha*A**T*A + beta*C.
+*>
+*>              TRANS = 'C' or 'c'   C := alpha*A**T*A + beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns   of  the   matrix   A,   and  on   entry   with
+*>           TRANS = 'T' or 't' or 'C' or 'c',  K  specifies  the  number
+*>           of rows of the matrix  A.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is DOUBLE PRECISION array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DSYRK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*A**T + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**T*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP = ZERO
+                      DO 220 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DSYRK .
+*
+      END
diff --git a/superlu/BLAS/dtbmv.f b/superlu/BLAS/dtbmv.f
new file mode 100644
index 0000000..20dd83e
--- /dev/null
+++ b/superlu/BLAS/dtbmv.f
@@ -0,0 +1,398 @@
+*> \brief \b DTBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DTBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,K,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DTBMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular band matrix, with ( k + 1 ) diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**T*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with UPLO = 'U' or 'u', K specifies the number of
+*>           super-diagonals of the matrix A.
+*>           On entry with UPLO = 'L' or 'l', K specifies the number of
+*>           sub-diagonals of the matrix A.
+*>           K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer an upper
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer a lower
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that when DIAG = 'U' or 'u' the elements of the array A
+*>           corresponding to the diagonal elements of the matrix are not
+*>           referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DTBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DTBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX   too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*         Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          L = KPLUS1 - J
+                          DO 10 I = MAX(1,J-K),J - 1
+                              X(I) = X(I) + TEMP*A(L+I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(KPLUS1,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          L = KPLUS1 - J
+                          DO 30 I = MAX(1,J-K),J - 1
+                              X(IX) = X(IX) + TEMP*A(L+I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(KPLUS1,J)
+                      END IF
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          L = 1 - J
+                          DO 50 I = MIN(N,J+K),J + 1,-1
+                              X(I) = X(I) + TEMP*A(L+I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(1,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          L = 1 - J
+                          DO 70 I = MIN(N,J+K),J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(L+I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(1,J)
+                      END IF
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = N,1,-1
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)
+                      DO 90 I = J - 1,MAX(1,J-K),-1
+                          TEMP = TEMP + A(L+I,J)*X(I)
+   90                 CONTINUE
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 120 J = N,1,-1
+                      TEMP = X(JX)
+                      KX = KX - INCX
+                      IX = KX
+                      L = KPLUS1 - J
+                      IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)
+                      DO 110 I = J - 1,MAX(1,J-K),-1
+                          TEMP = TEMP + A(L+I,J)*X(IX)
+                          IX = IX - INCX
+  110                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = 1,N
+                      TEMP = X(J)
+                      L = 1 - J
+                      IF (NOUNIT) TEMP = TEMP*A(1,J)
+                      DO 130 I = J + 1,MIN(N,J+K)
+                          TEMP = TEMP + A(L+I,J)*X(I)
+  130                 CONTINUE
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 160 J = 1,N
+                      TEMP = X(JX)
+                      KX = KX + INCX
+                      IX = KX
+                      L = 1 - J
+                      IF (NOUNIT) TEMP = TEMP*A(1,J)
+                      DO 150 I = J + 1,MIN(N,J+K)
+                          TEMP = TEMP + A(L+I,J)*X(IX)
+                          IX = IX + INCX
+  150                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTBMV .
+*
+      END
diff --git a/superlu/BLAS/dtbsv.f b/superlu/BLAS/dtbsv.f
new file mode 100644
index 0000000..ad46828
--- /dev/null
+++ b/superlu/BLAS/dtbsv.f
@@ -0,0 +1,401 @@
+*> \brief \b DTBSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DTBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,K,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DTBSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular band matrix, with ( k + 1 )
+*> diagonals.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**T*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with UPLO = 'U' or 'u', K specifies the number of
+*>           super-diagonals of the matrix A.
+*>           On entry with UPLO = 'L' or 'l', K specifies the number of
+*>           sub-diagonals of the matrix A.
+*>           K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer an upper
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer a lower
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that when DIAG = 'U' or 'u' the elements of the array A
+*>           corresponding to the diagonal elements of the matrix are not
+*>           referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DTBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DTBSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed by sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(KPLUS1,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,MAX(1,J-K),-1
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 40 J = N,1,-1
+                      KX = KX - INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(KPLUS1,J)
+                          TEMP = X(JX)
+                          DO 30 I = J - 1,MAX(1,J-K),-1
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX - INCX
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          L = 1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(1,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,MIN(N,J+K)
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      KX = KX + INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = 1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(1,J)
+                          TEMP = X(JX)
+                          DO 70 I = J + 1,MIN(N,J+K)
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX + INCX
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T)*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = 1,N
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      DO 90 I = MAX(1,J-K),J - 1
+                          TEMP = TEMP - A(L+I,J)*X(I)
+   90                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 120 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      L = KPLUS1 - J
+                      DO 110 I = MAX(1,J-K),J - 1
+                          TEMP = TEMP - A(L+I,J)*X(IX)
+                          IX = IX + INCX
+  110                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = N,1,-1
+                      TEMP = X(J)
+                      L = 1 - J
+                      DO 130 I = MIN(N,J+K),J + 1,-1
+                          TEMP = TEMP - A(L+I,J)*X(I)
+  130                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 160 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      L = 1 - J
+                      DO 150 I = MIN(N,J+K),J + 1,-1
+                          TEMP = TEMP - A(L+I,J)*X(IX)
+                          IX = IX - INCX
+  150                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTBSV .
+*
+      END
diff --git a/superlu/BLAS/dtpmv.f b/superlu/BLAS/dtpmv.f
new file mode 100644
index 0000000..3b0e620
--- /dev/null
+++ b/superlu/BLAS/dtpmv.f
@@ -0,0 +1,352 @@
+*> \brief \b DTPMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DTPMV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DTPMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**T*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is DOUBLE PRECISION array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 )
+*>           respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 )
+*>           respectively, and so on.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DTPMV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DTPMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of AP are
+*     accessed sequentially with one pass through AP.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x:= A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          K = KK
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*AP(K)
+                              K = K + 1
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*AP(KK+J-1)
+                      END IF
+                      KK = KK + J
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 K = KK,KK + J - 2
+                              X(IX) = X(IX) + TEMP*AP(K)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*AP(KK+J-1)
+                      END IF
+                      JX = JX + INCX
+                      KK = KK + J
+   40             CONTINUE
+              END IF
+          ELSE
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          K = KK
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*AP(K)
+                              K = K - 1
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*AP(KK-N+J)
+                      END IF
+                      KK = KK - (N-J+1)
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 K = KK,KK - (N- (J+1)),-1
+                              X(IX) = X(IX) + TEMP*AP(K)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*AP(KK-N+J)
+                      END IF
+                      JX = JX - INCX
+                      KK = KK - (N-J+1)
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*AP(KK)
+                      K = KK - 1
+                      DO 90 I = J - 1,1,-1
+                          TEMP = TEMP + AP(K)*X(I)
+                          K = K - 1
+   90                 CONTINUE
+                      X(J) = TEMP
+                      KK = KK - J
+  100             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 120 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*AP(KK)
+                      DO 110 K = KK - 1,KK - J + 1,-1
+                          IX = IX - INCX
+                          TEMP = TEMP + AP(K)*X(IX)
+  110                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      KK = KK - J
+  120             CONTINUE
+              END IF
+          ELSE
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = 1,N
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*AP(KK)
+                      K = KK + 1
+                      DO 130 I = J + 1,N
+                          TEMP = TEMP + AP(K)*X(I)
+                          K = K + 1
+  130                 CONTINUE
+                      X(J) = TEMP
+                      KK = KK + (N-J+1)
+  140             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 160 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*AP(KK)
+                      DO 150 K = KK + 1,KK + N - J
+                          IX = IX + INCX
+                          TEMP = TEMP + AP(K)*X(IX)
+  150                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      KK = KK + (N-J+1)
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTPMV .
+*
+      END
diff --git a/superlu/BLAS/dtpsv.f b/superlu/BLAS/dtpsv.f
new file mode 100644
index 0000000..a5d9faa
--- /dev/null
+++ b/superlu/BLAS/dtpsv.f
@@ -0,0 +1,354 @@
+*> \brief \b DTPSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DTPSV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DTPSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular matrix, supplied in packed form.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**T*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is DOUBLE PRECISION array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 )
+*>           respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 )
+*>           respectively, and so on.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DTPSV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DTPSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of AP are
+*     accessed sequentially with one pass through AP.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/AP(KK)
+                          TEMP = X(J)
+                          K = KK - 1
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*AP(K)
+                              K = K - 1
+   10                     CONTINUE
+                      END IF
+                      KK = KK - J
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/AP(KK)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 K = KK - 1,KK - J + 1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*AP(K)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+                      KK = KK - J
+   40             CONTINUE
+              END IF
+          ELSE
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/AP(KK)
+                          TEMP = X(J)
+                          K = KK + 1
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*AP(K)
+                              K = K + 1
+   50                     CONTINUE
+                      END IF
+                      KK = KK + (N-J+1)
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/AP(KK)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 K = KK + 1,KK + N - J
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*AP(K)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+                      KK = KK + (N-J+1)
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = 1,N
+                      TEMP = X(J)
+                      K = KK
+                      DO 90 I = 1,J - 1
+                          TEMP = TEMP - AP(K)*X(I)
+                          K = K + 1
+   90                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/AP(KK+J-1)
+                      X(J) = TEMP
+                      KK = KK + J
+  100             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 120 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 110 K = KK,KK + J - 2
+                          TEMP = TEMP - AP(K)*X(IX)
+                          IX = IX + INCX
+  110                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/AP(KK+J-1)
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      KK = KK + J
+  120             CONTINUE
+              END IF
+          ELSE
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = N,1,-1
+                      TEMP = X(J)
+                      K = KK
+                      DO 130 I = N,J + 1,-1
+                          TEMP = TEMP - AP(K)*X(I)
+                          K = K - 1
+  130                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/AP(KK-N+J)
+                      X(J) = TEMP
+                      KK = KK - (N-J+1)
+  140             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 160 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 150 K = KK,KK - (N- (J+1)),-1
+                          TEMP = TEMP - AP(K)*X(IX)
+                          IX = IX - INCX
+  150                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/AP(KK-N+J)
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      KK = KK - (N-J+1)
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTPSV .
+*
+      END
diff --git a/superlu/BLAS/dtrmm.f b/superlu/BLAS/dtrmm.f
new file mode 100644
index 0000000..e315d59
--- /dev/null
+++ b/superlu/BLAS/dtrmm.f
@@ -0,0 +1,415 @@
+*> \brief \b DTRMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DTRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA
+*       INTEGER LDA,LDB,M,N
+*       CHARACTER DIAG,SIDE,TRANSA,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),B(LDB,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DTRMM  performs one of the matrix-matrix operations
+*>
+*>    B := alpha*op( A )*B,   or   B := alpha*B*op( A ),
+*>
+*> where  alpha  is a scalar,  B  is an m by n matrix,  A  is a unit, or
+*> non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*>
+*>    op( A ) = A   or   op( A ) = A**T.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE specifies whether  op( A ) multiplies B from
+*>           the left or right as follows:
+*>
+*>              SIDE = 'L' or 'l'   B := alpha*op( A )*B.
+*>
+*>              SIDE = 'R' or 'r'   B := alpha*B*op( A ).
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix A is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n'   op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't'   op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c'   op( A ) = A**T.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit triangular
+*>           as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of B. M must be at
+*>           least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of B.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*>           zero then  A is not referenced and  B need not be set before
+*>           entry.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>           A is DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m
+*>           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*>           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*>           upper triangular part of the array  A must contain the upper
+*>           triangular matrix  and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*>           lower triangular part of the array  A must contain the lower
+*>           triangular matrix  and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*>           A  are not referenced either,  but are assumed to be  unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*>           then LDA must be at least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] B
+*> \verbatim
+*>          B is DOUBLE PRECISION array of DIMENSION ( LDB, n ).
+*>           Before entry,  the leading  m by n part of the array  B must
+*>           contain the matrix  B,  and  on exit  is overwritten  by the
+*>           transformed matrix.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DTRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),B(LDB,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DTRMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*A*B.
+*
+              IF (UPPER) THEN
+                  DO 50 J = 1,N
+                      DO 40 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              DO 30 I = 1,K - 1
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   30                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP*A(K,K)
+                              B(K,J) = TEMP
+                          END IF
+   40                 CONTINUE
+   50             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              B(K,J) = TEMP
+                              IF (NOUNIT) B(K,J) = B(K,J)*A(K,K)
+                              DO 60 I = K + 1,M
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   60                         CONTINUE
+                          END IF
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*A**T*B.
+*
+              IF (UPPER) THEN
+                  DO 110 J = 1,N
+                      DO 100 I = M,1,-1
+                          TEMP = B(I,J)
+                          IF (NOUNIT) TEMP = TEMP*A(I,I)
+                          DO 90 K = 1,I - 1
+                              TEMP = TEMP + A(K,I)*B(K,J)
+   90                     CONTINUE
+                          B(I,J) = ALPHA*TEMP
+  100                 CONTINUE
+  110             CONTINUE
+              ELSE
+                  DO 140 J = 1,N
+                      DO 130 I = 1,M
+                          TEMP = B(I,J)
+                          IF (NOUNIT) TEMP = TEMP*A(I,I)
+                          DO 120 K = I + 1,M
+                              TEMP = TEMP + A(K,I)*B(K,J)
+  120                     CONTINUE
+                          B(I,J) = ALPHA*TEMP
+  130                 CONTINUE
+  140             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*A.
+*
+              IF (UPPER) THEN
+                  DO 180 J = N,1,-1
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 150 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  150                 CONTINUE
+                      DO 170 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 160 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  160                         CONTINUE
+                          END IF
+  170                 CONTINUE
+  180             CONTINUE
+              ELSE
+                  DO 220 J = 1,N
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 190 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  190                 CONTINUE
+                      DO 210 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 200 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  200                         CONTINUE
+                          END IF
+  210                 CONTINUE
+  220             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*A**T.
+*
+              IF (UPPER) THEN
+                  DO 260 K = 1,N
+                      DO 240 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = ALPHA*A(J,K)
+                              DO 230 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  230                         CONTINUE
+                          END IF
+  240                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(K,K)
+                      IF (TEMP.NE.ONE) THEN
+                          DO 250 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  250                     CONTINUE
+                      END IF
+  260             CONTINUE
+              ELSE
+                  DO 300 K = N,1,-1
+                      DO 280 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = ALPHA*A(J,K)
+                              DO 270 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  270                         CONTINUE
+                          END IF
+  280                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(K,K)
+                      IF (TEMP.NE.ONE) THEN
+                          DO 290 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  290                     CONTINUE
+                      END IF
+  300             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTRMM .
+*
+      END
diff --git a/superlu/BLAS/dtrmv.f b/superlu/BLAS/dtrmv.f
new file mode 100644
index 0000000..83959d0
--- /dev/null
+++ b/superlu/BLAS/dtrmv.f
@@ -0,0 +1,342 @@
+*> \brief \b DTRMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DTRMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**T*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular matrix and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular matrix and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced either, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DTRMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*A(I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 I = 1,J - 1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*A(I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 I = N,J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 90 I = J - 1,1,-1
+                          TEMP = TEMP + A(I,J)*X(I)
+   90                 CONTINUE
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 120 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 110 I = J - 1,1,-1
+                          IX = IX - INCX
+                          TEMP = TEMP + A(I,J)*X(IX)
+  110                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = 1,N
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 130 I = J + 1,N
+                          TEMP = TEMP + A(I,J)*X(I)
+  130                 CONTINUE
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 160 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 150 I = J + 1,N
+                          IX = IX + INCX
+                          TEMP = TEMP + A(I,J)*X(IX)
+  150                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTRMV .
+*
+      END
diff --git a/superlu/BLAS/dtrsm.f b/superlu/BLAS/dtrsm.f
new file mode 100644
index 0000000..bc440f0
--- /dev/null
+++ b/superlu/BLAS/dtrsm.f
@@ -0,0 +1,443 @@
+*> \brief \b DTRSM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA
+*       INTEGER LDA,LDB,M,N
+*       CHARACTER DIAG,SIDE,TRANSA,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),B(LDB,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DTRSM  solves one of the matrix equations
+*>
+*>    op( A )*X = alpha*B,   or   X*op( A ) = alpha*B,
+*>
+*> where alpha is a scalar, X and B are m by n matrices, A is a unit, or
+*> non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*>
+*>    op( A ) = A   or   op( A ) = A**T.
+*>
+*> The matrix X is overwritten on B.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry, SIDE specifies whether op( A ) appears on the left
+*>           or right of X as follows:
+*>
+*>              SIDE = 'L' or 'l'   op( A )*X = alpha*B.
+*>
+*>              SIDE = 'R' or 'r'   X*op( A ) = alpha*B.
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix A is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n'   op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't'   op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c'   op( A ) = A**T.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit triangular
+*>           as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of B. M must be at
+*>           least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of B.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*>           zero then  A is not referenced and  B need not be set before
+*>           entry.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, k ),
+*>           where k is m when SIDE = 'L' or 'l'
+*>             and k is n when SIDE = 'R' or 'r'.
+*>           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*>           upper triangular part of the array  A must contain the upper
+*>           triangular matrix  and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*>           lower triangular part of the array  A must contain the lower
+*>           triangular matrix  and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*>           A  are not referenced either,  but are assumed to be  unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*>           then LDA must be at least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] B
+*> \verbatim
+*>          B is DOUBLE PRECISION array of DIMENSION ( LDB, n ).
+*>           Before entry,  the leading  m by n part of the array  B must
+*>           contain  the  right-hand  side  matrix  B,  and  on exit  is
+*>           overwritten by the solution matrix  X.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE DTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),B(LDB,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DTRSM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*inv( A )*B.
+*
+              IF (UPPER) THEN
+                  DO 60 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 30 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   30                     CONTINUE
+                      END IF
+                      DO 50 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 40 I = 1,K - 1
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   40                         CONTINUE
+                          END IF
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 100 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 70 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   70                     CONTINUE
+                      END IF
+                      DO 90 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 80 I = K + 1,M
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   80                         CONTINUE
+                          END IF
+   90                 CONTINUE
+  100             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*inv( A**T )*B.
+*
+              IF (UPPER) THEN
+                  DO 130 J = 1,N
+                      DO 120 I = 1,M
+                          TEMP = ALPHA*B(I,J)
+                          DO 110 K = 1,I - 1
+                              TEMP = TEMP - A(K,I)*B(K,J)
+  110                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          B(I,J) = TEMP
+  120                 CONTINUE
+  130             CONTINUE
+              ELSE
+                  DO 160 J = 1,N
+                      DO 150 I = M,1,-1
+                          TEMP = ALPHA*B(I,J)
+                          DO 140 K = I + 1,M
+                              TEMP = TEMP - A(K,I)*B(K,J)
+  140                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          B(I,J) = TEMP
+  150                 CONTINUE
+  160             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*inv( A ).
+*
+              IF (UPPER) THEN
+                  DO 210 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 170 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  170                     CONTINUE
+                      END IF
+                      DO 190 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 180 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  180                         CONTINUE
+                          END IF
+  190                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 200 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  200                     CONTINUE
+                      END IF
+  210             CONTINUE
+              ELSE
+                  DO 260 J = N,1,-1
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 220 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  220                     CONTINUE
+                      END IF
+                      DO 240 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 230 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  230                         CONTINUE
+                          END IF
+  240                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 250 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  250                     CONTINUE
+                      END IF
+  260             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*inv( A**T ).
+*
+              IF (UPPER) THEN
+                  DO 310 K = N,1,-1
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(K,K)
+                          DO 270 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  270                     CONTINUE
+                      END IF
+                      DO 290 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = A(J,K)
+                              DO 280 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  280                         CONTINUE
+                          END IF
+  290                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 300 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  300                     CONTINUE
+                      END IF
+  310             CONTINUE
+              ELSE
+                  DO 360 K = 1,N
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(K,K)
+                          DO 320 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  320                     CONTINUE
+                      END IF
+                      DO 340 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = A(J,K)
+                              DO 330 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  330                         CONTINUE
+                          END IF
+  340                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 350 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  350                     CONTINUE
+                      END IF
+  360             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTRSM .
+*
+      END
diff --git a/superlu/BLAS/dtrsv.f b/superlu/BLAS/dtrsv.f
new file mode 100644
index 0000000..cab3fd9
--- /dev/null
+++ b/superlu/BLAS/dtrsv.f
@@ -0,0 +1,338 @@
+*> \brief \b DTRSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE DTRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DTRSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular matrix.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**T*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is DOUBLE PRECISION array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular matrix and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular matrix and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced either, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is DOUBLE PRECISION array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*  =====================================================================
+      SUBROUTINE DTRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ZERO
+      PARAMETER (ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('DTRSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*A(I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 I = J - 1,1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*A(I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 I = J + 1,N
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = 1,N
+                      TEMP = X(J)
+                      DO 90 I = 1,J - 1
+                          TEMP = TEMP - A(I,J)*X(I)
+   90                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 120 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 110 I = 1,J - 1
+                          TEMP = TEMP - A(I,J)*X(IX)
+                          IX = IX + INCX
+  110                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = N,1,-1
+                      TEMP = X(J)
+                      DO 130 I = N,J + 1,-1
+                          TEMP = TEMP - A(I,J)*X(I)
+  130                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 160 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 150 I = N,J + 1,-1
+                          TEMP = TEMP - A(I,J)*X(IX)
+                          IX = IX - INCX
+  150                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of DTRSV .
+*
+      END
diff --git a/superlu/BLAS/dzasum.f b/superlu/BLAS/dzasum.f
new file mode 100644
index 0000000..9f0d3fd
--- /dev/null
+++ b/superlu/BLAS/dzasum.f
@@ -0,0 +1,98 @@
+*> \brief \b DZASUM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       DOUBLE PRECISION FUNCTION DZASUM(N,ZX,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 ZX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    DZASUM takes the sum of the (|Re(.)| + |Im(.)|)'s of a complex vector and
+*>    returns a single precision result.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      DOUBLE PRECISION FUNCTION DZASUM(N,ZX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 ZX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION STEMP
+      INTEGER I,NINCX
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION DCABS1
+      EXTERNAL DCABS1
+*     ..
+      DZASUM = 0.0d0
+      STEMP = 0.0d0
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         DO I = 1,N
+            STEMP = STEMP + DCABS1(ZX(I))
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            STEMP = STEMP + DCABS1(ZX(I))
+         END DO
+      END IF
+      DZASUM = STEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/dznrm2.f b/superlu/BLAS/dznrm2.f
new file mode 100644
index 0000000..3b6bf61
--- /dev/null
+++ b/superlu/BLAS/dznrm2.f
@@ -0,0 +1,119 @@
+*> \brief \b DZNRM2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       DOUBLE PRECISION FUNCTION DZNRM2(N,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> DZNRM2 returns the euclidean norm of a vector via the function
+*> name, so that
+*>
+*>    DZNRM2 := sqrt( x**H*x )
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup double_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  -- This version written on 25-October-1982.
+*>     Modified on 14-October-1993 to inline the call to ZLASSQ.
+*>     Sven Hammarling, Nag Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      DOUBLE PRECISION FUNCTION DZNRM2(N,X,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*     .. Local Scalars ..
+      DOUBLE PRECISION NORM,SCALE,SSQ,TEMP
+      INTEGER IX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,DBLE,DIMAG,SQRT
+*     ..
+      IF (N.LT.1 .OR. INCX.LT.1) THEN
+          NORM = ZERO
+      ELSE
+          SCALE = ZERO
+          SSQ = ONE
+*        The following loop is equivalent to this call to the LAPACK
+*        auxiliary routine:
+*        CALL ZLASSQ( N, X, INCX, SCALE, SSQ )
+*
+          DO 10 IX = 1,1 + (N-1)*INCX,INCX
+              IF (DBLE(X(IX)).NE.ZERO) THEN
+                  TEMP = ABS(DBLE(X(IX)))
+                  IF (SCALE.LT.TEMP) THEN
+                      SSQ = ONE + SSQ* (SCALE/TEMP)**2
+                      SCALE = TEMP
+                  ELSE
+                      SSQ = SSQ + (TEMP/SCALE)**2
+                  END IF
+              END IF
+              IF (DIMAG(X(IX)).NE.ZERO) THEN
+                  TEMP = ABS(DIMAG(X(IX)))
+                  IF (SCALE.LT.TEMP) THEN
+                      SSQ = ONE + SSQ* (SCALE/TEMP)**2
+                      SCALE = TEMP
+                  ELSE
+                      SSQ = SSQ + (TEMP/SCALE)**2
+                  END IF
+              END IF
+   10     CONTINUE
+          NORM = SCALE*SQRT(SSQ)
+      END IF
+*
+      DZNRM2 = NORM
+      RETURN
+*
+*     End of DZNRM2.
+*
+      END
diff --git a/superlu/BLAS/icamax.f b/superlu/BLAS/icamax.f
new file mode 100644
index 0000000..37035c7
--- /dev/null
+++ b/superlu/BLAS/icamax.f
@@ -0,0 +1,107 @@
+*> \brief \b ICAMAX
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       INTEGER FUNCTION ICAMAX(N,CX,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX CX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    ICAMAX finds the index of the first element having maximum |Re(.)| + |Im(.)|
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup aux_blas
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      INTEGER FUNCTION ICAMAX(N,CX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL SMAX
+      INTEGER I,IX
+*     ..
+*     .. External Functions ..
+      REAL SCABS1
+      EXTERNAL SCABS1
+*     ..
+      ICAMAX = 0
+      IF (N.LT.1 .OR. INCX.LE.0) RETURN
+      ICAMAX = 1
+      IF (N.EQ.1) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         SMAX = SCABS1(CX(1))
+         DO I = 2,N
+            IF (SCABS1(CX(I)).GT.SMAX) THEN
+               ICAMAX = I
+               SMAX = SCABS1(CX(I))
+            END IF
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         IX = 1
+         SMAX = SCABS1(CX(1))
+         IX = IX + INCX
+         DO I = 2,N
+            IF (SCABS1(CX(IX)).GT.SMAX) THEN
+               ICAMAX = I
+               SMAX = SCABS1(CX(IX))
+            END IF
+            IX = IX + INCX
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/idamax.f b/superlu/BLAS/idamax.f
new file mode 100644
index 0000000..9585660
--- /dev/null
+++ b/superlu/BLAS/idamax.f
@@ -0,0 +1,106 @@
+*> \brief \b IDAMAX
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       INTEGER FUNCTION IDAMAX(N,DX,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       DOUBLE PRECISION DX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    IDAMAX finds the index of the first element having maximum absolute value.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup aux_blas
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      INTEGER FUNCTION IDAMAX(N,DX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      DOUBLE PRECISION DX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION DMAX
+      INTEGER I,IX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DABS
+*     ..
+      IDAMAX = 0
+      IF (N.LT.1 .OR. INCX.LE.0) RETURN
+      IDAMAX = 1
+      IF (N.EQ.1) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         DMAX = DABS(DX(1))
+         DO I = 2,N
+            IF (DABS(DX(I)).GT.DMAX) THEN
+               IDAMAX = I
+               DMAX = DABS(DX(I))
+            END IF
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         IX = 1
+         DMAX = DABS(DX(1))
+         IX = IX + INCX
+         DO I = 2,N
+            IF (DABS(DX(IX)).GT.DMAX) THEN
+               IDAMAX = I
+               DMAX = DABS(DX(IX))
+            END IF
+            IX = IX + INCX
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/isamax.f b/superlu/BLAS/isamax.f
new file mode 100644
index 0000000..e731223
--- /dev/null
+++ b/superlu/BLAS/isamax.f
@@ -0,0 +1,106 @@
+*> \brief \b ISAMAX
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       INTEGER FUNCTION ISAMAX(N,SX,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    ISAMAX finds the index of the first element having maximum absolute value.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup aux_blas
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      INTEGER FUNCTION ISAMAX(N,SX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL SMAX
+      INTEGER I,IX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS
+*     ..
+      ISAMAX = 0
+      IF (N.LT.1 .OR. INCX.LE.0) RETURN
+      ISAMAX = 1
+      IF (N.EQ.1) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         SMAX = ABS(SX(1))
+         DO I = 2,N
+            IF (ABS(SX(I)).GT.SMAX) THEN
+               ISAMAX = I
+               SMAX = ABS(SX(I))
+            END IF
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         IX = 1
+         SMAX = ABS(SX(1))
+         IX = IX + INCX
+         DO I = 2,N
+            IF (ABS(SX(IX)).GT.SMAX) THEN
+               ISAMAX = I
+               SMAX = ABS(SX(IX))
+            END IF
+            IX = IX + INCX
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/izamax.f b/superlu/BLAS/izamax.f
new file mode 100644
index 0000000..2ee9b66
--- /dev/null
+++ b/superlu/BLAS/izamax.f
@@ -0,0 +1,107 @@
+*> \brief \b IZAMAX
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       INTEGER FUNCTION IZAMAX(N,ZX,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 ZX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    IZAMAX finds the index of the first element having maximum |Re(.)| + |Im(.)|
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup aux_blas
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, 1/15/85.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      INTEGER FUNCTION IZAMAX(N,ZX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 ZX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION DMAX
+      INTEGER I,IX
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION DCABS1
+      EXTERNAL DCABS1
+*     ..
+      IZAMAX = 0
+      IF (N.LT.1 .OR. INCX.LE.0) RETURN
+      IZAMAX = 1
+      IF (N.EQ.1) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         DMAX = DCABS1(ZX(1))
+         DO I = 2,N
+            IF (DCABS1(ZX(I)).GT.DMAX) THEN
+               IZAMAX = I
+               DMAX = DCABS1(ZX(I))
+            END IF
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         IX = 1
+         DMAX = DCABS1(ZX(1))
+         IX = IX + INCX
+         DO I = 2,N
+            IF (DCABS1(ZX(IX)).GT.DMAX) THEN
+               IZAMAX = I
+               DMAX = DCABS1(ZX(IX))
+            END IF
+            IX = IX + INCX
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/lsame.f b/superlu/BLAS/lsame.f
new file mode 100644
index 0000000..d819478
--- /dev/null
+++ b/superlu/BLAS/lsame.f
@@ -0,0 +1,125 @@
+*> \brief \b LSAME
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       LOGICAL FUNCTION LSAME(CA,CB)
+*
+*       .. Scalar Arguments ..
+*       CHARACTER CA,CB
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> LSAME returns .TRUE. if CA is the same letter as CB regardless of
+*> case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] CA
+*> \verbatim
+*>          CA is CHARACTER*1
+*> \endverbatim
+*>
+*> \param[in] CB
+*> \verbatim
+*>          CB is CHARACTER*1
+*>          CA and CB specify the single characters to be compared.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup aux_blas
+*
+*  =====================================================================
+      LOGICAL FUNCTION LSAME(CA,CB)
+*
+*  -- Reference BLAS level1 routine (version 3.1) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      CHARACTER CA,CB
+*     ..
+*
+* =====================================================================
+*
+*     .. Intrinsic Functions ..
+      INTRINSIC ICHAR
+*     ..
+*     .. Local Scalars ..
+      INTEGER INTA,INTB,ZCODE
+*     ..
+*
+*     Test if the characters are equal
+*
+      LSAME = CA .EQ. CB
+      IF (LSAME) RETURN
+*
+*     Now test for equivalence if both characters are alphabetic.
+*
+      ZCODE = ICHAR('Z')
+*
+*     Use 'Z' rather than 'A' so that ASCII can be detected on Prime
+*     machines, on which ICHAR returns a value with bit 8 set.
+*     ICHAR('A') on Prime machines returns 193 which is the same as
+*     ICHAR('A') on an EBCDIC machine.
+*
+      INTA = ICHAR(CA)
+      INTB = ICHAR(CB)
+*
+      IF (ZCODE.EQ.90 .OR. ZCODE.EQ.122) THEN
+*
+*        ASCII is assumed - ZCODE is the ASCII code of either lower or
+*        upper case 'Z'.
+*
+          IF (INTA.GE.97 .AND. INTA.LE.122) INTA = INTA - 32
+          IF (INTB.GE.97 .AND. INTB.LE.122) INTB = INTB - 32
+*
+      ELSE IF (ZCODE.EQ.233 .OR. ZCODE.EQ.169) THEN
+*
+*        EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or
+*        upper case 'Z'.
+*
+          IF (INTA.GE.129 .AND. INTA.LE.137 .OR.
+     +        INTA.GE.145 .AND. INTA.LE.153 .OR.
+     +        INTA.GE.162 .AND. INTA.LE.169) INTA = INTA + 64
+          IF (INTB.GE.129 .AND. INTB.LE.137 .OR.
+     +        INTB.GE.145 .AND. INTB.LE.153 .OR.
+     +        INTB.GE.162 .AND. INTB.LE.169) INTB = INTB + 64
+*
+      ELSE IF (ZCODE.EQ.218 .OR. ZCODE.EQ.250) THEN
+*
+*        ASCII is assumed, on Prime machines - ZCODE is the ASCII code
+*        plus 128 of either lower or upper case 'Z'.
+*
+          IF (INTA.GE.225 .AND. INTA.LE.250) INTA = INTA - 32
+          IF (INTB.GE.225 .AND. INTB.LE.250) INTB = INTB - 32
+      END IF
+      LSAME = INTA .EQ. INTB
+*
+*     RETURN
+*
+*     End of LSAME
+*
+      END
diff --git a/superlu/BLAS/sasum.f b/superlu/BLAS/sasum.f
new file mode 100644
index 0000000..a453ff7
--- /dev/null
+++ b/superlu/BLAS/sasum.f
@@ -0,0 +1,112 @@
+*> \brief \b SASUM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       REAL FUNCTION SASUM(N,SX,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    SASUM takes the sum of the absolute values.
+*>    uses unrolled loops for increment equal to one.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      REAL FUNCTION SASUM(N,SX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,M,MP1,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,MOD
+*     ..
+      SASUM = 0.0e0
+      STEMP = 0.0e0
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*        code for increment equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,6)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               STEMP = STEMP + ABS(SX(I))
+            END DO
+            IF (N.LT.6) THEN
+               SASUM = STEMP
+               RETURN
+            END IF
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,6
+            STEMP = STEMP + ABS(SX(I)) + ABS(SX(I+1)) +
+     $              ABS(SX(I+2)) + ABS(SX(I+3)) +
+     $              ABS(SX(I+4)) + ABS(SX(I+5))
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            STEMP = STEMP + ABS(SX(I))
+         END DO
+      END IF
+      SASUM = STEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/saxpy.f b/superlu/BLAS/saxpy.f
new file mode 100644
index 0000000..610dfe7
--- /dev/null
+++ b/superlu/BLAS/saxpy.f
@@ -0,0 +1,115 @@
+*> \brief \b SAXPY
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SAXPY(N,SA,SX,INCX,SY,INCY)
+*
+*       .. Scalar Arguments ..
+*       REAL SA
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*),SY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    SAXPY constant times a vector plus a vector.
+*>    uses unrolled loops for increments equal to one.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SAXPY(N,SA,SX,INCX,SY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL SA
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0) RETURN
+      IF (SA.EQ.0.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,4)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               SY(I) = SY(I) + SA*SX(I)
+            END DO
+         END IF
+         IF (N.LT.4) RETURN
+         MP1 = M + 1
+         DO I = MP1,N,4
+            SY(I) = SY(I) + SA*SX(I)
+            SY(I+1) = SY(I+1) + SA*SX(I+1)
+            SY(I+2) = SY(I+2) + SA*SX(I+2)
+            SY(I+3) = SY(I+3) + SA*SX(I+3)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+          SY(IY) = SY(IY) + SA*SX(IX)
+          IX = IX + INCX
+          IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/scabs1.f b/superlu/BLAS/scabs1.f
new file mode 100644
index 0000000..b68f76f
--- /dev/null
+++ b/superlu/BLAS/scabs1.f
@@ -0,0 +1,57 @@
+*> \brief \b SCABS1
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       REAL FUNCTION SCABS1(Z)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX Z
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SCABS1 computes |Re(.)| + |Im(.)| of a complex number
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*  =====================================================================
+      REAL FUNCTION SCABS1(Z)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX Z
+*     ..
+*
+*  =====================================================================
+*
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,AIMAG,REAL
+*     ..
+      SCABS1 = ABS(REAL(Z)) + ABS(AIMAG(Z))
+      RETURN
+      END
diff --git a/superlu/BLAS/scasum.f b/superlu/BLAS/scasum.f
new file mode 100644
index 0000000..5fc1a56
--- /dev/null
+++ b/superlu/BLAS/scasum.f
@@ -0,0 +1,97 @@
+*> \brief \b SCASUM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       REAL FUNCTION SCASUM(N,CX,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX CX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    SCASUM takes the sum of the (|Re(.)| + |Im(.)|)'s of a complex vector and
+*>    returns a single precision result.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      REAL FUNCTION SCASUM(N,CX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX CX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,AIMAG,REAL
+*     ..
+      SCASUM = 0.0e0
+      STEMP = 0.0e0
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         DO I = 1,N
+            STEMP = STEMP + ABS(REAL(CX(I))) + ABS(AIMAG(CX(I)))
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            STEMP = STEMP + ABS(REAL(CX(I))) + ABS(AIMAG(CX(I)))
+         END DO
+      END IF
+      SCASUM = STEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/scnrm2.f b/superlu/BLAS/scnrm2.f
new file mode 100644
index 0000000..4f1f03a
--- /dev/null
+++ b/superlu/BLAS/scnrm2.f
@@ -0,0 +1,119 @@
+*> \brief \b SCNRM2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       REAL FUNCTION SCNRM2(N,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SCNRM2 returns the euclidean norm of a vector via the function
+*> name, so that
+*>
+*>    SCNRM2 := sqrt( x**H*x )
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  -- This version written on 25-October-1982.
+*>     Modified on 14-October-1993 to inline the call to CLASSQ.
+*>     Sven Hammarling, Nag Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      REAL FUNCTION SCNRM2(N,X,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL NORM,SCALE,SSQ,TEMP
+      INTEGER IX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,AIMAG,REAL,SQRT
+*     ..
+      IF (N.LT.1 .OR. INCX.LT.1) THEN
+          NORM = ZERO
+      ELSE
+          SCALE = ZERO
+          SSQ = ONE
+*        The following loop is equivalent to this call to the LAPACK
+*        auxiliary routine:
+*        CALL CLASSQ( N, X, INCX, SCALE, SSQ )
+*
+          DO 10 IX = 1,1 + (N-1)*INCX,INCX
+              IF (REAL(X(IX)).NE.ZERO) THEN
+                  TEMP = ABS(REAL(X(IX)))
+                  IF (SCALE.LT.TEMP) THEN
+                      SSQ = ONE + SSQ* (SCALE/TEMP)**2
+                      SCALE = TEMP
+                  ELSE
+                      SSQ = SSQ + (TEMP/SCALE)**2
+                  END IF
+              END IF
+              IF (AIMAG(X(IX)).NE.ZERO) THEN
+                  TEMP = ABS(AIMAG(X(IX)))
+                  IF (SCALE.LT.TEMP) THEN
+                      SSQ = ONE + SSQ* (SCALE/TEMP)**2
+                      SCALE = TEMP
+                  ELSE
+                      SSQ = SSQ + (TEMP/SCALE)**2
+                  END IF
+              END IF
+   10     CONTINUE
+          NORM = SCALE*SQRT(SSQ)
+      END IF
+*
+      SCNRM2 = NORM
+      RETURN
+*
+*     End of SCNRM2.
+*
+      END
diff --git a/superlu/BLAS/scopy.f b/superlu/BLAS/scopy.f
new file mode 100644
index 0000000..4755797
--- /dev/null
+++ b/superlu/BLAS/scopy.f
@@ -0,0 +1,115 @@
+*> \brief \b SCOPY
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SCOPY(N,SX,INCX,SY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*),SY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    SCOPY copies a vector, x, to a vector, y.
+*>    uses unrolled loops for increments equal to 1.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SCOPY(N,SX,INCX,SY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,7)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               SY(I) = SX(I)
+            END DO
+            IF (N.LT.7) RETURN
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,7
+            SY(I) = SX(I)
+            SY(I+1) = SX(I+1)
+            SY(I+2) = SX(I+2)
+            SY(I+3) = SX(I+3)
+            SY(I+4) = SX(I+4)
+            SY(I+5) = SX(I+5)
+            SY(I+6) = SX(I+6)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            SY(IY) = SX(IX)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/sdot.f b/superlu/BLAS/sdot.f
new file mode 100644
index 0000000..5a54ee2
--- /dev/null
+++ b/superlu/BLAS/sdot.f
@@ -0,0 +1,117 @@
+*> \brief \b SDOT
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       REAL FUNCTION SDOT(N,SX,INCX,SY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*),SY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    SDOT forms the dot product of two vectors.
+*>    uses unrolled loops for increments equal to one.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      REAL FUNCTION SDOT(N,SX,INCX,SY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      STEMP = 0.0e0
+      SDOT = 0.0e0
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,5)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               STEMP = STEMP + SX(I)*SY(I)
+            END DO
+            IF (N.LT.5) THEN
+               SDOT=STEMP
+            RETURN
+            END IF
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,5
+          STEMP = STEMP + SX(I)*SY(I) + SX(I+1)*SY(I+1) +
+     $            SX(I+2)*SY(I+2) + SX(I+3)*SY(I+3) + SX(I+4)*SY(I+4)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            STEMP = STEMP + SX(IX)*SY(IY)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      SDOT = STEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/sdsdot.f b/superlu/BLAS/sdsdot.f
new file mode 100644
index 0000000..7ee6ad6
--- /dev/null
+++ b/superlu/BLAS/sdsdot.f
@@ -0,0 +1,255 @@
+*> \brief \b SDSDOT
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       REAL FUNCTION SDSDOT(N,SB,SX,INCX,SY,INCY)
+*
+*       .. Scalar Arguments ..
+*       REAL SB
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*),SY(*)
+*       ..
+*
+*    PURPOSE
+*    =======
+*
+*    Compute the inner product of two vectors with extended
+*    precision accumulation.
+*
+*    Returns S.P. result with dot product accumulated in D.P.
+*    SDSDOT = SB + sum for I = 0 to N-1 of SX(LX+I*INCX)*SY(LY+I*INCY),
+*    where LX = 1 if INCX .GE. 0, else LX = 1+(1-N)*INCX, and LY is
+*    defined in a similar way using INCY.
+*
+*    AUTHOR
+*    ======
+*    Lawson, C. L., (JPL), Hanson, R. J., (SNLA),
+*    Kincaid, D. R., (U. of Texas), Krogh, F. T., (JPL)
+*
+*    ARGUMENTS
+*    =========
+*
+*    N      (input) INTEGER
+*           number of elements in input vector(s)
+*
+*    SB     (input) REAL
+*           single precision scalar to be added to inner product
+*
+*    SX     (input) REAL array, dimension (N)
+*           single precision vector with N elements
+*
+*    INCX   (input) INTEGER
+*           storage spacing between elements of SX
+*
+*    SY     (input) REAL array, dimension (N)
+*           single precision vector with N elements
+*
+*    INCY   (input) INTEGER
+*           storage spacing between elements of SY
+*
+*    SDSDOT (output) REAL
+*           single precision dot product (SB if N .LE. 0)
+*
+*    Further Details
+*    ===============
+*
+*    REFERENCES
+*
+*    C. L. Lawson, R. J. Hanson, D. R. Kincaid and F. T.
+*    Krogh, Basic linear algebra subprograms for Fortran
+*    usage, Algorithm No. 539, Transactions on Mathematical
+*    Software 5, 3 (September 1979), pp. 308-323.
+*
+*    REVISION HISTORY  (YYMMDD)
+*
+*    791001  DATE WRITTEN
+*    890531  Changed all specific intrinsics to generic.  (WRB)
+*    890831  Modified array declarations.  (WRB)
+*    890831  REVISION DATE from Version 3.2
+*    891214  Prologue converted to Version 4.0 format.  (BAB)
+*    920310  Corrected definition of LX in DESCRIPTION.  (WRB)
+*    920501  Reformatted the REFERENCES section.  (WRB)
+*    070118  Reformat to LAPACK coding style
+*
+*    =====================================================================
+*
+*       .. Local Scalars ..
+*       DOUBLE PRECISION DSDOT
+*       INTEGER I,KX,KY,NS
+*       ..
+*       .. Intrinsic Functions ..
+*       INTRINSIC DBLE
+*       ..
+*       DSDOT = SB
+*       IF (N.LE.0) THEN
+*          SDSDOT = DSDOT
+*          RETURN
+*       END IF
+*       IF (INCX.EQ.INCY .AND. INCX.GT.0) THEN
+*
+*       Code for equal and positive increments.
+*
+*          NS = N*INCX
+*          DO I = 1,NS,INCX
+*             DSDOT = DSDOT + DBLE(SX(I))*DBLE(SY(I))
+*          END DO
+*       ELSE
+*
+*       Code for unequal or nonpositive increments.
+*
+*          KX = 1
+*          KY = 1
+*          IF (INCX.LT.0) KX = 1 + (1-N)*INCX
+*          IF (INCY.LT.0) KY = 1 + (1-N)*INCY
+*          DO I = 1,N
+*             DSDOT = DSDOT + DBLE(SX(KX))*DBLE(SY(KY))
+*             KX = KX + INCX
+*             KY = KY + INCY
+*          END DO
+*       END IF
+*       SDSDOT = DSDOT
+*       RETURN
+*       END
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*  =====================================================================
+      REAL FUNCTION SDSDOT(N,SB,SX,INCX,SY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL SB
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  PURPOSE
+*  =======
+*
+*  Compute the inner product of two vectors with extended
+*  precision accumulation.
+*
+*  Returns S.P. result with dot product accumulated in D.P.
+*  SDSDOT = SB + sum for I = 0 to N-1 of SX(LX+I*INCX)*SY(LY+I*INCY),
+*  where LX = 1 if INCX .GE. 0, else LX = 1+(1-N)*INCX, and LY is
+*  defined in a similar way using INCY.
+*
+*  AUTHOR
+*  ======
+*  Lawson, C. L., (JPL), Hanson, R. J., (SNLA),
+*  Kincaid, D. R., (U. of Texas), Krogh, F. T., (JPL)
+*
+*  ARGUMENTS
+*  =========
+*
+*  N      (input) INTEGER
+*         number of elements in input vector(s)
+*
+*  SB     (input) REAL
+*         single precision scalar to be added to inner product
+*
+*  SX     (input) REAL array, dimension (N)
+*         single precision vector with N elements
+*
+*  INCX   (input) INTEGER
+*         storage spacing between elements of SX
+*
+*  SY     (input) REAL array, dimension (N)
+*         single precision vector with N elements
+*
+*  INCY   (input) INTEGER
+*         storage spacing between elements of SY
+*
+*  SDSDOT (output) REAL
+*         single precision dot product (SB if N .LE. 0)
+*
+*  Further Details
+*  ===============
+*
+*  REFERENCES
+*
+*  C. L. Lawson, R. J. Hanson, D. R. Kincaid and F. T.
+*  Krogh, Basic linear algebra subprograms for Fortran
+*  usage, Algorithm No. 539, Transactions on Mathematical
+*  Software 5, 3 (September 1979), pp. 308-323.
+*
+*  REVISION HISTORY  (YYMMDD)
+*
+*  791001  DATE WRITTEN
+*  890531  Changed all specific intrinsics to generic.  (WRB)
+*  890831  Modified array declarations.  (WRB)
+*  890831  REVISION DATE from Version 3.2
+*  891214  Prologue converted to Version 4.0 format.  (BAB)
+*  920310  Corrected definition of LX in DESCRIPTION.  (WRB)
+*  920501  Reformatted the REFERENCES section.  (WRB)
+*  070118  Reformat to LAPACK coding style
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      DOUBLE PRECISION DSDOT
+      INTEGER I,KX,KY,NS
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE
+*     ..
+      DSDOT = SB
+      IF (N.LE.0) THEN
+         SDSDOT = DSDOT
+         RETURN
+      END IF
+      IF (INCX.EQ.INCY .AND. INCX.GT.0) THEN
+*
+*     Code for equal and positive increments.
+*
+         NS = N*INCX
+         DO I = 1,NS,INCX
+            DSDOT = DSDOT + DBLE(SX(I))*DBLE(SY(I))
+         END DO
+      ELSE
+*
+*     Code for unequal or nonpositive increments.
+*
+         KX = 1
+         KY = 1
+         IF (INCX.LT.0) KX = 1 + (1-N)*INCX
+         IF (INCY.LT.0) KY = 1 + (1-N)*INCY
+         DO I = 1,N
+            DSDOT = DSDOT + DBLE(SX(KX))*DBLE(SY(KY))
+            KX = KX + INCX
+            KY = KY + INCY
+         END DO
+      END IF
+      SDSDOT = DSDOT
+      RETURN
+      END
diff --git a/superlu/BLAS/sgbmv.f b/superlu/BLAS/sgbmv.f
new file mode 100644
index 0000000..9289632
--- /dev/null
+++ b/superlu/BLAS/sgbmv.f
@@ -0,0 +1,370 @@
+*> \brief \b SGBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SGBMV(TRANS,M,N,KL,KU,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER INCX,INCY,KL,KU,LDA,M,N
+*       CHARACTER TRANS
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SGBMV  performs one of the matrix-vector operations
+*>
+*>    y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are vectors and A is an
+*> m by n band matrix, with kl sub-diagonals and ku super-diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*>
+*>              TRANS = 'T' or 't'   y := alpha*A**T*x + beta*y.
+*>
+*>              TRANS = 'C' or 'c'   y := alpha*A**T*x + beta*y.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] KL
+*> \verbatim
+*>          KL is INTEGER
+*>           On entry, KL specifies the number of sub-diagonals of the
+*>           matrix A. KL must satisfy  0 .le. KL.
+*> \endverbatim
+*>
+*> \param[in] KU
+*> \verbatim
+*>          KU is INTEGER
+*>           On entry, KU specifies the number of super-diagonals of the
+*>           matrix A. KU must satisfy  0 .le. KU.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading ( kl + ku + 1 ) by n part of the
+*>           array A must contain the matrix of coefficients, supplied
+*>           column by column, with the leading diagonal of the matrix in
+*>           row ( ku + 1 ) of the array, the first super-diagonal
+*>           starting at position 2 in row ku, the first sub-diagonal
+*>           starting at position 1 in row ( ku + 2 ), and so on.
+*>           Elements in the array A that do not correspond to elements
+*>           in the band matrix (such as the top left ku by ku triangle)
+*>           are not referenced.
+*>           The following program segment will transfer a band matrix
+*>           from conventional full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    K = KU + 1 - J
+*>                    DO 10, I = MAX( 1, J - KU ), MIN( M, J + KL )
+*>                       A( K + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( kl + ku + 1 ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is REAL array of DIMENSION at least
+*>           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*>           Before entry, the incremented array Y must contain the
+*>           vector y. On exit, Y is overwritten by the updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SGBMV(TRANS,M,N,KL,KU,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER INCX,INCY,KL,KU,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KUP1,KX,KY,LENX,LENY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (KL.LT.0) THEN
+          INFO = 4
+      ELSE IF (KU.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (KL+KU+1)) THEN
+          INFO = 8
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 10
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SGBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the band part of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      KUP1 = KU + 1
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  K = KUP1 - J
+                  DO 50 I = MAX(1,J-KU),MIN(M,J+KL)
+                      Y(I) = Y(I) + TEMP*A(K+I,J)
+   50             CONTINUE
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  IY = KY
+                  K = KUP1 - J
+                  DO 70 I = MAX(1,J-KU),MIN(M,J+KL)
+                      Y(IY) = Y(IY) + TEMP*A(K+I,J)
+                      IY = IY + INCY
+   70             CONTINUE
+                  JX = JX + INCX
+                  IF (J.GT.KU) KY = KY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A**T*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 100 J = 1,N
+                  TEMP = ZERO
+                  K = KUP1 - J
+                  DO 90 I = MAX(1,J-KU),MIN(M,J+KL)
+                      TEMP = TEMP + A(K+I,J)*X(I)
+   90             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  100         CONTINUE
+          ELSE
+              DO 120 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  K = KUP1 - J
+                  DO 110 I = MAX(1,J-KU),MIN(M,J+KL)
+                      TEMP = TEMP + A(K+I,J)*X(IX)
+                      IX = IX + INCX
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+                  IF (J.GT.KU) KX = KX + INCX
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SGBMV .
+*
+      END
diff --git a/superlu/BLAS/sgemm.f b/superlu/BLAS/sgemm.f
new file mode 100644
index 0000000..d7bdb9c
--- /dev/null
+++ b/superlu/BLAS/sgemm.f
@@ -0,0 +1,384 @@
+*> \brief \b SGEMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER K,LDA,LDB,LDC,M,N
+*       CHARACTER TRANSA,TRANSB
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SGEMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*op( A )*op( B ) + beta*C,
+*>
+*> where  op( X ) is one of
+*>
+*>    op( X ) = X   or   op( X ) = X**T,
+*>
+*> alpha and beta are scalars, and A, B and C are matrices, with op( A )
+*> an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n',  op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't',  op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c',  op( A ) = A**T.
+*> \endverbatim
+*>
+*> \param[in] TRANSB
+*> \verbatim
+*>          TRANSB is CHARACTER*1
+*>           On entry, TRANSB specifies the form of op( B ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSB = 'N' or 'n',  op( B ) = B.
+*>
+*>              TRANSB = 'T' or 't',  op( B ) = B**T.
+*>
+*>              TRANSB = 'C' or 'c',  op( B ) = B**T.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies  the number  of rows  of the  matrix
+*>           op( A )  and of the  matrix  C.  M  must  be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N  specifies the number  of columns of the matrix
+*>           op( B ) and the number of columns of the matrix C. N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry,  K  specifies  the number of columns of the matrix
+*>           op( A ) and the number of rows of the matrix op( B ). K must
+*>           be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANSA = 'N' or 'n',  and is  m  otherwise.
+*>           Before entry with  TRANSA = 'N' or 'n',  the leading  m by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by m  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. When  TRANSA = 'N' or 'n' then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is REAL array of DIMENSION ( LDB, kb ), where kb is
+*>           n  when  TRANSB = 'N' or 'n',  and is  k  otherwise.
+*>           Before entry with  TRANSB = 'N' or 'n',  the leading  k by n
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  n by k  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in the calling (sub) program. When  TRANSB = 'N' or 'n' then
+*>           LDB must be at least  max( 1, k ), otherwise  LDB must be at
+*>           least  max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is REAL array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n  matrix
+*>           ( alpha*op( A )*op( B ) + beta*C ).
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,M,N
+      CHARACTER TRANSA,TRANSB
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,J,L,NCOLA,NROWA,NROWB
+      LOGICAL NOTA,NOTB
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not
+*     transposed and set  NROWA, NCOLA and  NROWB  as the number of rows
+*     and  columns of  A  and the  number of  rows  of  B  respectively.
+*
+      NOTA = LSAME(TRANSA,'N')
+      NOTB = LSAME(TRANSB,'N')
+      IF (NOTA) THEN
+          NROWA = M
+          NCOLA = K
+      ELSE
+          NROWA = K
+          NCOLA = M
+      END IF
+      IF (NOTB) THEN
+          NROWB = K
+      ELSE
+          NROWB = N
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.NOTA) .AND. (.NOT.LSAME(TRANSA,'C')) .AND.
+     +    (.NOT.LSAME(TRANSA,'T'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.NOTB) .AND. (.NOT.LSAME(TRANSB,'C')) .AND.
+     +         (.NOT.LSAME(TRANSB,'T'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 8
+      ELSE IF (LDB.LT.MAX(1,NROWB)) THEN
+          INFO = 10
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SGEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And if  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (NOTB) THEN
+          IF (NOTA) THEN
+*
+*           Form  C := alpha*A*B + beta*C.
+*
+              DO 90 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 50 I = 1,M
+                          C(I,J) = ZERO
+   50                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 60 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+   60                 CONTINUE
+                  END IF
+                  DO 80 L = 1,K
+                      TEMP = ALPHA*B(L,J)
+                      DO 70 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+   70                 CONTINUE
+   80             CONTINUE
+   90         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**T*B + beta*C
+*
+              DO 120 J = 1,N
+                  DO 110 I = 1,M
+                      TEMP = ZERO
+                      DO 100 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(L,J)
+  100                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  110             CONTINUE
+  120         CONTINUE
+          END IF
+      ELSE
+          IF (NOTA) THEN
+*
+*           Form  C := alpha*A*B**T + beta*C
+*
+              DO 170 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 130 I = 1,M
+                          C(I,J) = ZERO
+  130                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 140 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+  140                 CONTINUE
+                  END IF
+                  DO 160 L = 1,K
+                      TEMP = ALPHA*B(J,L)
+                      DO 150 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+  150                 CONTINUE
+  160             CONTINUE
+  170         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**T*B**T + beta*C
+*
+              DO 200 J = 1,N
+                  DO 190 I = 1,M
+                      TEMP = ZERO
+                      DO 180 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(J,L)
+  180                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  190             CONTINUE
+  200         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SGEMM .
+*
+      END
diff --git a/superlu/BLAS/sgemv.f b/superlu/BLAS/sgemv.f
new file mode 100644
index 0000000..0dfb1fc
--- /dev/null
+++ b/superlu/BLAS/sgemv.f
@@ -0,0 +1,330 @@
+*> \brief \b SGEMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER INCX,INCY,LDA,M,N
+*       CHARACTER TRANS
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SGEMV  performs one of the matrix-vector operations
+*>
+*>    y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are vectors and A is an
+*> m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*>
+*>              TRANS = 'T' or 't'   y := alpha*A**T*x + beta*y.
+*>
+*>              TRANS = 'C' or 'c'   y := alpha*A**T*x + beta*y.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is REAL array of DIMENSION at least
+*>           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*>           Before entry with BETA non-zero, the incremented array Y
+*>           must contain the vector y. On exit, Y is overwritten by the
+*>           updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER INCX,INCY,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY,LENX,LENY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SGEMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  DO 50 I = 1,M
+                      Y(I) = Y(I) + TEMP*A(I,J)
+   50             CONTINUE
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  IY = KY
+                  DO 70 I = 1,M
+                      Y(IY) = Y(IY) + TEMP*A(I,J)
+                      IY = IY + INCY
+   70             CONTINUE
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A**T*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 100 J = 1,N
+                  TEMP = ZERO
+                  DO 90 I = 1,M
+                      TEMP = TEMP + A(I,J)*X(I)
+   90             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  100         CONTINUE
+          ELSE
+              DO 120 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  DO 110 I = 1,M
+                      TEMP = TEMP + A(I,J)*X(IX)
+                      IX = IX + INCX
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SGEMV .
+*
+      END
diff --git a/superlu/BLAS/sger.f b/superlu/BLAS/sger.f
new file mode 100644
index 0000000..c2a9958
--- /dev/null
+++ b/superlu/BLAS/sger.f
@@ -0,0 +1,227 @@
+*> \brief \b SGER
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SGER(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA
+*       INTEGER INCX,INCY,LDA,M,N
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SGER   performs the rank 1 operation
+*>
+*>    A := alpha*x*y**T + A,
+*>
+*> where alpha is a scalar, x is an m element vector, y is an n element
+*> vector and A is an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the m
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients. On exit, A is
+*>           overwritten by the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SGER(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,INCY,LDA,M,N
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JY,KX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (M.LT.0) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SGER  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (INCY.GT.0) THEN
+          JY = 1
+      ELSE
+          JY = 1 - (N-1)*INCY
+      END IF
+      IF (INCX.EQ.1) THEN
+          DO 20 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  DO 10 I = 1,M
+                      A(I,J) = A(I,J) + X(I)*TEMP
+   10             CONTINUE
+              END IF
+              JY = JY + INCY
+   20     CONTINUE
+      ELSE
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (M-1)*INCX
+          END IF
+          DO 40 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  IX = KX
+                  DO 30 I = 1,M
+                      A(I,J) = A(I,J) + X(IX)*TEMP
+                      IX = IX + INCX
+   30             CONTINUE
+              END IF
+              JY = JY + INCY
+   40     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SGER  .
+*
+      END
diff --git a/superlu/BLAS/snrm2.f b/superlu/BLAS/snrm2.f
new file mode 100644
index 0000000..7de03d2
--- /dev/null
+++ b/superlu/BLAS/snrm2.f
@@ -0,0 +1,112 @@
+*> \brief \b SNRM2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       REAL FUNCTION SNRM2(N,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       REAL X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SNRM2 returns the euclidean norm of a vector via the function
+*> name, so that
+*>
+*>    SNRM2 := sqrt( x'*x ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  -- This version written on 25-October-1982.
+*>     Modified on 14-October-1993 to inline the call to SLASSQ.
+*>     Sven Hammarling, Nag Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      REAL FUNCTION SNRM2(N,X,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      REAL X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL ABSXI,NORM,SCALE,SSQ
+      INTEGER IX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,SQRT
+*     ..
+      IF (N.LT.1 .OR. INCX.LT.1) THEN
+          NORM = ZERO
+      ELSE IF (N.EQ.1) THEN
+          NORM = ABS(X(1))
+      ELSE
+          SCALE = ZERO
+          SSQ = ONE
+*        The following loop is equivalent to this call to the LAPACK
+*        auxiliary routine:
+*        CALL SLASSQ( N, X, INCX, SCALE, SSQ )
+*
+          DO 10 IX = 1,1 + (N-1)*INCX,INCX
+              IF (X(IX).NE.ZERO) THEN
+                  ABSXI = ABS(X(IX))
+                  IF (SCALE.LT.ABSXI) THEN
+                      SSQ = ONE + SSQ* (SCALE/ABSXI)**2
+                      SCALE = ABSXI
+                  ELSE
+                      SSQ = SSQ + (ABSXI/SCALE)**2
+                  END IF
+              END IF
+   10     CONTINUE
+          NORM = SCALE*SQRT(SSQ)
+      END IF
+*
+      SNRM2 = NORM
+      RETURN
+*
+*     End of SNRM2.
+*
+      END
diff --git a/superlu/BLAS/srot.f b/superlu/BLAS/srot.f
new file mode 100644
index 0000000..fa8e295
--- /dev/null
+++ b/superlu/BLAS/srot.f
@@ -0,0 +1,101 @@
+*> \brief \b SROT
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SROT(N,SX,INCX,SY,INCY,C,S)
+*
+*       .. Scalar Arguments ..
+*       REAL C,S
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*),SY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    applies a plane rotation.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SROT(N,SX,INCX,SY,INCY,C,S)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL C,S
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,IX,IY
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*       code for both increments equal to 1
+*
+         DO I = 1,N
+            STEMP = C*SX(I) + S*SY(I)
+            SY(I) = C*SY(I) - S*SX(I)
+            SX(I) = STEMP
+         END DO
+      ELSE
+*
+*       code for unequal increments or equal increments not equal
+*         to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            STEMP = C*SX(IX) + S*SY(IY)
+            SY(IY) = C*SY(IY) - S*SX(IX)
+            SX(IX) = STEMP
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/srotg.f b/superlu/BLAS/srotg.f
new file mode 100644
index 0000000..b4484fb
--- /dev/null
+++ b/superlu/BLAS/srotg.f
@@ -0,0 +1,86 @@
+*> \brief \b SROTG
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SROTG(SA,SB,C,S)
+*
+*       .. Scalar Arguments ..
+*       REAL C,S,SA,SB
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    SROTG construct givens plane rotation.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SROTG(SA,SB,C,S)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL C,S,SA,SB
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL R,ROE,SCALE,Z
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS,SIGN,SQRT
+*     ..
+      ROE = SB
+      IF (ABS(SA).GT.ABS(SB)) ROE = SA
+      SCALE = ABS(SA) + ABS(SB)
+      IF (SCALE.EQ.0.0) THEN
+         C = 1.0
+         S = 0.0
+         R = 0.0
+         Z = 0.0
+      ELSE
+         R = SCALE*SQRT((SA/SCALE)**2+ (SB/SCALE)**2)
+         R = SIGN(1.0,ROE)*R
+         C = SA/R
+         S = SB/R
+         Z = 1.0
+         IF (ABS(SA).GT.ABS(SB)) Z = S
+         IF (ABS(SB).GE.ABS(SA) .AND. C.NE.0.0) Z = 1.0/C
+      END IF
+      SA = R
+      SB = Z
+      RETURN
+      END
diff --git a/superlu/BLAS/srotm.f b/superlu/BLAS/srotm.f
new file mode 100644
index 0000000..c71f7f0
--- /dev/null
+++ b/superlu/BLAS/srotm.f
@@ -0,0 +1,203 @@
+*> \brief \b SROTM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SROTM(N,SX,INCX,SY,INCY,SPARAM)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SPARAM(5),SX(*),SY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    APPLY THE MODIFIED GIVENS TRANSFORMATION, H, TO THE 2 BY N MATRIX
+*>
+*>    (SX**T) , WHERE **T INDICATES TRANSPOSE. THE ELEMENTS OF SX ARE IN
+*>    (SX**T)
+*>
+*>    SX(LX+I*INCX), I = 0 TO N-1, WHERE LX = 1 IF INCX .GE. 0, ELSE
+*>    LX = (-INCX)*N, AND SIMILARLY FOR SY USING USING LY AND INCY.
+*>    WITH SPARAM(1)=SFLAG, H HAS ONE OF THE FOLLOWING FORMS..
+*>
+*>    SFLAG=-1.E0     SFLAG=0.E0        SFLAG=1.E0     SFLAG=-2.E0
+*>
+*>      (SH11  SH12)    (1.E0  SH12)    (SH11  1.E0)    (1.E0  0.E0)
+*>    H=(          )    (          )    (          )    (          )
+*>      (SH21  SH22),   (SH21  1.E0),   (-1.E0 SH22),   (0.E0  1.E0).
+*>    SEE  SROTMG FOR A DESCRIPTION OF DATA STORAGE IN SPARAM.
+*>
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>         number of elements in input vector(s)
+*> \endverbatim
+*>
+*> \param[in,out] SX
+*> \verbatim
+*>          SX is REAL array, dimension N
+*>         double precision vector with N elements
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>         storage spacing between elements of SX
+*> \endverbatim
+*>
+*> \param[in,out] SY
+*> \verbatim
+*>          SY is REAL array, dimension N
+*>         double precision vector with N elements
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>         storage spacing between elements of SY
+*> \endverbatim
+*>
+*> \param[in,out] SPARAM
+*> \verbatim
+*>          SPARAM is REAL array, dimension 5
+*>     SPARAM(1)=SFLAG
+*>     SPARAM(2)=SH11
+*>     SPARAM(3)=SH21
+*>     SPARAM(4)=SH12
+*>     SPARAM(5)=SH22
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*  =====================================================================
+      SUBROUTINE SROTM(N,SX,INCX,SY,INCY,SPARAM)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SPARAM(5),SX(*),SY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL SFLAG,SH11,SH12,SH21,SH22,TWO,W,Z,ZERO
+      INTEGER I,KX,KY,NSTEPS
+*     ..
+*     .. Data statements ..
+      DATA ZERO,TWO/0.E0,2.E0/
+*     ..
+*
+      SFLAG = SPARAM(1)
+      IF (N.LE.0 .OR. (SFLAG+TWO.EQ.ZERO)) RETURN
+      IF (INCX.EQ.INCY.AND.INCX.GT.0) THEN
+*
+         NSTEPS = N*INCX
+         IF (SFLAG.LT.ZERO) THEN
+            SH11 = SPARAM(2)
+            SH12 = SPARAM(4)
+            SH21 = SPARAM(3)
+            SH22 = SPARAM(5)
+            DO I = 1,NSTEPS,INCX
+               W = SX(I)
+               Z = SY(I)
+               SX(I) = W*SH11 + Z*SH12
+               SY(I) = W*SH21 + Z*SH22
+            END DO
+         ELSE IF (SFLAG.EQ.ZERO) THEN
+            SH12 = SPARAM(4)
+            SH21 = SPARAM(3)
+            DO I = 1,NSTEPS,INCX
+               W = SX(I)
+               Z = SY(I)
+               SX(I) = W + Z*SH12
+               SY(I) = W*SH21 + Z
+            END DO
+         ELSE
+            SH11 = SPARAM(2)
+            SH22 = SPARAM(5)
+            DO I = 1,NSTEPS,INCX
+               W = SX(I)
+               Z = SY(I)
+               SX(I) = W*SH11 + Z
+               SY(I) = -W + SH22*Z
+            END DO
+         END IF
+      ELSE
+         KX = 1
+         KY = 1
+         IF (INCX.LT.0) KX = 1 + (1-N)*INCX
+         IF (INCY.LT.0) KY = 1 + (1-N)*INCY
+*
+         IF (SFLAG.LT.ZERO) THEN
+            SH11 = SPARAM(2)
+            SH12 = SPARAM(4)
+            SH21 = SPARAM(3)
+            SH22 = SPARAM(5)
+            DO I = 1,N
+               W = SX(KX)
+               Z = SY(KY)
+               SX(KX) = W*SH11 + Z*SH12
+               SY(KY) = W*SH21 + Z*SH22
+               KX = KX + INCX
+               KY = KY + INCY
+            END DO
+         ELSE IF (SFLAG.EQ.ZERO) THEN
+            SH12 = SPARAM(4)
+            SH21 = SPARAM(3)
+            DO I = 1,N
+               W = SX(KX)
+               Z = SY(KY)
+               SX(KX) = W + Z*SH12
+               SY(KY) = W*SH21 + Z
+               KX = KX + INCX
+               KY = KY + INCY
+            END DO
+         ELSE
+             SH11 = SPARAM(2)
+             SH22 = SPARAM(5)
+             DO I = 1,N
+                W = SX(KX)
+                Z = SY(KY)
+                SX(KX) = W*SH11 + Z
+                SY(KY) = -W + SH22*Z
+                KX = KX + INCX
+                KY = KY + INCY
+            END DO
+         END IF
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/srotmg.f b/superlu/BLAS/srotmg.f
new file mode 100644
index 0000000..a5077c0
--- /dev/null
+++ b/superlu/BLAS/srotmg.f
@@ -0,0 +1,251 @@
+*> \brief \b SROTMG
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SROTMG(SD1,SD2,SX1,SY1,SPARAM)
+*
+*       .. Scalar Arguments ..
+*       REAL SD1,SD2,SX1,SY1
+*       ..
+*       .. Array Arguments ..
+*       REAL SPARAM(5)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    CONSTRUCT THE MODIFIED GIVENS TRANSFORMATION MATRIX H WHICH ZEROS
+*>    THE SECOND COMPONENT OF THE 2-VECTOR  (SQRT(SD1)*SX1,SQRT(SD2)*>    SY2)**T.
+*>    WITH SPARAM(1)=SFLAG, H HAS ONE OF THE FOLLOWING FORMS..
+*>
+*>    SFLAG=-1.E0     SFLAG=0.E0        SFLAG=1.E0     SFLAG=-2.E0
+*>
+*>      (SH11  SH12)    (1.E0  SH12)    (SH11  1.E0)    (1.E0  0.E0)
+*>    H=(          )    (          )    (          )    (          )
+*>      (SH21  SH22),   (SH21  1.E0),   (-1.E0 SH22),   (0.E0  1.E0).
+*>    LOCATIONS 2-4 OF SPARAM CONTAIN SH11,SH21,SH12, AND SH22
+*>    RESPECTIVELY. (VALUES OF 1.E0, -1.E0, OR 0.E0 IMPLIED BY THE
+*>    VALUE OF SPARAM(1) ARE NOT STORED IN SPARAM.)
+*>
+*>    THE VALUES OF GAMSQ AND RGAMSQ SET IN THE DATA STATEMENT MAY BE
+*>    INEXACT.  THIS IS OK AS THEY ARE ONLY USED FOR TESTING THE SIZE
+*>    OF SD1 AND SD2.  ALL ACTUAL SCALING OF DATA IS DONE USING GAM.
+*>
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in,out] SD1
+*> \verbatim
+*>          SD1 is REAL
+*> \endverbatim
+*>
+*> \param[in,out] SD2
+*> \verbatim
+*>          SD2 is REAL
+*> \endverbatim
+*>
+*> \param[in,out] SX1
+*> \verbatim
+*>          SX1 is REAL
+*> \endverbatim
+*>
+*> \param[in] SY1
+*> \verbatim
+*>          SY1 is REAL
+*> \endverbatim
+*>
+*> \param[in,out] SPARAM
+*> \verbatim
+*>          SPARAM is REAL array, dimension 5
+*>     SPARAM(1)=SFLAG
+*>     SPARAM(2)=SH11
+*>     SPARAM(3)=SH21
+*>     SPARAM(4)=SH12
+*>     SPARAM(5)=SH22
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*  =====================================================================
+      SUBROUTINE SROTMG(SD1,SD2,SX1,SY1,SPARAM)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL SD1,SD2,SX1,SY1
+*     ..
+*     .. Array Arguments ..
+      REAL SPARAM(5)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL GAM,GAMSQ,ONE,RGAMSQ,SFLAG,SH11,SH12,SH21,SH22,SP1,SP2,SQ1,
+     $     SQ2,STEMP,SU,TWO,ZERO
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC ABS
+*     ..
+*     .. Data statements ..
+*
+      DATA ZERO,ONE,TWO/0.E0,1.E0,2.E0/
+      DATA GAM,GAMSQ,RGAMSQ/4096.E0,1.67772E7,5.96046E-8/
+*     ..
+
+      IF (SD1.LT.ZERO) THEN
+*        GO ZERO-H-D-AND-SX1..
+         SFLAG = -ONE
+         SH11 = ZERO
+         SH12 = ZERO
+         SH21 = ZERO
+         SH22 = ZERO
+*
+         SD1 = ZERO
+         SD2 = ZERO
+         SX1 = ZERO
+      ELSE
+*        CASE-SD1-NONNEGATIVE
+         SP2 = SD2*SY1
+         IF (SP2.EQ.ZERO) THEN
+            SFLAG = -TWO
+            SPARAM(1) = SFLAG
+            RETURN
+         END IF
+*        REGULAR-CASE..
+         SP1 = SD1*SX1
+         SQ2 = SP2*SY1
+         SQ1 = SP1*SX1
+*
+         IF (ABS(SQ1).GT.ABS(SQ2)) THEN
+            SH21 = -SY1/SX1
+            SH12 = SP2/SP1
+*
+            SU = ONE - SH12*SH21
+*
+           IF (SU.GT.ZERO) THEN
+             SFLAG = ZERO
+             SD1 = SD1/SU
+             SD2 = SD2/SU
+             SX1 = SX1*SU
+           END IF
+         ELSE
+
+            IF (SQ2.LT.ZERO) THEN
+*              GO ZERO-H-D-AND-SX1..
+               SFLAG = -ONE
+               SH11 = ZERO
+               SH12 = ZERO
+               SH21 = ZERO
+               SH22 = ZERO
+*
+               SD1 = ZERO
+               SD2 = ZERO
+               SX1 = ZERO
+            ELSE
+               SFLAG = ONE
+               SH11 = SP1/SP2
+               SH22 = SX1/SY1
+               SU = ONE + SH11*SH22
+               STEMP = SD2/SU
+               SD2 = SD1/SU
+               SD1 = STEMP
+               SX1 = SY1*SU
+            END IF
+         END IF
+
+*     PROCESURE..SCALE-CHECK
+         IF (SD1.NE.ZERO) THEN
+            DO WHILE ((SD1.LE.RGAMSQ) .OR. (SD1.GE.GAMSQ))
+               IF (SFLAG.EQ.ZERO) THEN
+                  SH11 = ONE
+                  SH22 = ONE
+                  SFLAG = -ONE
+               ELSE
+                  SH21 = -ONE
+                  SH12 = ONE
+                  SFLAG = -ONE
+               END IF
+               IF (SD1.LE.RGAMSQ) THEN
+                  SD1 = SD1*GAM**2
+                  SX1 = SX1/GAM
+                  SH11 = SH11/GAM
+                  SH12 = SH12/GAM
+               ELSE
+                  SD1 = SD1/GAM**2
+                  SX1 = SX1*GAM
+                  SH11 = SH11*GAM
+                  SH12 = SH12*GAM
+               END IF
+            ENDDO
+         END IF
+
+         IF (SD2.NE.ZERO) THEN
+            DO WHILE ( (ABS(SD2).LE.RGAMSQ) .OR. (ABS(SD2).GE.GAMSQ) )
+               IF (SFLAG.EQ.ZERO) THEN
+                  SH11 = ONE
+                  SH22 = ONE
+                  SFLAG = -ONE
+               ELSE
+                  SH21 = -ONE
+                  SH12 = ONE
+                  SFLAG = -ONE
+               END IF
+               IF (ABS(SD2).LE.RGAMSQ) THEN
+                  SD2 = SD2*GAM**2
+                  SH21 = SH21/GAM
+                  SH22 = SH22/GAM
+               ELSE
+                  SD2 = SD2/GAM**2
+                  SH21 = SH21*GAM
+                  SH22 = SH22*GAM
+               END IF
+            END DO
+         END IF
+
+      END IF
+
+      IF (SFLAG.LT.ZERO) THEN
+         SPARAM(2) = SH11
+         SPARAM(3) = SH21
+         SPARAM(4) = SH12
+         SPARAM(5) = SH22
+      ELSE IF (SFLAG.EQ.ZERO) THEN
+         SPARAM(3) = SH21
+         SPARAM(4) = SH12
+      ELSE
+         SPARAM(2) = SH11
+         SPARAM(5) = SH22
+      END IF
+
+      SPARAM(1) = SFLAG
+      RETURN
+      END
+
+
+
+
diff --git a/superlu/BLAS/ssbmv.f b/superlu/BLAS/ssbmv.f
new file mode 100644
index 0000000..b711d8b
--- /dev/null
+++ b/superlu/BLAS/ssbmv.f
@@ -0,0 +1,375 @@
+*> \brief \b SSBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER INCX,INCY,K,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSBMV  performs the matrix-vector  operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n symmetric band matrix, with k super-diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the band matrix A is being supplied as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  being supplied.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  being supplied.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry, K specifies the number of super-diagonals of the
+*>           matrix A. K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the symmetric matrix, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer the upper
+*>           triangular part of a symmetric band matrix from conventional
+*>           full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the symmetric matrix, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer the lower
+*>           triangular part of a symmetric band matrix from conventional
+*>           full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is REAL array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the
+*>           vector y. On exit, Y is overwritten by the updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER INCX,INCY,K,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KPLUS1,KX,KY,L
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (K.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of the array A
+*     are accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when upper triangle of A is stored.
+*
+          KPLUS1 = K + 1
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  L = KPLUS1 - J
+                  DO 50 I = MAX(1,J-K),J - 1
+                      Y(I) = Y(I) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + A(L+I,J)*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*A(KPLUS1,J) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  L = KPLUS1 - J
+                  DO 70 I = MAX(1,J-K),J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + A(L+I,J)*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*A(KPLUS1,J) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  IF (J.GT.K) THEN
+                      KX = KX + INCX
+                      KY = KY + INCY
+                  END IF
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when lower triangle of A is stored.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*A(1,J)
+                  L = 1 - J
+                  DO 90 I = J + 1,MIN(N,J+K)
+                      Y(I) = Y(I) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + A(L+I,J)*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*A(1,J)
+                  L = 1 - J
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,MIN(N,J+K)
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + A(L+I,J)*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSBMV .
+*
+      END
diff --git a/superlu/BLAS/sscal.f b/superlu/BLAS/sscal.f
new file mode 100644
index 0000000..2ffc1a2
--- /dev/null
+++ b/superlu/BLAS/sscal.f
@@ -0,0 +1,110 @@
+*> \brief \b SSCAL
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSCAL(N,SA,SX,INCX)
+*
+*       .. Scalar Arguments ..
+*       REAL SA
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    scales a vector by a constant.
+*>    uses unrolled loops for increment equal to 1.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSCAL(N,SA,SX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL SA
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,M,MP1,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+*
+*        clean-up loop
+*
+         M = MOD(N,5)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               SX(I) = SA*SX(I)
+            END DO
+            IF (N.LT.5) RETURN
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,5
+            SX(I) = SA*SX(I)
+            SX(I+1) = SA*SX(I+1)
+            SX(I+2) = SA*SX(I+2)
+            SX(I+3) = SA*SX(I+3)
+            SX(I+4) = SA*SX(I+4)
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            SX(I) = SA*SX(I)
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/sspmv.f b/superlu/BLAS/sspmv.f
new file mode 100644
index 0000000..bc8af3d
--- /dev/null
+++ b/superlu/BLAS/sspmv.f
@@ -0,0 +1,331 @@
+*> \brief \b SSPMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER INCX,INCY,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL AP(*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSPMV  performs the matrix-vector operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n symmetric matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is REAL array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y. On exit, Y is overwritten by the updated
+*>           vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER INCX,INCY,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL AP(*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 6
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSPMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when AP contains the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  K = KK
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + AP(K)*X(I)
+                      K = K + 1
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*AP(KK+J-1) + ALPHA*TEMP2
+                  KK = KK + J
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 K = KK,KK + J - 2
+                      Y(IY) = Y(IY) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + AP(K)*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*AP(KK+J-1) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + J
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when AP contains the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*AP(KK)
+                  K = KK + 1
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + AP(K)*X(I)
+                      K = K + 1
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+                  KK = KK + (N-J+1)
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*AP(KK)
+                  IX = JX
+                  IY = JY
+                  DO 110 K = KK + 1,KK + N - J
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + AP(K)*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + (N-J+1)
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSPMV .
+*
+      END
diff --git a/superlu/BLAS/sspr.f b/superlu/BLAS/sspr.f
new file mode 100644
index 0000000..52cb731
--- /dev/null
+++ b/superlu/BLAS/sspr.f
@@ -0,0 +1,261 @@
+*> \brief \b SSPR
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSPR(UPLO,N,ALPHA,X,INCX,AP)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA
+*       INTEGER INCX,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSPR    performs the symmetric rank 1 operation
+*>
+*>    A := alpha*x*x**T + A,
+*>
+*> where alpha is a real scalar, x is an n element vector and A is an
+*> n by n symmetric matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] AP
+*> \verbatim
+*>          AP is REAL array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the upper triangular part of the
+*>           updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the lower triangular part of the
+*>           updated matrix.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSPR(UPLO,N,ALPHA,X,INCX,AP)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSPR  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when upper triangle is stored in AP.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      K = KK
+                      DO 10 I = 1,J
+                          AP(K) = AP(K) + X(I)*TEMP
+                          K = K + 1
+   10                 CONTINUE
+                  END IF
+                  KK = KK + J
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = KX
+                      DO 30 K = KK,KK + J - 1
+                          AP(K) = AP(K) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  KK = KK + J
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when lower triangle is stored in AP.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      K = KK
+                      DO 50 I = J,N
+                          AP(K) = AP(K) + X(I)*TEMP
+                          K = K + 1
+   50                 CONTINUE
+                  END IF
+                  KK = KK + N - J + 1
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = JX
+                      DO 70 K = KK,KK + N - J
+                          AP(K) = AP(K) + X(IX)*TEMP
+                          IX = IX + INCX
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  KK = KK + N - J + 1
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSPR  .
+*
+      END
diff --git a/superlu/BLAS/sspr2.f b/superlu/BLAS/sspr2.f
new file mode 100644
index 0000000..b4c8118
--- /dev/null
+++ b/superlu/BLAS/sspr2.f
@@ -0,0 +1,296 @@
+*> \brief \b SSPR2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSPR2(UPLO,N,ALPHA,X,INCX,Y,INCY,AP)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA
+*       INTEGER INCX,INCY,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL AP(*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSPR2  performs the symmetric rank 2 operation
+*>
+*>    A := alpha*x*y**T + alpha*y*x**T + A,
+*>
+*> where alpha is a scalar, x and y are n element vectors and A is an
+*> n by n symmetric matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] AP
+*> \verbatim
+*>          AP is REAL array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the upper triangular part of the
+*>           updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the symmetric matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the lower triangular part of the
+*>           updated matrix.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSPR2(UPLO,N,ALPHA,X,INCX,Y,INCY,AP)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,INCY,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL AP(*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSPR2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when upper triangle is stored in AP.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      K = KK
+                      DO 10 I = 1,J
+                          AP(K) = AP(K) + X(I)*TEMP1 + Y(I)*TEMP2
+                          K = K + 1
+   10                 CONTINUE
+                  END IF
+                  KK = KK + J
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = KX
+                      IY = KY
+                      DO 30 K = KK,KK + J - 1
+                          AP(K) = AP(K) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + J
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when lower triangle is stored in AP.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      K = KK
+                      DO 50 I = J,N
+                          AP(K) = AP(K) + X(I)*TEMP1 + Y(I)*TEMP2
+                          K = K + 1
+   50                 CONTINUE
+                  END IF
+                  KK = KK + N - J + 1
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = JX
+                      IY = JY
+                      DO 70 K = KK,KK + N - J
+                          AP(K) = AP(K) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + N - J + 1
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSPR2 .
+*
+      END
diff --git a/superlu/BLAS/sswap.f b/superlu/BLAS/sswap.f
new file mode 100644
index 0000000..f821a1e
--- /dev/null
+++ b/superlu/BLAS/sswap.f
@@ -0,0 +1,122 @@
+*> \brief \b SSWAP
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSWAP(N,SX,INCX,SY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       REAL SX(*),SY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    interchanges two vectors.
+*>    uses unrolled loops for increments equal to 1.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSWAP(N,SX,INCX,SY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      REAL SX(*),SY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      REAL STEMP
+      INTEGER I,IX,IY,M,MP1
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MOD
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*       code for both increments equal to 1
+*
+*
+*       clean-up loop
+*
+         M = MOD(N,3)
+         IF (M.NE.0) THEN
+            DO I = 1,M
+               STEMP = SX(I)
+               SX(I) = SY(I)
+               SY(I) = STEMP
+            END DO
+            IF (N.LT.3) RETURN
+         END IF
+         MP1 = M + 1
+         DO I = MP1,N,3
+            STEMP = SX(I)
+            SX(I) = SY(I)
+            SY(I) = STEMP
+            STEMP = SX(I+1)
+            SX(I+1) = SY(I+1)
+            SY(I+1) = STEMP
+            STEMP = SX(I+2)
+            SX(I+2) = SY(I+2)
+            SY(I+2) = STEMP
+         END DO
+      ELSE
+*
+*       code for unequal increments or equal increments not equal
+*         to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            STEMP = SX(IX)
+            SX(IX) = SY(IY)
+            SY(IY) = STEMP
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/ssymm.f b/superlu/BLAS/ssymm.f
new file mode 100644
index 0000000..d3a193f
--- /dev/null
+++ b/superlu/BLAS/ssymm.f
@@ -0,0 +1,367 @@
+*> \brief \b SSYMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER LDA,LDB,LDC,M,N
+*       CHARACTER SIDE,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSYMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*A*B + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*B*A + beta*C,
+*>
+*> where alpha and beta are scalars,  A is a symmetric matrix and  B and
+*> C are  m by n matrices.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE  specifies whether  the  symmetric matrix  A
+*>           appears on the  left or right  in the  operation as follows:
+*>
+*>              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*>
+*>              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of  the  symmetric  matrix   A  is  to  be
+*>           referenced as follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*>                                  symmetric matrix is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*>                                  symmetric matrix is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies the number of rows of the matrix  C.
+*>           M  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix C.
+*>           N  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, ka ), where ka is
+*>           m  when  SIDE = 'L' or 'l'  and is  n otherwise.
+*>           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*>           the array  A  must contain the  symmetric matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  symmetric matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  m by m  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  symmetric
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*>           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*>           the array  A  must contain the  symmetric matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  symmetric matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  n by n  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  symmetric
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least  max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is REAL array of DIMENSION ( LDB, n ).
+*>           Before entry, the leading  m by n part of the array  B  must
+*>           contain the matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is REAL array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n updated
+*>           matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*A(J,J)
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*A(J,K)
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(J,K)
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of SSYMM .
+*
+      END
diff --git a/superlu/BLAS/ssymv.f b/superlu/BLAS/ssymv.f
new file mode 100644
index 0000000..a1fa54f
--- /dev/null
+++ b/superlu/BLAS/ssymv.f
@@ -0,0 +1,333 @@
+*> \brief \b SSYMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSYMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER INCX,INCY,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSYMV  performs the matrix-vector  operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n symmetric matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the symmetric matrix and the strictly
+*>           lower triangular part of A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the symmetric matrix and the strictly
+*>           upper triangular part of A is not referenced.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y. On exit, Y is overwritten by the updated
+*>           vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSYMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 5
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when A is stored in upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*A(J,J) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 I = 1,J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*A(J,J) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when A is stored in lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*A(J,J)
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*A(J,J)
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,N
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + A(I,J)*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYMV .
+*
+      END
diff --git a/superlu/BLAS/ssyr.f b/superlu/BLAS/ssyr.f
new file mode 100644
index 0000000..9d73f86
--- /dev/null
+++ b/superlu/BLAS/ssyr.f
@@ -0,0 +1,263 @@
+*> \brief \b SSYR
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSYR(UPLO,N,ALPHA,X,INCX,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA
+*       INTEGER INCX,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSYR   performs the symmetric rank 1 operation
+*>
+*>    A := alpha*x*x**T + A,
+*>
+*> where alpha is a real scalar, x is an n element vector and A is an
+*> n by n symmetric matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the symmetric matrix and the strictly
+*>           lower triangular part of A is not referenced. On exit, the
+*>           upper triangular part of the array A is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the symmetric matrix and the strictly
+*>           upper triangular part of A is not referenced. On exit, the
+*>           lower triangular part of the array A is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSYR(UPLO,N,ALPHA,X,INCX,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYR  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in upper triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      DO 10 I = 1,J
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   10                 CONTINUE
+                  END IF
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = KX
+                      DO 30 I = 1,J
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in lower triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*X(J)
+                      DO 50 I = J,N
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   50                 CONTINUE
+                  END IF
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*X(JX)
+                      IX = JX
+                      DO 70 I = J,N
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+                          IX = IX + INCX
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYR  .
+*
+      END
diff --git a/superlu/BLAS/ssyr2.f b/superlu/BLAS/ssyr2.f
new file mode 100644
index 0000000..a2a083a
--- /dev/null
+++ b/superlu/BLAS/ssyr2.f
@@ -0,0 +1,298 @@
+*> \brief \b SSYR2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSYR2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA
+*       INTEGER INCX,INCY,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSYR2  performs the symmetric rank 2 operation
+*>
+*>    A := alpha*x*y**T + alpha*y*x**T + A,
+*>
+*> where alpha is a scalar, x and y are n element vectors and A is an n
+*> by n symmetric matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the symmetric matrix and the strictly
+*>           lower triangular part of A is not referenced. On exit, the
+*>           upper triangular part of the array A is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the symmetric matrix and the strictly
+*>           upper triangular part of A is not referenced. On exit, the
+*>           lower triangular part of the array A is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSYR2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYR2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      DO 10 I = 1,J
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   10                 CONTINUE
+                  END IF
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = KX
+                      IY = KY
+                      DO 30 I = 1,J
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(J)
+                      TEMP2 = ALPHA*X(J)
+                      DO 50 I = J,N
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   50                 CONTINUE
+                  END IF
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*Y(JY)
+                      TEMP2 = ALPHA*X(JX)
+                      IX = JX
+                      IY = JY
+                      DO 70 I = J,N
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   70                 CONTINUE
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYR2 .
+*
+      END
diff --git a/superlu/BLAS/ssyr2k.f b/superlu/BLAS/ssyr2k.f
new file mode 100644
index 0000000..4a705f7
--- /dev/null
+++ b/superlu/BLAS/ssyr2k.f
@@ -0,0 +1,399 @@
+*> \brief \b SSYR2K
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSYR2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER K,LDA,LDB,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSYR2K  performs one of the symmetric rank 2k operations
+*>
+*>    C := alpha*A*B**T + alpha*B*A**T + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**T*B + alpha*B**T*A + beta*C,
+*>
+*> where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
+*> and  A and B  are  n by k  matrices  in the  first  case  and  k by n
+*> matrices in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   C := alpha*A*B**T + alpha*B*A**T +
+*>                                        beta*C.
+*>
+*>              TRANS = 'T' or 't'   C := alpha*A**T*B + alpha*B**T*A +
+*>                                        beta*C.
+*>
+*>              TRANS = 'C' or 'c'   C := alpha*A**T*B + alpha*B**T*A +
+*>                                        beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns  of the  matrices  A and B,  and on  entry  with
+*>           TRANS = 'T' or 't' or 'C' or 'c',  K  specifies  the  number
+*>           of rows of the matrices  A and B.  K must be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is REAL array of DIMENSION ( LDB, kb ), where kb is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  k by n  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is REAL array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSYR2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP1,TEMP2
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYR2K',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*B**T + alpha*B*A**T + C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**T*B + alpha*B**T*A + C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 190 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 220 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYR2K.
+*
+      END
diff --git a/superlu/BLAS/ssyrk.f b/superlu/BLAS/ssyrk.f
new file mode 100644
index 0000000..ecb1e4f
--- /dev/null
+++ b/superlu/BLAS/ssyrk.f
@@ -0,0 +1,364 @@
+*> \brief \b SSYRK
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE SSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA,BETA
+*       INTEGER K,LDA,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> SSYRK  performs one of the symmetric rank k operations
+*>
+*>    C := alpha*A*A**T + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**T*A + beta*C,
+*>
+*> where  alpha and beta  are scalars, C is an  n by n  symmetric matrix
+*> and  A  is an  n by k  matrix in the first case and a  k by n  matrix
+*> in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   C := alpha*A*A**T + beta*C.
+*>
+*>              TRANS = 'T' or 't'   C := alpha*A**T*A + beta*C.
+*>
+*>              TRANS = 'C' or 'c'   C := alpha*A**T*A + beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns   of  the   matrix   A,   and  on   entry   with
+*>           TRANS = 'T' or 't' or 'C' or 'c',  K  specifies  the  number
+*>           of rows of the matrix  A.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is REAL
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is REAL array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE SSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('SSYRK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*A**T + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**T*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP = ZERO
+                      DO 220 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of SSYRK .
+*
+      END
diff --git a/superlu/BLAS/stbmv.f b/superlu/BLAS/stbmv.f
new file mode 100644
index 0000000..4323864
--- /dev/null
+++ b/superlu/BLAS/stbmv.f
@@ -0,0 +1,398 @@
+*> \brief \b STBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE STBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,K,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> STBMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular band matrix, with ( k + 1 ) diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**T*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with UPLO = 'U' or 'u', K specifies the number of
+*>           super-diagonals of the matrix A.
+*>           On entry with UPLO = 'L' or 'l', K specifies the number of
+*>           sub-diagonals of the matrix A.
+*>           K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer an upper
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer a lower
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that when DIAG = 'U' or 'u' the elements of the array A
+*>           corresponding to the diagonal elements of the matrix are not
+*>           referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE STBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX   too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*         Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          L = KPLUS1 - J
+                          DO 10 I = MAX(1,J-K),J - 1
+                              X(I) = X(I) + TEMP*A(L+I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(KPLUS1,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          L = KPLUS1 - J
+                          DO 30 I = MAX(1,J-K),J - 1
+                              X(IX) = X(IX) + TEMP*A(L+I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(KPLUS1,J)
+                      END IF
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          L = 1 - J
+                          DO 50 I = MIN(N,J+K),J + 1,-1
+                              X(I) = X(I) + TEMP*A(L+I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(1,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          L = 1 - J
+                          DO 70 I = MIN(N,J+K),J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(L+I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(1,J)
+                      END IF
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = N,1,-1
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)
+                      DO 90 I = J - 1,MAX(1,J-K),-1
+                          TEMP = TEMP + A(L+I,J)*X(I)
+   90                 CONTINUE
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 120 J = N,1,-1
+                      TEMP = X(JX)
+                      KX = KX - INCX
+                      IX = KX
+                      L = KPLUS1 - J
+                      IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)
+                      DO 110 I = J - 1,MAX(1,J-K),-1
+                          TEMP = TEMP + A(L+I,J)*X(IX)
+                          IX = IX - INCX
+  110                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = 1,N
+                      TEMP = X(J)
+                      L = 1 - J
+                      IF (NOUNIT) TEMP = TEMP*A(1,J)
+                      DO 130 I = J + 1,MIN(N,J+K)
+                          TEMP = TEMP + A(L+I,J)*X(I)
+  130                 CONTINUE
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 160 J = 1,N
+                      TEMP = X(JX)
+                      KX = KX + INCX
+                      IX = KX
+                      L = 1 - J
+                      IF (NOUNIT) TEMP = TEMP*A(1,J)
+                      DO 150 I = J + 1,MIN(N,J+K)
+                          TEMP = TEMP + A(L+I,J)*X(IX)
+                          IX = IX + INCX
+  150                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STBMV .
+*
+      END
diff --git a/superlu/BLAS/stbsv.f b/superlu/BLAS/stbsv.f
new file mode 100644
index 0000000..00aaeba
--- /dev/null
+++ b/superlu/BLAS/stbsv.f
@@ -0,0 +1,401 @@
+*> \brief \b STBSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE STBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,K,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> STBSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular band matrix, with ( k + 1 )
+*> diagonals.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**T*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with UPLO = 'U' or 'u', K specifies the number of
+*>           super-diagonals of the matrix A.
+*>           On entry with UPLO = 'L' or 'l', K specifies the number of
+*>           sub-diagonals of the matrix A.
+*>           K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer an upper
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer a lower
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that when DIAG = 'U' or 'u' the elements of the array A
+*>           corresponding to the diagonal elements of the matrix are not
+*>           referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE STBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STBSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed by sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(KPLUS1,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,MAX(1,J-K),-1
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 40 J = N,1,-1
+                      KX = KX - INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(KPLUS1,J)
+                          TEMP = X(JX)
+                          DO 30 I = J - 1,MAX(1,J-K),-1
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX - INCX
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          L = 1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(1,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,MIN(N,J+K)
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      KX = KX + INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = 1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(1,J)
+                          TEMP = X(JX)
+                          DO 70 I = J + 1,MIN(N,J+K)
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX + INCX
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T)*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = 1,N
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      DO 90 I = MAX(1,J-K),J - 1
+                          TEMP = TEMP - A(L+I,J)*X(I)
+   90                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 120 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      L = KPLUS1 - J
+                      DO 110 I = MAX(1,J-K),J - 1
+                          TEMP = TEMP - A(L+I,J)*X(IX)
+                          IX = IX + INCX
+  110                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = N,1,-1
+                      TEMP = X(J)
+                      L = 1 - J
+                      DO 130 I = MIN(N,J+K),J + 1,-1
+                          TEMP = TEMP - A(L+I,J)*X(I)
+  130                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 160 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      L = 1 - J
+                      DO 150 I = MIN(N,J+K),J + 1,-1
+                          TEMP = TEMP - A(L+I,J)*X(IX)
+                          IX = IX - INCX
+  150                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STBSV .
+*
+      END
diff --git a/superlu/BLAS/stpmv.f b/superlu/BLAS/stpmv.f
new file mode 100644
index 0000000..765e7f9
--- /dev/null
+++ b/superlu/BLAS/stpmv.f
@@ -0,0 +1,352 @@
+*> \brief \b STPMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE STPMV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> STPMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**T*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is REAL array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 )
+*>           respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 )
+*>           respectively, and so on.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE STPMV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STPMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of AP are
+*     accessed sequentially with one pass through AP.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x:= A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          K = KK
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*AP(K)
+                              K = K + 1
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*AP(KK+J-1)
+                      END IF
+                      KK = KK + J
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 K = KK,KK + J - 2
+                              X(IX) = X(IX) + TEMP*AP(K)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*AP(KK+J-1)
+                      END IF
+                      JX = JX + INCX
+                      KK = KK + J
+   40             CONTINUE
+              END IF
+          ELSE
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          K = KK
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*AP(K)
+                              K = K - 1
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*AP(KK-N+J)
+                      END IF
+                      KK = KK - (N-J+1)
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 K = KK,KK - (N- (J+1)),-1
+                              X(IX) = X(IX) + TEMP*AP(K)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*AP(KK-N+J)
+                      END IF
+                      JX = JX - INCX
+                      KK = KK - (N-J+1)
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*AP(KK)
+                      K = KK - 1
+                      DO 90 I = J - 1,1,-1
+                          TEMP = TEMP + AP(K)*X(I)
+                          K = K - 1
+   90                 CONTINUE
+                      X(J) = TEMP
+                      KK = KK - J
+  100             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 120 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*AP(KK)
+                      DO 110 K = KK - 1,KK - J + 1,-1
+                          IX = IX - INCX
+                          TEMP = TEMP + AP(K)*X(IX)
+  110                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      KK = KK - J
+  120             CONTINUE
+              END IF
+          ELSE
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = 1,N
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*AP(KK)
+                      K = KK + 1
+                      DO 130 I = J + 1,N
+                          TEMP = TEMP + AP(K)*X(I)
+                          K = K + 1
+  130                 CONTINUE
+                      X(J) = TEMP
+                      KK = KK + (N-J+1)
+  140             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 160 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*AP(KK)
+                      DO 150 K = KK + 1,KK + N - J
+                          IX = IX + INCX
+                          TEMP = TEMP + AP(K)*X(IX)
+  150                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      KK = KK + (N-J+1)
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STPMV .
+*
+      END
diff --git a/superlu/BLAS/stpsv.f b/superlu/BLAS/stpsv.f
new file mode 100644
index 0000000..5a29776
--- /dev/null
+++ b/superlu/BLAS/stpsv.f
@@ -0,0 +1,354 @@
+*> \brief \b STPSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE STPSV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> STPSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular matrix, supplied in packed form.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**T*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is REAL array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 )
+*>           respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 )
+*>           respectively, and so on.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE STPSV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STPSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of AP are
+*     accessed sequentially with one pass through AP.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/AP(KK)
+                          TEMP = X(J)
+                          K = KK - 1
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*AP(K)
+                              K = K - 1
+   10                     CONTINUE
+                      END IF
+                      KK = KK - J
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/AP(KK)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 K = KK - 1,KK - J + 1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*AP(K)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+                      KK = KK - J
+   40             CONTINUE
+              END IF
+          ELSE
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/AP(KK)
+                          TEMP = X(J)
+                          K = KK + 1
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*AP(K)
+                              K = K + 1
+   50                     CONTINUE
+                      END IF
+                      KK = KK + (N-J+1)
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/AP(KK)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 K = KK + 1,KK + N - J
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*AP(K)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+                      KK = KK + (N-J+1)
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = 1,N
+                      TEMP = X(J)
+                      K = KK
+                      DO 90 I = 1,J - 1
+                          TEMP = TEMP - AP(K)*X(I)
+                          K = K + 1
+   90                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/AP(KK+J-1)
+                      X(J) = TEMP
+                      KK = KK + J
+  100             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 120 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 110 K = KK,KK + J - 2
+                          TEMP = TEMP - AP(K)*X(IX)
+                          IX = IX + INCX
+  110                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/AP(KK+J-1)
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      KK = KK + J
+  120             CONTINUE
+              END IF
+          ELSE
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = N,1,-1
+                      TEMP = X(J)
+                      K = KK
+                      DO 130 I = N,J + 1,-1
+                          TEMP = TEMP - AP(K)*X(I)
+                          K = K - 1
+  130                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/AP(KK-N+J)
+                      X(J) = TEMP
+                      KK = KK - (N-J+1)
+  140             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 160 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 150 K = KK,KK - (N- (J+1)),-1
+                          TEMP = TEMP - AP(K)*X(IX)
+                          IX = IX - INCX
+  150                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/AP(KK-N+J)
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      KK = KK - (N-J+1)
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STPSV .
+*
+      END
diff --git a/superlu/BLAS/strmm.f b/superlu/BLAS/strmm.f
new file mode 100644
index 0000000..dd20872
--- /dev/null
+++ b/superlu/BLAS/strmm.f
@@ -0,0 +1,415 @@
+*> \brief \b STRMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE STRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA
+*       INTEGER LDA,LDB,M,N
+*       CHARACTER DIAG,SIDE,TRANSA,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),B(LDB,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> STRMM  performs one of the matrix-matrix operations
+*>
+*>    B := alpha*op( A )*B,   or   B := alpha*B*op( A ),
+*>
+*> where  alpha  is a scalar,  B  is an m by n matrix,  A  is a unit, or
+*> non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*>
+*>    op( A ) = A   or   op( A ) = A**T.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE specifies whether  op( A ) multiplies B from
+*>           the left or right as follows:
+*>
+*>              SIDE = 'L' or 'l'   B := alpha*op( A )*B.
+*>
+*>              SIDE = 'R' or 'r'   B := alpha*B*op( A ).
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix A is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n'   op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't'   op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c'   op( A ) = A**T.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit triangular
+*>           as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of B. M must be at
+*>           least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of B.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*>           zero then  A is not referenced and  B need not be set before
+*>           entry.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, k ), where k is m
+*>           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*>           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*>           upper triangular part of the array  A must contain the upper
+*>           triangular matrix  and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*>           lower triangular part of the array  A must contain the lower
+*>           triangular matrix  and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*>           A  are not referenced either,  but are assumed to be  unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*>           then LDA must be at least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] B
+*> \verbatim
+*>          B is REAL array of DIMENSION ( LDB, n ).
+*>           Before entry,  the leading  m by n part of the array  B must
+*>           contain the matrix  B,  and  on exit  is overwritten  by the
+*>           transformed matrix.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE STRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STRMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*A*B.
+*
+              IF (UPPER) THEN
+                  DO 50 J = 1,N
+                      DO 40 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              DO 30 I = 1,K - 1
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   30                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP*A(K,K)
+                              B(K,J) = TEMP
+                          END IF
+   40                 CONTINUE
+   50             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              B(K,J) = TEMP
+                              IF (NOUNIT) B(K,J) = B(K,J)*A(K,K)
+                              DO 60 I = K + 1,M
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   60                         CONTINUE
+                          END IF
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*A**T*B.
+*
+              IF (UPPER) THEN
+                  DO 110 J = 1,N
+                      DO 100 I = M,1,-1
+                          TEMP = B(I,J)
+                          IF (NOUNIT) TEMP = TEMP*A(I,I)
+                          DO 90 K = 1,I - 1
+                              TEMP = TEMP + A(K,I)*B(K,J)
+   90                     CONTINUE
+                          B(I,J) = ALPHA*TEMP
+  100                 CONTINUE
+  110             CONTINUE
+              ELSE
+                  DO 140 J = 1,N
+                      DO 130 I = 1,M
+                          TEMP = B(I,J)
+                          IF (NOUNIT) TEMP = TEMP*A(I,I)
+                          DO 120 K = I + 1,M
+                              TEMP = TEMP + A(K,I)*B(K,J)
+  120                     CONTINUE
+                          B(I,J) = ALPHA*TEMP
+  130                 CONTINUE
+  140             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*A.
+*
+              IF (UPPER) THEN
+                  DO 180 J = N,1,-1
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 150 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  150                 CONTINUE
+                      DO 170 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 160 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  160                         CONTINUE
+                          END IF
+  170                 CONTINUE
+  180             CONTINUE
+              ELSE
+                  DO 220 J = 1,N
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 190 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  190                 CONTINUE
+                      DO 210 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 200 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  200                         CONTINUE
+                          END IF
+  210                 CONTINUE
+  220             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*A**T.
+*
+              IF (UPPER) THEN
+                  DO 260 K = 1,N
+                      DO 240 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = ALPHA*A(J,K)
+                              DO 230 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  230                         CONTINUE
+                          END IF
+  240                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(K,K)
+                      IF (TEMP.NE.ONE) THEN
+                          DO 250 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  250                     CONTINUE
+                      END IF
+  260             CONTINUE
+              ELSE
+                  DO 300 K = N,1,-1
+                      DO 280 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = ALPHA*A(J,K)
+                              DO 270 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  270                         CONTINUE
+                          END IF
+  280                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(K,K)
+                      IF (TEMP.NE.ONE) THEN
+                          DO 290 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  290                     CONTINUE
+                      END IF
+  300             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STRMM .
+*
+      END
diff --git a/superlu/BLAS/strmv.f b/superlu/BLAS/strmv.f
new file mode 100644
index 0000000..ba3d7b6
--- /dev/null
+++ b/superlu/BLAS/strmv.f
@@ -0,0 +1,342 @@
+*> \brief \b STRMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE STRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> STRMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**T*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular matrix and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular matrix and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced either, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE STRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STRMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*A(I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 I = 1,J - 1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*A(I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 I = N,J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 90 I = J - 1,1,-1
+                          TEMP = TEMP + A(I,J)*X(I)
+   90                 CONTINUE
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 120 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 110 I = J - 1,1,-1
+                          IX = IX - INCX
+                          TEMP = TEMP + A(I,J)*X(IX)
+  110                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = 1,N
+                      TEMP = X(J)
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 130 I = J + 1,N
+                          TEMP = TEMP + A(I,J)*X(I)
+  130                 CONTINUE
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 160 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 150 I = J + 1,N
+                          IX = IX + INCX
+                          TEMP = TEMP + A(I,J)*X(IX)
+  150                 CONTINUE
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STRMV .
+*
+      END
diff --git a/superlu/BLAS/strsm.f b/superlu/BLAS/strsm.f
new file mode 100644
index 0000000..f2927fe
--- /dev/null
+++ b/superlu/BLAS/strsm.f
@@ -0,0 +1,443 @@
+*> \brief \b STRSM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE STRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*       .. Scalar Arguments ..
+*       REAL ALPHA
+*       INTEGER LDA,LDB,M,N
+*       CHARACTER DIAG,SIDE,TRANSA,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),B(LDB,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> STRSM  solves one of the matrix equations
+*>
+*>    op( A )*X = alpha*B,   or   X*op( A ) = alpha*B,
+*>
+*> where alpha is a scalar, X and B are m by n matrices, A is a unit, or
+*> non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*>
+*>    op( A ) = A   or   op( A ) = A**T.
+*>
+*> The matrix X is overwritten on B.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry, SIDE specifies whether op( A ) appears on the left
+*>           or right of X as follows:
+*>
+*>              SIDE = 'L' or 'l'   op( A )*X = alpha*B.
+*>
+*>              SIDE = 'R' or 'r'   X*op( A ) = alpha*B.
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix A is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n'   op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't'   op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c'   op( A ) = A**T.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit triangular
+*>           as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of B. M must be at
+*>           least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of B.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is REAL
+*>           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*>           zero then  A is not referenced and  B need not be set before
+*>           entry.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, k ),
+*>           where k is m when SIDE = 'L' or 'l'
+*>             and k is n when SIDE = 'R' or 'r'.
+*>           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*>           upper triangular part of the array  A must contain the upper
+*>           triangular matrix  and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*>           lower triangular part of the array  A must contain the lower
+*>           triangular matrix  and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*>           A  are not referenced either,  but are assumed to be  unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*>           then LDA must be at least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] B
+*> \verbatim
+*>          B is REAL array of DIMENSION ( LDB, n ).
+*>           Before entry,  the leading  m by n part of the array  B must
+*>           contain  the  right-hand  side  matrix  B,  and  on exit  is
+*>           overwritten by the solution matrix  X.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE STRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      REAL ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),B(LDB,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      REAL ONE,ZERO
+      PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STRSM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*inv( A )*B.
+*
+              IF (UPPER) THEN
+                  DO 60 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 30 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   30                     CONTINUE
+                      END IF
+                      DO 50 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 40 I = 1,K - 1
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   40                         CONTINUE
+                          END IF
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 100 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 70 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   70                     CONTINUE
+                      END IF
+                      DO 90 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 80 I = K + 1,M
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   80                         CONTINUE
+                          END IF
+   90                 CONTINUE
+  100             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*inv( A**T )*B.
+*
+              IF (UPPER) THEN
+                  DO 130 J = 1,N
+                      DO 120 I = 1,M
+                          TEMP = ALPHA*B(I,J)
+                          DO 110 K = 1,I - 1
+                              TEMP = TEMP - A(K,I)*B(K,J)
+  110                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          B(I,J) = TEMP
+  120                 CONTINUE
+  130             CONTINUE
+              ELSE
+                  DO 160 J = 1,N
+                      DO 150 I = M,1,-1
+                          TEMP = ALPHA*B(I,J)
+                          DO 140 K = I + 1,M
+                              TEMP = TEMP - A(K,I)*B(K,J)
+  140                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          B(I,J) = TEMP
+  150                 CONTINUE
+  160             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*inv( A ).
+*
+              IF (UPPER) THEN
+                  DO 210 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 170 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  170                     CONTINUE
+                      END IF
+                      DO 190 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 180 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  180                         CONTINUE
+                          END IF
+  190                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 200 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  200                     CONTINUE
+                      END IF
+  210             CONTINUE
+              ELSE
+                  DO 260 J = N,1,-1
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 220 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  220                     CONTINUE
+                      END IF
+                      DO 240 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 230 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  230                         CONTINUE
+                          END IF
+  240                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 250 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  250                     CONTINUE
+                      END IF
+  260             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*inv( A**T ).
+*
+              IF (UPPER) THEN
+                  DO 310 K = N,1,-1
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(K,K)
+                          DO 270 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  270                     CONTINUE
+                      END IF
+                      DO 290 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = A(J,K)
+                              DO 280 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  280                         CONTINUE
+                          END IF
+  290                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 300 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  300                     CONTINUE
+                      END IF
+  310             CONTINUE
+              ELSE
+                  DO 360 K = 1,N
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(K,K)
+                          DO 320 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  320                     CONTINUE
+                      END IF
+                      DO 340 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              TEMP = A(J,K)
+                              DO 330 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  330                         CONTINUE
+                          END IF
+  340                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 350 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  350                     CONTINUE
+                      END IF
+  360             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STRSM .
+*
+      END
diff --git a/superlu/BLAS/strsv.f b/superlu/BLAS/strsv.f
new file mode 100644
index 0000000..a31651b
--- /dev/null
+++ b/superlu/BLAS/strsv.f
@@ -0,0 +1,344 @@
+*> \brief \b STRSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE STRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       REAL A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> STRSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular matrix.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**T*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is REAL array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular matrix and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular matrix and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced either, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is REAL array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup single_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE STRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      REAL A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      REAL ZERO
+      PARAMETER (ZERO=0.0E+0)
+*     ..
+*     .. Local Scalars ..
+      REAL TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('STRSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*A(I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 I = J - 1,1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*A(I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 I = J + 1,N
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 100 J = 1,N
+                      TEMP = X(J)
+                      DO 90 I = 1,J - 1
+                          TEMP = TEMP - A(I,J)*X(I)
+   90                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(J) = TEMP
+  100             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 120 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 110 I = 1,J - 1
+                          TEMP = TEMP - A(I,J)*X(IX)
+                          IX = IX + INCX
+  110                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  120             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 140 J = N,1,-1
+                      TEMP = X(J)
+                      DO 130 I = N,J + 1,-1
+                          TEMP = TEMP - A(I,J)*X(I)
+  130                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(J) = TEMP
+  140             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 160 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      DO 150 I = N,J + 1,-1
+                          TEMP = TEMP - A(I,J)*X(IX)
+                          IX = IX - INCX
+  150                 CONTINUE
+                      IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  160             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of STRSV .
+*
+      END
diff --git a/superlu/BLAS/xerbla.f b/superlu/BLAS/xerbla.f
new file mode 100644
index 0000000..bbe6cce
--- /dev/null
+++ b/superlu/BLAS/xerbla.f
@@ -0,0 +1,89 @@
+*> \brief \b XERBLA
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE XERBLA( SRNAME, INFO )
+*
+*       .. Scalar Arguments ..
+*       CHARACTER*(*)      SRNAME
+*       INTEGER            INFO
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> XERBLA  is an error handler for the LAPACK routines.
+*> It is called by an LAPACK routine if an input parameter has an
+*> invalid value.  A message is printed and execution stops.
+*>
+*> Installers may consider modifying the STOP statement in order to
+*> call system-specific exception-handling facilities.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SRNAME
+*> \verbatim
+*>          SRNAME is CHARACTER*(*)
+*>          The name of the routine which called XERBLA.
+*> \endverbatim
+*>
+*> \param[in] INFO
+*> \verbatim
+*>          INFO is INTEGER
+*>          The position of the invalid parameter in the parameter list
+*>          of the calling routine.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup aux_blas
+*
+*  =====================================================================
+      SUBROUTINE XERBLA( SRNAME, INFO )
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      CHARACTER*(*)      SRNAME
+      INTEGER            INFO
+*     ..
+*
+* =====================================================================
+*
+*     .. Intrinsic Functions ..
+      INTRINSIC          LEN_TRIM
+*     ..
+*     .. Executable Statements ..
+*
+      WRITE( *, FMT = 9999 )SRNAME( 1:LEN_TRIM( SRNAME ) ), INFO
+*
+      STOP
+*
+ 9999 FORMAT( ' ** On entry to ', A, ' parameter number ', I2, ' had ',
+     $      'an illegal value' )
+*
+*     End of XERBLA
+*
+      END
diff --git a/superlu/BLAS/xerbla_array.f b/superlu/BLAS/xerbla_array.f
new file mode 100644
index 0000000..df4e627
--- /dev/null
+++ b/superlu/BLAS/xerbla_array.f
@@ -0,0 +1,119 @@
+*> \brief \b XERBLA_ARRAY
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE XERBLA_ARRAY(SRNAME_ARRAY, SRNAME_LEN, INFO)
+*
+*       .. Scalar Arguments ..
+*       INTEGER SRNAME_LEN, INFO
+*       ..
+*       .. Array Arguments ..
+*       CHARACTER(1) SRNAME_ARRAY(SRNAME_LEN)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> XERBLA_ARRAY assists other languages in calling XERBLA, the LAPACK
+*> and BLAS error handler.  Rather than taking a Fortran string argument
+*> as the function's name, XERBLA_ARRAY takes an array of single
+*> characters along with the array's length.  XERBLA_ARRAY then copies
+*> up to 32 characters of that array into a Fortran string and passes
+*> that to XERBLA.  If called with a non-positive SRNAME_LEN,
+*> XERBLA_ARRAY will call XERBLA with a string of all blank characters.
+*>
+*> Say some macro or other device makes XERBLA_ARRAY available to C99
+*> by a name lapack_xerbla and with a common Fortran calling convention.
+*> Then a C99 program could invoke XERBLA via:
+*>    {
+*>      int flen = strlen(__func__);
+*>      lapack_xerbla(__func__, &flen, &info);
+*>    }
+*>
+*> Providing XERBLA_ARRAY is not necessary for intercepting LAPACK
+*> errors.  XERBLA_ARRAY calls XERBLA.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SRNAME_ARRAY
+*> \verbatim
+*>          SRNAME_ARRAY is CHARACTER(1) array, dimension (SRNAME_LEN)
+*>          The name of the routine which called XERBLA_ARRAY.
+*> \endverbatim
+*>
+*> \param[in] SRNAME_LEN
+*> \verbatim
+*>          SRNAME_LEN is INTEGER
+*>          The length of the name in SRNAME_ARRAY.
+*> \endverbatim
+*>
+*> \param[in] INFO
+*> \verbatim
+*>          INFO is INTEGER
+*>          The position of the invalid parameter in the parameter list
+*>          of the calling routine.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup aux_blas
+*
+*  =====================================================================
+      SUBROUTINE XERBLA_ARRAY(SRNAME_ARRAY, SRNAME_LEN, INFO)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER SRNAME_LEN, INFO
+*     ..
+*     .. Array Arguments ..
+      CHARACTER(1) SRNAME_ARRAY(SRNAME_LEN)
+*     ..
+*
+* =====================================================================
+*
+*     ..
+*     .. Local Scalars ..
+      INTEGER I
+*     ..
+*     .. Local Arrays ..
+      CHARACTER*32 SRNAME
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MIN, LEN
+*     ..
+*     .. External Functions ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Executable Statements ..
+      SRNAME = ''
+      DO I = 1, MIN( SRNAME_LEN, LEN( SRNAME ) )
+         SRNAME( I:I ) = SRNAME_ARRAY( I )
+      END DO
+
+      CALL XERBLA( SRNAME, INFO )
+
+      RETURN
+      END
diff --git a/superlu/BLAS/zaxpy.f b/superlu/BLAS/zaxpy.f
new file mode 100644
index 0000000..bca78fb
--- /dev/null
+++ b/superlu/BLAS/zaxpy.f
@@ -0,0 +1,102 @@
+*> \brief \b ZAXPY
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZAXPY(N,ZA,ZX,INCX,ZY,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ZA
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 ZX(*),ZY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    ZAXPY constant times a vector plus a vector.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZAXPY(N,ZA,ZX,INCX,ZY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ZA
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 ZX(*),ZY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY
+*     ..
+*     .. External Functions ..
+      DOUBLE PRECISION DCABS1
+      EXTERNAL DCABS1
+*     ..
+      IF (N.LE.0) RETURN
+      IF (DCABS1(ZA).EQ.0.0d0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1,N
+            ZY(I) = ZY(I) + ZA*ZX(I)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            ZY(IY) = ZY(IY) + ZA*ZX(IX)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+*
+      RETURN
+      END
diff --git a/superlu/BLAS/zcopy.f b/superlu/BLAS/zcopy.f
new file mode 100644
index 0000000..830548a
--- /dev/null
+++ b/superlu/BLAS/zcopy.f
@@ -0,0 +1,94 @@
+*> \brief \b ZCOPY
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZCOPY(N,ZX,INCX,ZY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 ZX(*),ZY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    ZCOPY copies a vector, x, to a vector, y.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, linpack, 4/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZCOPY(N,ZX,INCX,ZY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 ZX(*),ZY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,IX,IY
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1,N
+          ZY(I) = ZX(I)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            ZY(IY) = ZX(IX)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/zdotc.f b/superlu/BLAS/zdotc.f
new file mode 100644
index 0000000..70119ec
--- /dev/null
+++ b/superlu/BLAS/zdotc.f
@@ -0,0 +1,103 @@
+*> \brief \b ZDOTC
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       COMPLEX*16 FUNCTION ZDOTC(N,ZX,INCX,ZY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 ZX(*),ZY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZDOTC forms the dot product of two complex vectors
+*>      ZDOTC = X^H * Y
+*>
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      COMPLEX*16 FUNCTION ZDOTC(N,ZX,INCX,ZY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 ZX(*),ZY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      COMPLEX*16 ZTEMP
+      INTEGER I,IX,IY
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG
+*     ..
+      ZTEMP = (0.0d0,0.0d0)
+      ZDOTC = (0.0d0,0.0d0)
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1,N
+            ZTEMP = ZTEMP + DCONJG(ZX(I))*ZY(I)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            ZTEMP = ZTEMP + DCONJG(ZX(IX))*ZY(IY)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      ZDOTC = ZTEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/zdotu.f b/superlu/BLAS/zdotu.f
new file mode 100644
index 0000000..318fae2
--- /dev/null
+++ b/superlu/BLAS/zdotu.f
@@ -0,0 +1,100 @@
+*> \brief \b ZDOTU
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       COMPLEX*16 FUNCTION ZDOTU(N,ZX,INCX,ZY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 ZX(*),ZY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZDOTU forms the dot product of two complex vectors
+*>      ZDOTU = X^T * Y
+*>
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      COMPLEX*16 FUNCTION ZDOTU(N,ZX,INCX,ZY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 ZX(*),ZY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      COMPLEX*16 ZTEMP
+      INTEGER I,IX,IY
+*     ..
+      ZTEMP = (0.0d0,0.0d0)
+      ZDOTU = (0.0d0,0.0d0)
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1,N
+            ZTEMP = ZTEMP + ZX(I)*ZY(I)
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments
+*          not equal to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            ZTEMP = ZTEMP + ZX(IX)*ZY(IY)
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      ZDOTU = ZTEMP
+      RETURN
+      END
diff --git a/superlu/BLAS/zdrot.f b/superlu/BLAS/zdrot.f
new file mode 100644
index 0000000..8a4cf65
--- /dev/null
+++ b/superlu/BLAS/zdrot.f
@@ -0,0 +1,153 @@
+*> \brief \b ZDROT
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZDROT( N, CX, INCX, CY, INCY, C, S )
+*
+*       .. Scalar Arguments ..
+*       INTEGER            INCX, INCY, N
+*       DOUBLE PRECISION   C, S
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16         CX( * ), CY( * )
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> Applies a plane rotation, where the cos and sin (c and s) are real
+*> and the vectors cx and cy are complex.
+*> jack dongarra, linpack, 3/11/78.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the vectors cx and cy.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in,out] CX
+*> \verbatim
+*>          CX is COMPLEX*16 array, dimension at least
+*>           ( 1 + ( N - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array CX must contain the n
+*>           element vector cx. On exit, CX is overwritten by the updated
+*>           vector cx.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           CX. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] CY
+*> \verbatim
+*>          CY is COMPLEX*16 array, dimension at least
+*>           ( 1 + ( N - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array CY must contain the n
+*>           element vector cy. On exit, CY is overwritten by the updated
+*>           vector cy.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           CY. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in] C
+*> \verbatim
+*>          C is DOUBLE PRECISION
+*>           On entry, C specifies the cosine, cos.
+*> \endverbatim
+*>
+*> \param[in] S
+*> \verbatim
+*>          S is DOUBLE PRECISION
+*>           On entry, S specifies the sine, sin.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level1
+*
+*  =====================================================================
+      SUBROUTINE ZDROT( N, CX, INCX, CY, INCY, C, S )
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER            INCX, INCY, N
+      DOUBLE PRECISION   C, S
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16         CX( * ), CY( * )
+*     ..
+*
+* =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER            I, IX, IY
+      COMPLEX*16         CTEMP
+*     ..
+*     .. Executable Statements ..
+*
+      IF( N.LE.0 )
+     $   RETURN
+      IF( INCX.EQ.1 .AND. INCY.EQ.1 ) THEN
+*
+*        code for both increments equal to 1
+*
+         DO I = 1, N
+            CTEMP = C*CX( I ) + S*CY( I )
+            CY( I ) = C*CY( I ) - S*CX( I )
+            CX( I ) = CTEMP
+         END DO
+      ELSE
+*
+*        code for unequal increments or equal increments not equal
+*          to 1
+*
+         IX = 1
+         IY = 1
+         IF( INCX.LT.0 )
+     $      IX = ( -N+1 )*INCX + 1
+         IF( INCY.LT.0 )
+     $      IY = ( -N+1 )*INCY + 1
+         DO I = 1, N
+            CTEMP = C*CX( IX ) + S*CY( IY )
+            CY( IY ) = C*CY( IY ) - S*CX( IX )
+            CX( IX ) = CTEMP
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/zdscal.f b/superlu/BLAS/zdscal.f
new file mode 100644
index 0000000..def9078
--- /dev/null
+++ b/superlu/BLAS/zdscal.f
@@ -0,0 +1,94 @@
+*> \brief \b ZDSCAL
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZDSCAL(N,DA,ZX,INCX)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION DA
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 ZX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    ZDSCAL scales a vector by a constant.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZDSCAL(N,DA,ZX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION DA
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 ZX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,NINCX
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCMPLX
+*     ..
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         DO I = 1,N
+            ZX(I) = DCMPLX(DA,0.0d0)*ZX(I)
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            ZX(I) = DCMPLX(DA,0.0d0)*ZX(I)
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/zgbmv.f b/superlu/BLAS/zgbmv.f
new file mode 100644
index 0000000..f49da22
--- /dev/null
+++ b/superlu/BLAS/zgbmv.f
@@ -0,0 +1,390 @@
+*> \brief \b ZGBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZGBMV(TRANS,M,N,KL,KU,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER INCX,INCY,KL,KU,LDA,M,N
+*       CHARACTER TRANS
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZGBMV  performs one of the matrix-vector operations
+*>
+*>    y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,   or
+*>
+*>    y := alpha*A**H*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are vectors and A is an
+*> m by n band matrix, with kl sub-diagonals and ku super-diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*>
+*>              TRANS = 'T' or 't'   y := alpha*A**T*x + beta*y.
+*>
+*>              TRANS = 'C' or 'c'   y := alpha*A**H*x + beta*y.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] KL
+*> \verbatim
+*>          KL is INTEGER
+*>           On entry, KL specifies the number of sub-diagonals of the
+*>           matrix A. KL must satisfy  0 .le. KL.
+*> \endverbatim
+*>
+*> \param[in] KU
+*> \verbatim
+*>          KU is INTEGER
+*>           On entry, KU specifies the number of super-diagonals of the
+*>           matrix A. KU must satisfy  0 .le. KU.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading ( kl + ku + 1 ) by n part of the
+*>           array A must contain the matrix of coefficients, supplied
+*>           column by column, with the leading diagonal of the matrix in
+*>           row ( ku + 1 ) of the array, the first super-diagonal
+*>           starting at position 2 in row ku, the first sub-diagonal
+*>           starting at position 1 in row ( ku + 2 ), and so on.
+*>           Elements in the array A that do not correspond to elements
+*>           in the band matrix (such as the top left ku by ku triangle)
+*>           are not referenced.
+*>           The following program segment will transfer a band matrix
+*>           from conventional full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    K = KU + 1 - J
+*>                    DO 10, I = MAX( 1, J - KU ), MIN( M, J + KL )
+*>                       A( K + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( kl + ku + 1 ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX*16 array of DIMENSION at least
+*>           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*>           Before entry, the incremented array Y must contain the
+*>           vector y. On exit, Y is overwritten by the updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZGBMV(TRANS,M,N,KL,KU,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER INCX,INCY,KL,KU,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KUP1,KX,KY,LENX,LENY
+      LOGICAL NOCONJ
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (KL.LT.0) THEN
+          INFO = 4
+      ELSE IF (KU.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (KL+KU+1)) THEN
+          INFO = 8
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 10
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZGBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the band part of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      KUP1 = KU + 1
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  K = KUP1 - J
+                  DO 50 I = MAX(1,J-KU),MIN(M,J+KL)
+                      Y(I) = Y(I) + TEMP*A(K+I,J)
+   50             CONTINUE
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  IY = KY
+                  K = KUP1 - J
+                  DO 70 I = MAX(1,J-KU),MIN(M,J+KL)
+                      Y(IY) = Y(IY) + TEMP*A(K+I,J)
+                      IY = IY + INCY
+   70             CONTINUE
+                  JX = JX + INCX
+                  IF (J.GT.KU) KY = KY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A**T*x + y  or  y := alpha*A**H*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 110 J = 1,N
+                  TEMP = ZERO
+                  K = KUP1 - J
+                  IF (NOCONJ) THEN
+                      DO 90 I = MAX(1,J-KU),MIN(M,J+KL)
+                          TEMP = TEMP + A(K+I,J)*X(I)
+   90                 CONTINUE
+                  ELSE
+                      DO 100 I = MAX(1,J-KU),MIN(M,J+KL)
+                          TEMP = TEMP + DCONJG(A(K+I,J))*X(I)
+  100                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  110         CONTINUE
+          ELSE
+              DO 140 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  K = KUP1 - J
+                  IF (NOCONJ) THEN
+                      DO 120 I = MAX(1,J-KU),MIN(M,J+KL)
+                          TEMP = TEMP + A(K+I,J)*X(IX)
+                          IX = IX + INCX
+  120                 CONTINUE
+                  ELSE
+                      DO 130 I = MAX(1,J-KU),MIN(M,J+KL)
+                          TEMP = TEMP + DCONJG(A(K+I,J))*X(IX)
+                          IX = IX + INCX
+  130                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+                  IF (J.GT.KU) KX = KX + INCX
+  140         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZGBMV .
+*
+      END
diff --git a/superlu/BLAS/zgemm.f b/superlu/BLAS/zgemm.f
new file mode 100644
index 0000000..a172632
--- /dev/null
+++ b/superlu/BLAS/zgemm.f
@@ -0,0 +1,483 @@
+*> \brief \b ZGEMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER K,LDA,LDB,LDC,M,N
+*       CHARACTER TRANSA,TRANSB
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZGEMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*op( A )*op( B ) + beta*C,
+*>
+*> where  op( X ) is one of
+*>
+*>    op( X ) = X   or   op( X ) = X**T   or   op( X ) = X**H,
+*>
+*> alpha and beta are scalars, and A, B and C are matrices, with op( A )
+*> an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n',  op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't',  op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c',  op( A ) = A**H.
+*> \endverbatim
+*>
+*> \param[in] TRANSB
+*> \verbatim
+*>          TRANSB is CHARACTER*1
+*>           On entry, TRANSB specifies the form of op( B ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSB = 'N' or 'n',  op( B ) = B.
+*>
+*>              TRANSB = 'T' or 't',  op( B ) = B**T.
+*>
+*>              TRANSB = 'C' or 'c',  op( B ) = B**H.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies  the number  of rows  of the  matrix
+*>           op( A )  and of the  matrix  C.  M  must  be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N  specifies the number  of columns of the matrix
+*>           op( B ) and the number of columns of the matrix C. N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry,  K  specifies  the number of columns of the matrix
+*>           op( A ) and the number of rows of the matrix op( B ). K must
+*>           be at least  zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANSA = 'N' or 'n',  and is  m  otherwise.
+*>           Before entry with  TRANSA = 'N' or 'n',  the leading  m by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by m  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. When  TRANSA = 'N' or 'n' then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX*16 array of DIMENSION ( LDB, kb ), where kb is
+*>           n  when  TRANSB = 'N' or 'n',  and is  k  otherwise.
+*>           Before entry with  TRANSB = 'N' or 'n',  the leading  k by n
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  n by k  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in the calling (sub) program. When  TRANSB = 'N' or 'n' then
+*>           LDB must be at least  max( 1, k ), otherwise  LDB must be at
+*>           least  max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX*16 array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n  matrix
+*>           ( alpha*op( A )*op( B ) + beta*C ).
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,M,N
+      CHARACTER TRANSA,TRANSB
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,J,L,NCOLA,NROWA,NROWB
+      LOGICAL CONJA,CONJB,NOTA,NOTB
+*     ..
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not
+*     conjugated or transposed, set  CONJA and CONJB  as true if  A  and
+*     B  respectively are to be  transposed but  not conjugated  and set
+*     NROWA, NCOLA and  NROWB  as the number of rows and  columns  of  A
+*     and the number of rows of  B  respectively.
+*
+      NOTA = LSAME(TRANSA,'N')
+      NOTB = LSAME(TRANSB,'N')
+      CONJA = LSAME(TRANSA,'C')
+      CONJB = LSAME(TRANSB,'C')
+      IF (NOTA) THEN
+          NROWA = M
+          NCOLA = K
+      ELSE
+          NROWA = K
+          NCOLA = M
+      END IF
+      IF (NOTB) THEN
+          NROWB = K
+      ELSE
+          NROWB = N
+      END IF
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.NOTA) .AND. (.NOT.CONJA) .AND.
+     +    (.NOT.LSAME(TRANSA,'T'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.NOTB) .AND. (.NOT.CONJB) .AND.
+     +         (.NOT.LSAME(TRANSB,'T'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 8
+      ELSE IF (LDB.LT.MAX(1,NROWB)) THEN
+          INFO = 10
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 13
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZGEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (NOTB) THEN
+          IF (NOTA) THEN
+*
+*           Form  C := alpha*A*B + beta*C.
+*
+              DO 90 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 50 I = 1,M
+                          C(I,J) = ZERO
+   50                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 60 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+   60                 CONTINUE
+                  END IF
+                  DO 80 L = 1,K
+                      TEMP = ALPHA*B(L,J)
+                      DO 70 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+   70                 CONTINUE
+   80             CONTINUE
+   90         CONTINUE
+          ELSE IF (CONJA) THEN
+*
+*           Form  C := alpha*A**H*B + beta*C.
+*
+              DO 120 J = 1,N
+                  DO 110 I = 1,M
+                      TEMP = ZERO
+                      DO 100 L = 1,K
+                          TEMP = TEMP + DCONJG(A(L,I))*B(L,J)
+  100                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  110             CONTINUE
+  120         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**T*B + beta*C
+*
+              DO 150 J = 1,N
+                  DO 140 I = 1,M
+                      TEMP = ZERO
+                      DO 130 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(L,J)
+  130                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  140             CONTINUE
+  150         CONTINUE
+          END IF
+      ELSE IF (NOTA) THEN
+          IF (CONJB) THEN
+*
+*           Form  C := alpha*A*B**H + beta*C.
+*
+              DO 200 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 160 I = 1,M
+                          C(I,J) = ZERO
+  160                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 170 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+  170                 CONTINUE
+                  END IF
+                  DO 190 L = 1,K
+                      TEMP = ALPHA*DCONJG(B(J,L))
+                      DO 180 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+  180                 CONTINUE
+  190             CONTINUE
+  200         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A*B**T + beta*C
+*
+              DO 250 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 210 I = 1,M
+                          C(I,J) = ZERO
+  210                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 220 I = 1,M
+                          C(I,J) = BETA*C(I,J)
+  220                 CONTINUE
+                  END IF
+                  DO 240 L = 1,K
+                      TEMP = ALPHA*B(J,L)
+                      DO 230 I = 1,M
+                          C(I,J) = C(I,J) + TEMP*A(I,L)
+  230                 CONTINUE
+  240             CONTINUE
+  250         CONTINUE
+          END IF
+      ELSE IF (CONJA) THEN
+          IF (CONJB) THEN
+*
+*           Form  C := alpha*A**H*B**H + beta*C.
+*
+              DO 280 J = 1,N
+                  DO 270 I = 1,M
+                      TEMP = ZERO
+                      DO 260 L = 1,K
+                          TEMP = TEMP + DCONJG(A(L,I))*DCONJG(B(J,L))
+  260                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  270             CONTINUE
+  280         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**H*B**T + beta*C
+*
+              DO 310 J = 1,N
+                  DO 300 I = 1,M
+                      TEMP = ZERO
+                      DO 290 L = 1,K
+                          TEMP = TEMP + DCONJG(A(L,I))*B(J,L)
+  290                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  300             CONTINUE
+  310         CONTINUE
+          END IF
+      ELSE
+          IF (CONJB) THEN
+*
+*           Form  C := alpha*A**T*B**H + beta*C
+*
+              DO 340 J = 1,N
+                  DO 330 I = 1,M
+                      TEMP = ZERO
+                      DO 320 L = 1,K
+                          TEMP = TEMP + A(L,I)*DCONJG(B(J,L))
+  320                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  330             CONTINUE
+  340         CONTINUE
+          ELSE
+*
+*           Form  C := alpha*A**T*B**T + beta*C
+*
+              DO 370 J = 1,N
+                  DO 360 I = 1,M
+                      TEMP = ZERO
+                      DO 350 L = 1,K
+                          TEMP = TEMP + A(L,I)*B(J,L)
+  350                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  360             CONTINUE
+  370         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZGEMM .
+*
+      END
diff --git a/superlu/BLAS/zgemv.f b/superlu/BLAS/zgemv.f
new file mode 100644
index 0000000..01e44d4
--- /dev/null
+++ b/superlu/BLAS/zgemv.f
@@ -0,0 +1,350 @@
+*> \brief \b ZGEMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER INCX,INCY,LDA,M,N
+*       CHARACTER TRANS
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZGEMV  performs one of the matrix-vector operations
+*>
+*>    y := alpha*A*x + beta*y,   or   y := alpha*A**T*x + beta*y,   or
+*>
+*>    y := alpha*A**H*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are vectors and A is an
+*> m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.
+*>
+*>              TRANS = 'T' or 't'   y := alpha*A**T*x + beta*y.
+*>
+*>              TRANS = 'C' or 'c'   y := alpha*A**H*x + beta*y.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX*16 array of DIMENSION at least
+*>           ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
+*>           and at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
+*>           Before entry with BETA non-zero, the incremented array Y
+*>           must contain the vector y. On exit, Y is overwritten by the
+*>           updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER INCX,INCY,LDA,M,N
+      CHARACTER TRANS
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY,LENX,LENY
+      LOGICAL NOCONJ
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +    .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 1
+      ELSE IF (M.LT.0) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZGEMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+*
+*     Set  LENX  and  LENY, the lengths of the vectors x and y, and set
+*     up the start points in  X  and  Y.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          LENX = N
+          LENY = M
+      ELSE
+          LENX = M
+          LENY = N
+      END IF
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (LENX-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (LENY-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,LENY
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,LENY
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,LENY
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,LENY
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  y := alpha*A*x + y.
+*
+          JX = KX
+          IF (INCY.EQ.1) THEN
+              DO 60 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  DO 50 I = 1,M
+                      Y(I) = Y(I) + TEMP*A(I,J)
+   50             CONTINUE
+                  JX = JX + INCX
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  TEMP = ALPHA*X(JX)
+                  IY = KY
+                  DO 70 I = 1,M
+                      Y(IY) = Y(IY) + TEMP*A(I,J)
+                      IY = IY + INCY
+   70             CONTINUE
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y := alpha*A**T*x + y  or  y := alpha*A**H*x + y.
+*
+          JY = KY
+          IF (INCX.EQ.1) THEN
+              DO 110 J = 1,N
+                  TEMP = ZERO
+                  IF (NOCONJ) THEN
+                      DO 90 I = 1,M
+                          TEMP = TEMP + A(I,J)*X(I)
+   90                 CONTINUE
+                  ELSE
+                      DO 100 I = 1,M
+                          TEMP = TEMP + DCONJG(A(I,J))*X(I)
+  100                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  110         CONTINUE
+          ELSE
+              DO 140 J = 1,N
+                  TEMP = ZERO
+                  IX = KX
+                  IF (NOCONJ) THEN
+                      DO 120 I = 1,M
+                          TEMP = TEMP + A(I,J)*X(IX)
+                          IX = IX + INCX
+  120                 CONTINUE
+                  ELSE
+                      DO 130 I = 1,M
+                          TEMP = TEMP + DCONJG(A(I,J))*X(IX)
+                          IX = IX + INCX
+  130                 CONTINUE
+                  END IF
+                  Y(JY) = Y(JY) + ALPHA*TEMP
+                  JY = JY + INCY
+  140         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZGEMV .
+*
+      END
diff --git a/superlu/BLAS/zgerc.f b/superlu/BLAS/zgerc.f
new file mode 100644
index 0000000..cf8e17d
--- /dev/null
+++ b/superlu/BLAS/zgerc.f
@@ -0,0 +1,227 @@
+*> \brief \b ZGERC
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZGERC(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA
+*       INTEGER INCX,INCY,LDA,M,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZGERC  performs the rank 1 operation
+*>
+*>    A := alpha*x*y**H + A,
+*>
+*> where alpha is a scalar, x is an m element vector, y is an n element
+*> vector and A is an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the m
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients. On exit, A is
+*>           overwritten by the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZGERC(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA
+      INTEGER INCX,INCY,LDA,M,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JY,KX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (M.LT.0) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZGERC ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (INCY.GT.0) THEN
+          JY = 1
+      ELSE
+          JY = 1 - (N-1)*INCY
+      END IF
+      IF (INCX.EQ.1) THEN
+          DO 20 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*DCONJG(Y(JY))
+                  DO 10 I = 1,M
+                      A(I,J) = A(I,J) + X(I)*TEMP
+   10             CONTINUE
+              END IF
+              JY = JY + INCY
+   20     CONTINUE
+      ELSE
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (M-1)*INCX
+          END IF
+          DO 40 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*DCONJG(Y(JY))
+                  IX = KX
+                  DO 30 I = 1,M
+                      A(I,J) = A(I,J) + X(IX)*TEMP
+                      IX = IX + INCX
+   30             CONTINUE
+              END IF
+              JY = JY + INCY
+   40     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZGERC .
+*
+      END
diff --git a/superlu/BLAS/zgeru.f b/superlu/BLAS/zgeru.f
new file mode 100644
index 0000000..d191740
--- /dev/null
+++ b/superlu/BLAS/zgeru.f
@@ -0,0 +1,227 @@
+*> \brief \b ZGERU
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZGERU(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA
+*       INTEGER INCX,INCY,LDA,M,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZGERU  performs the rank 1 operation
+*>
+*>    A := alpha*x*y**T + A,
+*>
+*> where alpha is a scalar, x is an m element vector, y is an n element
+*> vector and A is an m by n matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of the matrix A.
+*>           M must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( m - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the m
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry, the leading m by n part of the array A must
+*>           contain the matrix of coefficients. On exit, A is
+*>           overwritten by the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZGERU(M,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA
+      INTEGER INCX,INCY,LDA,M,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JY,KX
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (M.LT.0) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,M)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZGERU ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (INCY.GT.0) THEN
+          JY = 1
+      ELSE
+          JY = 1 - (N-1)*INCY
+      END IF
+      IF (INCX.EQ.1) THEN
+          DO 20 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  DO 10 I = 1,M
+                      A(I,J) = A(I,J) + X(I)*TEMP
+   10             CONTINUE
+              END IF
+              JY = JY + INCY
+   20     CONTINUE
+      ELSE
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (M-1)*INCX
+          END IF
+          DO 40 J = 1,N
+              IF (Y(JY).NE.ZERO) THEN
+                  TEMP = ALPHA*Y(JY)
+                  IX = KX
+                  DO 30 I = 1,M
+                      A(I,J) = A(I,J) + X(IX)*TEMP
+                      IX = IX + INCX
+   30             CONTINUE
+              END IF
+              JY = JY + INCY
+   40     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZGERU .
+*
+      END
diff --git a/superlu/BLAS/zhbmv.f b/superlu/BLAS/zhbmv.f
new file mode 100644
index 0000000..8742215
--- /dev/null
+++ b/superlu/BLAS/zhbmv.f
@@ -0,0 +1,380 @@
+*> \brief \b ZHBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER INCX,INCY,K,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHBMV  performs the matrix-vector  operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n hermitian band matrix, with k super-diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the band matrix A is being supplied as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  being supplied.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  being supplied.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry, K specifies the number of super-diagonals of the
+*>           matrix A. K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the hermitian matrix, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer the upper
+*>           triangular part of a hermitian band matrix from conventional
+*>           full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the hermitian matrix, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer the lower
+*>           triangular part of a hermitian band matrix from conventional
+*>           full matrix storage to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set and are assumed to be zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the
+*>           vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX*16 array of DIMENSION at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the
+*>           vector y. On exit, Y is overwritten by the updated vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER INCX,INCY,K,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KPLUS1,KX,KY,L
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG,MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (K.LT.0) THEN
+          INFO = 3
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of the array A
+*     are accessed sequentially with one pass through A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when upper triangle of A is stored.
+*
+          KPLUS1 = K + 1
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  L = KPLUS1 - J
+                  DO 50 I = MAX(1,J-K),J - 1
+                      Y(I) = Y(I) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + DCONJG(A(L+I,J))*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*DBLE(A(KPLUS1,J)) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  L = KPLUS1 - J
+                  DO 70 I = MAX(1,J-K),J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + DCONJG(A(L+I,J))*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*DBLE(A(KPLUS1,J)) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  IF (J.GT.K) THEN
+                      KX = KX + INCX
+                      KY = KY + INCY
+                  END IF
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when lower triangle of A is stored.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*DBLE(A(1,J))
+                  L = 1 - J
+                  DO 90 I = J + 1,MIN(N,J+K)
+                      Y(I) = Y(I) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + DCONJG(A(L+I,J))*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*DBLE(A(1,J))
+                  L = 1 - J
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,MIN(N,J+K)
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(L+I,J)
+                      TEMP2 = TEMP2 + DCONJG(A(L+I,J))*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHBMV .
+*
+      END
diff --git a/superlu/BLAS/zhemm.f b/superlu/BLAS/zhemm.f
new file mode 100644
index 0000000..45a5eab
--- /dev/null
+++ b/superlu/BLAS/zhemm.f
@@ -0,0 +1,371 @@
+*> \brief \b ZHEMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHEMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER LDA,LDB,LDC,M,N
+*       CHARACTER SIDE,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHEMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*A*B + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*B*A + beta*C,
+*>
+*> where alpha and beta are scalars, A is an hermitian matrix and  B and
+*> C are m by n matrices.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE  specifies whether  the  hermitian matrix  A
+*>           appears on the  left or right  in the  operation as follows:
+*>
+*>              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*>
+*>              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of  the  hermitian  matrix   A  is  to  be
+*>           referenced as follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*>                                  hermitian matrix is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*>                                  hermitian matrix is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies the number of rows of the matrix  C.
+*>           M  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix C.
+*>           N  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, ka ), where ka is
+*>           m  when  SIDE = 'L' or 'l'  and is n  otherwise.
+*>           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*>           the array  A  must contain the  hermitian matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  hermitian matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  m by m  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  hermitian
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*>           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*>           the array  A  must contain the  hermitian matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  hermitian matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  n by n  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  hermitian
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*>           Note that the imaginary parts  of the diagonal elements need
+*>           not be set, they are assumed to be zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the  calling (sub) program. When  SIDE = 'L' or 'l'  then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX*16 array of DIMENSION ( LDB, n ).
+*>           Before entry, the leading  m by n part of the array  B  must
+*>           contain the matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX*16 array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n updated
+*>           matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHEMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHEMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*DCONJG(A(K,I))
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*DBLE(A(I,I)) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*DBLE(A(I,I)) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*DCONJG(A(K,I))
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*DBLE(A(I,I)) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*DBLE(A(I,I)) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*DBLE(A(J,J))
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*DCONJG(A(J,K))
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*DCONJG(A(J,K))
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZHEMM .
+*
+      END
diff --git a/superlu/BLAS/zhemv.f b/superlu/BLAS/zhemv.f
new file mode 100644
index 0000000..3791745
--- /dev/null
+++ b/superlu/BLAS/zhemv.f
@@ -0,0 +1,337 @@
+*> \brief \b ZHEMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHEMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER INCX,INCY,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHEMV  performs the matrix-vector  operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n hermitian matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the hermitian matrix and the strictly
+*>           lower triangular part of A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the hermitian matrix and the strictly
+*>           upper triangular part of A is not referenced.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set and are assumed to be zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y. On exit, Y is overwritten by the updated
+*>           vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHEMV(UPLO,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 5
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHEMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when A is stored in upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + DCONJG(A(I,J))*X(I)
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*DBLE(A(J,J)) + ALPHA*TEMP2
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 I = 1,J - 1
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + DCONJG(A(I,J))*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*DBLE(A(J,J)) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when A is stored in lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*DBLE(A(J,J))
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + DCONJG(A(I,J))*X(I)
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*DBLE(A(J,J))
+                  IX = JX
+                  IY = JY
+                  DO 110 I = J + 1,N
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*A(I,J)
+                      TEMP2 = TEMP2 + DCONJG(A(I,J))*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHEMV .
+*
+      END
diff --git a/superlu/BLAS/zher.f b/superlu/BLAS/zher.f
new file mode 100644
index 0000000..f7def76
--- /dev/null
+++ b/superlu/BLAS/zher.f
@@ -0,0 +1,278 @@
+*> \brief \b ZHER
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHER(UPLO,N,ALPHA,X,INCX,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA
+*       INTEGER INCX,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHER   performs the hermitian rank 1 operation
+*>
+*>    A := alpha*x*x**H + A,
+*>
+*> where alpha is a real scalar, x is an n element vector and A is an
+*> n by n hermitian matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the hermitian matrix and the strictly
+*>           lower triangular part of A is not referenced. On exit, the
+*>           upper triangular part of the array A is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the hermitian matrix and the strictly
+*>           upper triangular part of A is not referenced. On exit, the
+*>           lower triangular part of the array A is overwritten by the
+*>           lower triangular part of the updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set, they are assumed to be zero, and on exit they
+*>           are set to zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHER(UPLO,N,ALPHA,X,INCX,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA
+      INTEGER INCX,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHER  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.DBLE(ZERO))) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in upper triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*DCONJG(X(J))
+                      DO 10 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   10                 CONTINUE
+                      A(J,J) = DBLE(A(J,J)) + DBLE(X(J)*TEMP)
+                  ELSE
+                      A(J,J) = DBLE(A(J,J))
+                  END IF
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*DCONJG(X(JX))
+                      IX = KX
+                      DO 30 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                      A(J,J) = DBLE(A(J,J)) + DBLE(X(JX)*TEMP)
+                  ELSE
+                      A(J,J) = DBLE(A(J,J))
+                  END IF
+                  JX = JX + INCX
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in lower triangle.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*DCONJG(X(J))
+                      A(J,J) = DBLE(A(J,J)) + DBLE(TEMP*X(J))
+                      DO 50 I = J + 1,N
+                          A(I,J) = A(I,J) + X(I)*TEMP
+   50                 CONTINUE
+                  ELSE
+                      A(J,J) = DBLE(A(J,J))
+                  END IF
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*DCONJG(X(JX))
+                      A(J,J) = DBLE(A(J,J)) + DBLE(TEMP*X(JX))
+                      IX = JX
+                      DO 70 I = J + 1,N
+                          IX = IX + INCX
+                          A(I,J) = A(I,J) + X(IX)*TEMP
+   70                 CONTINUE
+                  ELSE
+                      A(J,J) = DBLE(A(J,J))
+                  END IF
+                  JX = JX + INCX
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHER  .
+*
+      END
diff --git a/superlu/BLAS/zher2.f b/superlu/BLAS/zher2.f
new file mode 100644
index 0000000..94c132c
--- /dev/null
+++ b/superlu/BLAS/zher2.f
@@ -0,0 +1,317 @@
+*> \brief \b ZHER2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHER2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA
+*       INTEGER INCX,INCY,LDA,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHER2  performs the hermitian rank 2 operation
+*>
+*>    A := alpha*x*y**H + conjg( alpha )*y*x**H + A,
+*>
+*> where alpha is a scalar, x and y are n element vectors and A is an n
+*> by n hermitian matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the array A is to be referenced as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of A
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of A
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular part of the hermitian matrix and the strictly
+*>           lower triangular part of A is not referenced. On exit, the
+*>           upper triangular part of the array A is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular part of the hermitian matrix and the strictly
+*>           upper triangular part of A is not referenced. On exit, the
+*>           lower triangular part of the array A is overwritten by the
+*>           lower triangular part of the updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set, they are assumed to be zero, and on exit they
+*>           are set to zero.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHER2(UPLO,N,ALPHA,X,INCX,Y,INCY,A,LDA)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA
+      INTEGER INCX,INCY,LDA,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHER2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through the triangular part
+*     of A.
+*
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when A is stored in the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*DCONJG(Y(J))
+                      TEMP2 = DCONJG(ALPHA*X(J))
+                      DO 10 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   10                 CONTINUE
+                      A(J,J) = DBLE(A(J,J)) +
+     +                         DBLE(X(J)*TEMP1+Y(J)*TEMP2)
+                  ELSE
+                      A(J,J) = DBLE(A(J,J))
+                  END IF
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*DCONJG(Y(JY))
+                      TEMP2 = DCONJG(ALPHA*X(JX))
+                      IX = KX
+                      IY = KY
+                      DO 30 I = 1,J - 1
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                      A(J,J) = DBLE(A(J,J)) +
+     +                         DBLE(X(JX)*TEMP1+Y(JY)*TEMP2)
+                  ELSE
+                      A(J,J) = DBLE(A(J,J))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when A is stored in the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*DCONJG(Y(J))
+                      TEMP2 = DCONJG(ALPHA*X(J))
+                      A(J,J) = DBLE(A(J,J)) +
+     +                         DBLE(X(J)*TEMP1+Y(J)*TEMP2)
+                      DO 50 I = J + 1,N
+                          A(I,J) = A(I,J) + X(I)*TEMP1 + Y(I)*TEMP2
+   50                 CONTINUE
+                  ELSE
+                      A(J,J) = DBLE(A(J,J))
+                  END IF
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*DCONJG(Y(JY))
+                      TEMP2 = DCONJG(ALPHA*X(JX))
+                      A(J,J) = DBLE(A(J,J)) +
+     +                         DBLE(X(JX)*TEMP1+Y(JY)*TEMP2)
+                      IX = JX
+                      IY = JY
+                      DO 70 I = J + 1,N
+                          IX = IX + INCX
+                          IY = IY + INCY
+                          A(I,J) = A(I,J) + X(IX)*TEMP1 + Y(IY)*TEMP2
+   70                 CONTINUE
+                  ELSE
+                      A(J,J) = DBLE(A(J,J))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHER2 .
+*
+      END
diff --git a/superlu/BLAS/zher2k.f b/superlu/BLAS/zher2k.f
new file mode 100644
index 0000000..407e8db
--- /dev/null
+++ b/superlu/BLAS/zher2k.f
@@ -0,0 +1,443 @@
+*> \brief \b ZHER2K
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHER2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA
+*       DOUBLE PRECISION BETA
+*       INTEGER K,LDA,LDB,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHER2K  performs one of the hermitian rank 2k operations
+*>
+*>    C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C,
+*>
+*> where  alpha and beta  are scalars with  beta  real,  C is an  n by n
+*> hermitian matrix and  A and B  are  n by k matrices in the first case
+*> and  k by n  matrices in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'    C := alpha*A*B**H          +
+*>                                         conjg( alpha )*B*A**H +
+*>                                         beta*C.
+*>
+*>              TRANS = 'C' or 'c'    C := alpha*A**H*B          +
+*>                                         conjg( alpha )*B**H*A +
+*>                                         beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns  of the  matrices  A and B,  and on  entry  with
+*>           TRANS = 'C' or 'c',  K  specifies  the number of rows of the
+*>           matrices  A and B.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16 .
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX*16 array of DIMENSION ( LDB, kb ), where kb is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  k by n  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*>           be at least  max( 1, k ).
+*>           Unchanged on exit.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION .
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX*16 array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  hermitian matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  hermitian matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set,  they are assumed to be zero,  and on exit they
+*>           are set to zero.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*>
+*>  -- Modified 8-Nov-93 to set C(J,J) to DBLE( C(J,J) ) when BETA = 1.
+*>     Ed Anderson, Cray Research Inc.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHER2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA
+      DOUBLE PRECISION BETA
+      INTEGER K,LDA,LDB,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP1,TEMP2
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION ONE
+      PARAMETER (ONE=1.0D+0)
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHER2K',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.DBLE(ZERO)) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+                      C(J,J) = BETA*DBLE(C(J,J))
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.DBLE(ZERO)) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      C(J,J) = BETA*DBLE(C(J,J))
+                      DO 70 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*B**H + conjg( alpha )*B*A**H +
+*                   C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.DBLE(ZERO)) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                      C(J,J) = BETA*DBLE(C(J,J))
+                  ELSE
+                      C(J,J) = DBLE(C(J,J))
+                  END IF
+                  DO 120 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*DCONJG(B(J,L))
+                          TEMP2 = DCONJG(ALPHA*A(J,L))
+                          DO 110 I = 1,J - 1
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  110                     CONTINUE
+                          C(J,J) = DBLE(C(J,J)) +
+     +                             DBLE(A(J,L)*TEMP1+B(J,L)*TEMP2)
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.DBLE(ZERO)) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                      C(J,J) = BETA*DBLE(C(J,J))
+                  ELSE
+                      C(J,J) = DBLE(C(J,J))
+                  END IF
+                  DO 170 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*DCONJG(B(J,L))
+                          TEMP2 = DCONJG(ALPHA*A(J,L))
+                          DO 160 I = J + 1,N
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  160                     CONTINUE
+                          C(J,J) = DBLE(C(J,J)) +
+     +                             DBLE(A(J,L)*TEMP1+B(J,L)*TEMP2)
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**H*B + conjg( alpha )*B**H*A +
+*                   C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 190 L = 1,K
+                          TEMP1 = TEMP1 + DCONJG(A(L,I))*B(L,J)
+                          TEMP2 = TEMP2 + DCONJG(B(L,I))*A(L,J)
+  190                 CONTINUE
+                      IF (I.EQ.J) THEN
+                          IF (BETA.EQ.DBLE(ZERO)) THEN
+                              C(J,J) = DBLE(ALPHA*TEMP1+
+     +                                 DCONJG(ALPHA)*TEMP2)
+                          ELSE
+                              C(J,J) = BETA*DBLE(C(J,J)) +
+     +                                 DBLE(ALPHA*TEMP1+
+     +                                 DCONJG(ALPHA)*TEMP2)
+                          END IF
+                      ELSE
+                          IF (BETA.EQ.DBLE(ZERO)) THEN
+                              C(I,J) = ALPHA*TEMP1 + DCONJG(ALPHA)*TEMP2
+                          ELSE
+                              C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                                 DCONJG(ALPHA)*TEMP2
+                          END IF
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 220 L = 1,K
+                          TEMP1 = TEMP1 + DCONJG(A(L,I))*B(L,J)
+                          TEMP2 = TEMP2 + DCONJG(B(L,I))*A(L,J)
+  220                 CONTINUE
+                      IF (I.EQ.J) THEN
+                          IF (BETA.EQ.DBLE(ZERO)) THEN
+                              C(J,J) = DBLE(ALPHA*TEMP1+
+     +                                 DCONJG(ALPHA)*TEMP2)
+                          ELSE
+                              C(J,J) = BETA*DBLE(C(J,J)) +
+     +                                 DBLE(ALPHA*TEMP1+
+     +                                 DCONJG(ALPHA)*TEMP2)
+                          END IF
+                      ELSE
+                          IF (BETA.EQ.DBLE(ZERO)) THEN
+                              C(I,J) = ALPHA*TEMP1 + DCONJG(ALPHA)*TEMP2
+                          ELSE
+                              C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                                 DCONJG(ALPHA)*TEMP2
+                          END IF
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHER2K.
+*
+      END
diff --git a/superlu/BLAS/zherk.f b/superlu/BLAS/zherk.f
new file mode 100644
index 0000000..d181ca0
--- /dev/null
+++ b/superlu/BLAS/zherk.f
@@ -0,0 +1,396 @@
+*> \brief \b ZHERK
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHERK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA,BETA
+*       INTEGER K,LDA,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHERK  performs one of the hermitian rank k operations
+*>
+*>    C := alpha*A*A**H + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**H*A + beta*C,
+*>
+*> where  alpha and beta  are  real scalars,  C is an  n by n  hermitian
+*> matrix and  A  is an  n by k  matrix in the  first case and a  k by n
+*> matrix in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   C := alpha*A*A**H + beta*C.
+*>
+*>              TRANS = 'C' or 'c'   C := alpha*A**H*A + beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns   of  the   matrix   A,   and  on   entry   with
+*>           TRANS = 'C' or 'c',  K  specifies  the number of rows of the
+*>           matrix A.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION .
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is DOUBLE PRECISION.
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX*16 array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  hermitian matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  hermitian matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set,  they are assumed to be zero,  and on exit they
+*>           are set to zero.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*>
+*>  -- Modified 8-Nov-93 to set C(J,J) to DBLE( C(J,J) ) when BETA = 1.
+*>     Ed Anderson, Cray Research Inc.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHERK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCMPLX,DCONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      DOUBLE PRECISION RTEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      DOUBLE PRECISION ONE,ZERO
+      PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'C'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHERK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+                      C(J,J) = BETA*DBLE(C(J,J))
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      C(J,J) = BETA*DBLE(C(J,J))
+                      DO 70 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*A**H + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J - 1
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                      C(J,J) = BETA*DBLE(C(J,J))
+                  ELSE
+                      C(J,J) = DBLE(C(J,J))
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.DCMPLX(ZERO)) THEN
+                          TEMP = ALPHA*DCONJG(A(J,L))
+                          DO 110 I = 1,J - 1
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                          C(J,J) = DBLE(C(J,J)) + DBLE(TEMP*A(I,L))
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      C(J,J) = BETA*DBLE(C(J,J))
+                      DO 150 I = J + 1,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  ELSE
+                      C(J,J) = DBLE(C(J,J))
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.DCMPLX(ZERO)) THEN
+                          TEMP = ALPHA*DCONJG(A(J,L))
+                          C(J,J) = DBLE(C(J,J)) + DBLE(TEMP*A(J,L))
+                          DO 160 I = J + 1,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**H*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 220 J = 1,N
+                  DO 200 I = 1,J - 1
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + DCONJG(A(L,I))*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+                  RTEMP = ZERO
+                  DO 210 L = 1,K
+                      RTEMP = RTEMP + DCONJG(A(L,J))*A(L,J)
+  210             CONTINUE
+                  IF (BETA.EQ.ZERO) THEN
+                      C(J,J) = ALPHA*RTEMP
+                  ELSE
+                      C(J,J) = ALPHA*RTEMP + BETA*DBLE(C(J,J))
+                  END IF
+  220         CONTINUE
+          ELSE
+              DO 260 J = 1,N
+                  RTEMP = ZERO
+                  DO 230 L = 1,K
+                      RTEMP = RTEMP + DCONJG(A(L,J))*A(L,J)
+  230             CONTINUE
+                  IF (BETA.EQ.ZERO) THEN
+                      C(J,J) = ALPHA*RTEMP
+                  ELSE
+                      C(J,J) = ALPHA*RTEMP + BETA*DBLE(C(J,J))
+                  END IF
+                  DO 250 I = J + 1,N
+                      TEMP = ZERO
+                      DO 240 L = 1,K
+                          TEMP = TEMP + DCONJG(A(L,I))*A(L,J)
+  240                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  250             CONTINUE
+  260         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHERK .
+*
+      END
diff --git a/superlu/BLAS/zhpmv.f b/superlu/BLAS/zhpmv.f
new file mode 100644
index 0000000..0d5d325
--- /dev/null
+++ b/superlu/BLAS/zhpmv.f
@@ -0,0 +1,338 @@
+*> \brief \b ZHPMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER INCX,INCY,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 AP(*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHPMV  performs the matrix-vector operation
+*>
+*>    y := alpha*A*x + beta*y,
+*>
+*> where alpha and beta are scalars, x and y are n element vectors and
+*> A is an n by n hermitian matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is COMPLEX*16 array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set and are assumed to be zero.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry, BETA specifies the scalar beta. When BETA is
+*>           supplied as zero then Y need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] Y
+*> \verbatim
+*>          Y is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y. On exit, Y is overwritten by the updated
+*>           vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER INCX,INCY,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 AP(*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 6
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHPMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     Set up the start points in  X  and  Y.
+*
+      IF (INCX.GT.0) THEN
+          KX = 1
+      ELSE
+          KX = 1 - (N-1)*INCX
+      END IF
+      IF (INCY.GT.0) THEN
+          KY = 1
+      ELSE
+          KY = 1 - (N-1)*INCY
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+*     First form  y := beta*y.
+*
+      IF (BETA.NE.ONE) THEN
+          IF (INCY.EQ.1) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 10 I = 1,N
+                      Y(I) = ZERO
+   10             CONTINUE
+              ELSE
+                  DO 20 I = 1,N
+                      Y(I) = BETA*Y(I)
+   20             CONTINUE
+              END IF
+          ELSE
+              IY = KY
+              IF (BETA.EQ.ZERO) THEN
+                  DO 30 I = 1,N
+                      Y(IY) = ZERO
+                      IY = IY + INCY
+   30             CONTINUE
+              ELSE
+                  DO 40 I = 1,N
+                      Y(IY) = BETA*Y(IY)
+                      IY = IY + INCY
+   40             CONTINUE
+              END IF
+          END IF
+      END IF
+      IF (ALPHA.EQ.ZERO) RETURN
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  y  when AP contains the upper triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  K = KK
+                  DO 50 I = 1,J - 1
+                      Y(I) = Y(I) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + DCONJG(AP(K))*X(I)
+                      K = K + 1
+   50             CONTINUE
+                  Y(J) = Y(J) + TEMP1*DBLE(AP(KK+J-1)) + ALPHA*TEMP2
+                  KK = KK + J
+   60         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 80 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  IX = KX
+                  IY = KY
+                  DO 70 K = KK,KK + J - 2
+                      Y(IY) = Y(IY) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + DCONJG(AP(K))*X(IX)
+                      IX = IX + INCX
+                      IY = IY + INCY
+   70             CONTINUE
+                  Y(JY) = Y(JY) + TEMP1*DBLE(AP(KK+J-1)) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + J
+   80         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  y  when AP contains the lower triangle.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 100 J = 1,N
+                  TEMP1 = ALPHA*X(J)
+                  TEMP2 = ZERO
+                  Y(J) = Y(J) + TEMP1*DBLE(AP(KK))
+                  K = KK + 1
+                  DO 90 I = J + 1,N
+                      Y(I) = Y(I) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + DCONJG(AP(K))*X(I)
+                      K = K + 1
+   90             CONTINUE
+                  Y(J) = Y(J) + ALPHA*TEMP2
+                  KK = KK + (N-J+1)
+  100         CONTINUE
+          ELSE
+              JX = KX
+              JY = KY
+              DO 120 J = 1,N
+                  TEMP1 = ALPHA*X(JX)
+                  TEMP2 = ZERO
+                  Y(JY) = Y(JY) + TEMP1*DBLE(AP(KK))
+                  IX = JX
+                  IY = JY
+                  DO 110 K = KK + 1,KK + N - J
+                      IX = IX + INCX
+                      IY = IY + INCY
+                      Y(IY) = Y(IY) + TEMP1*AP(K)
+                      TEMP2 = TEMP2 + DCONJG(AP(K))*X(IX)
+  110             CONTINUE
+                  Y(JY) = Y(JY) + ALPHA*TEMP2
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + (N-J+1)
+  120         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHPMV .
+*
+      END
diff --git a/superlu/BLAS/zhpr.f b/superlu/BLAS/zhpr.f
new file mode 100644
index 0000000..70051c8
--- /dev/null
+++ b/superlu/BLAS/zhpr.f
@@ -0,0 +1,279 @@
+*> \brief \b ZHPR
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHPR(UPLO,N,ALPHA,X,INCX,AP)
+*
+*       .. Scalar Arguments ..
+*       DOUBLE PRECISION ALPHA
+*       INTEGER INCX,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHPR    performs the hermitian rank 1 operation
+*>
+*>    A := alpha*x*x**H + A,
+*>
+*> where alpha is a real scalar, x is an n element vector and A is an
+*> n by n hermitian matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is DOUBLE PRECISION.
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] AP
+*> \verbatim
+*>          AP is COMPLEX*16 array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the upper triangular part of the
+*>           updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the lower triangular part of the
+*>           updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set, they are assumed to be zero, and on exit they
+*>           are set to zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHPR(UPLO,N,ALPHA,X,INCX,AP)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      DOUBLE PRECISION ALPHA
+      INTEGER INCX,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHPR  ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.DBLE(ZERO))) RETURN
+*
+*     Set the start point in X if the increment is not unity.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when upper triangle is stored in AP.
+*
+          IF (INCX.EQ.1) THEN
+              DO 20 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*DCONJG(X(J))
+                      K = KK
+                      DO 10 I = 1,J - 1
+                          AP(K) = AP(K) + X(I)*TEMP
+                          K = K + 1
+   10                 CONTINUE
+                      AP(KK+J-1) = DBLE(AP(KK+J-1)) + DBLE(X(J)*TEMP)
+                  ELSE
+                      AP(KK+J-1) = DBLE(AP(KK+J-1))
+                  END IF
+                  KK = KK + J
+   20         CONTINUE
+          ELSE
+              JX = KX
+              DO 40 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*DCONJG(X(JX))
+                      IX = KX
+                      DO 30 K = KK,KK + J - 2
+                          AP(K) = AP(K) + X(IX)*TEMP
+                          IX = IX + INCX
+   30                 CONTINUE
+                      AP(KK+J-1) = DBLE(AP(KK+J-1)) + DBLE(X(JX)*TEMP)
+                  ELSE
+                      AP(KK+J-1) = DBLE(AP(KK+J-1))
+                  END IF
+                  JX = JX + INCX
+                  KK = KK + J
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when lower triangle is stored in AP.
+*
+          IF (INCX.EQ.1) THEN
+              DO 60 J = 1,N
+                  IF (X(J).NE.ZERO) THEN
+                      TEMP = ALPHA*DCONJG(X(J))
+                      AP(KK) = DBLE(AP(KK)) + DBLE(TEMP*X(J))
+                      K = KK + 1
+                      DO 50 I = J + 1,N
+                          AP(K) = AP(K) + X(I)*TEMP
+                          K = K + 1
+   50                 CONTINUE
+                  ELSE
+                      AP(KK) = DBLE(AP(KK))
+                  END IF
+                  KK = KK + N - J + 1
+   60         CONTINUE
+          ELSE
+              JX = KX
+              DO 80 J = 1,N
+                  IF (X(JX).NE.ZERO) THEN
+                      TEMP = ALPHA*DCONJG(X(JX))
+                      AP(KK) = DBLE(AP(KK)) + DBLE(TEMP*X(JX))
+                      IX = JX
+                      DO 70 K = KK + 1,KK + N - J
+                          IX = IX + INCX
+                          AP(K) = AP(K) + X(IX)*TEMP
+   70                 CONTINUE
+                  ELSE
+                      AP(KK) = DBLE(AP(KK))
+                  END IF
+                  JX = JX + INCX
+                  KK = KK + N - J + 1
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHPR  .
+*
+      END
diff --git a/superlu/BLAS/zhpr2.f b/superlu/BLAS/zhpr2.f
new file mode 100644
index 0000000..c9fb758
--- /dev/null
+++ b/superlu/BLAS/zhpr2.f
@@ -0,0 +1,318 @@
+*> \brief \b ZHPR2
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZHPR2(UPLO,N,ALPHA,X,INCX,Y,INCY,AP)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA
+*       INTEGER INCX,INCY,N
+*       CHARACTER UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 AP(*),X(*),Y(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZHPR2  performs the hermitian rank 2 operation
+*>
+*>    A := alpha*x*y**H + conjg( alpha )*y*x**H + A,
+*>
+*> where alpha is a scalar, x and y are n element vectors and A is an
+*> n by n hermitian matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the upper or lower
+*>           triangular part of the matrix A is supplied in the packed
+*>           array AP as follows:
+*>
+*>              UPLO = 'U' or 'u'   The upper triangular part of A is
+*>                                  supplied in AP.
+*>
+*>              UPLO = 'L' or 'l'   The lower triangular part of A is
+*>                                  supplied in AP.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*>
+*> \param[in] Y
+*> \verbatim
+*>          Y is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCY ) ).
+*>           Before entry, the incremented array Y must contain the n
+*>           element vector y.
+*> \endverbatim
+*>
+*> \param[in] INCY
+*> \verbatim
+*>          INCY is INTEGER
+*>           On entry, INCY specifies the increment for the elements of
+*>           Y. INCY must not be zero.
+*> \endverbatim
+*>
+*> \param[in,out] AP
+*> \verbatim
+*>          AP is COMPLEX*16 array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )
+*>           and a( 2, 2 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the upper triangular part of the
+*>           updated matrix.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular part of the hermitian matrix
+*>           packed sequentially, column by column, so that AP( 1 )
+*>           contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )
+*>           and a( 3, 1 ) respectively, and so on. On exit, the array
+*>           AP is overwritten by the lower triangular part of the
+*>           updated matrix.
+*>           Note that the imaginary parts of the diagonal elements need
+*>           not be set, they are assumed to be zero, and on exit they
+*>           are set to zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZHPR2(UPLO,N,ALPHA,X,INCX,Y,INCY,AP)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA
+      INTEGER INCX,INCY,N
+      CHARACTER UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 AP(*),X(*),Y(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP1,TEMP2
+      INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DBLE,DCONJG
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (N.LT.0) THEN
+          INFO = 2
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 5
+      ELSE IF (INCY.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZHPR2 ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (ALPHA.EQ.ZERO)) RETURN
+*
+*     Set up the start points in X and Y if the increments are not both
+*     unity.
+*
+      IF ((INCX.NE.1) .OR. (INCY.NE.1)) THEN
+          IF (INCX.GT.0) THEN
+              KX = 1
+          ELSE
+              KX = 1 - (N-1)*INCX
+          END IF
+          IF (INCY.GT.0) THEN
+              KY = 1
+          ELSE
+              KY = 1 - (N-1)*INCY
+          END IF
+          JX = KX
+          JY = KY
+      END IF
+*
+*     Start the operations. In this version the elements of the array AP
+*     are accessed sequentially with one pass through AP.
+*
+      KK = 1
+      IF (LSAME(UPLO,'U')) THEN
+*
+*        Form  A  when upper triangle is stored in AP.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 20 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*DCONJG(Y(J))
+                      TEMP2 = DCONJG(ALPHA*X(J))
+                      K = KK
+                      DO 10 I = 1,J - 1
+                          AP(K) = AP(K) + X(I)*TEMP1 + Y(I)*TEMP2
+                          K = K + 1
+   10                 CONTINUE
+                      AP(KK+J-1) = DBLE(AP(KK+J-1)) +
+     +                             DBLE(X(J)*TEMP1+Y(J)*TEMP2)
+                  ELSE
+                      AP(KK+J-1) = DBLE(AP(KK+J-1))
+                  END IF
+                  KK = KK + J
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*DCONJG(Y(JY))
+                      TEMP2 = DCONJG(ALPHA*X(JX))
+                      IX = KX
+                      IY = KY
+                      DO 30 K = KK,KK + J - 2
+                          AP(K) = AP(K) + X(IX)*TEMP1 + Y(IY)*TEMP2
+                          IX = IX + INCX
+                          IY = IY + INCY
+   30                 CONTINUE
+                      AP(KK+J-1) = DBLE(AP(KK+J-1)) +
+     +                             DBLE(X(JX)*TEMP1+Y(JY)*TEMP2)
+                  ELSE
+                      AP(KK+J-1) = DBLE(AP(KK+J-1))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + J
+   40         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  A  when lower triangle is stored in AP.
+*
+          IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN
+              DO 60 J = 1,N
+                  IF ((X(J).NE.ZERO) .OR. (Y(J).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*DCONJG(Y(J))
+                      TEMP2 = DCONJG(ALPHA*X(J))
+                      AP(KK) = DBLE(AP(KK)) +
+     +                         DBLE(X(J)*TEMP1+Y(J)*TEMP2)
+                      K = KK + 1
+                      DO 50 I = J + 1,N
+                          AP(K) = AP(K) + X(I)*TEMP1 + Y(I)*TEMP2
+                          K = K + 1
+   50                 CONTINUE
+                  ELSE
+                      AP(KK) = DBLE(AP(KK))
+                  END IF
+                  KK = KK + N - J + 1
+   60         CONTINUE
+          ELSE
+              DO 80 J = 1,N
+                  IF ((X(JX).NE.ZERO) .OR. (Y(JY).NE.ZERO)) THEN
+                      TEMP1 = ALPHA*DCONJG(Y(JY))
+                      TEMP2 = DCONJG(ALPHA*X(JX))
+                      AP(KK) = DBLE(AP(KK)) +
+     +                         DBLE(X(JX)*TEMP1+Y(JY)*TEMP2)
+                      IX = JX
+                      IY = JY
+                      DO 70 K = KK + 1,KK + N - J
+                          IX = IX + INCX
+                          IY = IY + INCY
+                          AP(K) = AP(K) + X(IX)*TEMP1 + Y(IY)*TEMP2
+   70                 CONTINUE
+                  ELSE
+                      AP(KK) = DBLE(AP(KK))
+                  END IF
+                  JX = JX + INCX
+                  JY = JY + INCY
+                  KK = KK + N - J + 1
+   80         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZHPR2 .
+*
+      END
diff --git a/superlu/BLAS/zrotg.f b/superlu/BLAS/zrotg.f
new file mode 100644
index 0000000..e5c406d
--- /dev/null
+++ b/superlu/BLAS/zrotg.f
@@ -0,0 +1,75 @@
+*> \brief \b ZROTG
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZROTG(CA,CB,C,S)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 CA,CB,S
+*       DOUBLE PRECISION C
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    ZROTG determines a double complex Givens rotation.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level1
+*
+*  =====================================================================
+      SUBROUTINE ZROTG(CA,CB,C,S)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 CA,CB,S
+      DOUBLE PRECISION C
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      COMPLEX*16 ALPHA
+      DOUBLE PRECISION NORM,SCALE
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC CDABS,DCMPLX,DCONJG,DSQRT
+*     ..
+      IF (CDABS(CA).EQ.0.0d0) THEN
+         C = 0.0d0
+         S = (1.0d0,0.0d0)
+         CA = CB
+      ELSE
+         SCALE = CDABS(CA) + CDABS(CB)
+         NORM = SCALE*DSQRT((CDABS(CA/DCMPLX(SCALE,0.0d0)))**2+
+     $       (CDABS(CB/DCMPLX(SCALE,0.0d0)))**2)
+         ALPHA = CA/CDABS(CA)
+         C = CDABS(CA)/NORM
+         S = ALPHA*DCONJG(CB)/NORM
+         CA = ALPHA*NORM
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/zscal.f b/superlu/BLAS/zscal.f
new file mode 100644
index 0000000..ca038aa
--- /dev/null
+++ b/superlu/BLAS/zscal.f
@@ -0,0 +1,91 @@
+*> \brief \b ZSCAL
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZSCAL(N,ZA,ZX,INCX)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ZA
+*       INTEGER INCX,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 ZX(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    ZSCAL scales a vector by a constant.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, 3/11/78.
+*>     modified 3/93 to return if incx .le. 0.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZSCAL(N,ZA,ZX,INCX)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ZA
+      INTEGER INCX,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 ZX(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      INTEGER I,NINCX
+*     ..
+      IF (N.LE.0 .OR. INCX.LE.0) RETURN
+      IF (INCX.EQ.1) THEN
+*
+*        code for increment equal to 1
+*
+         DO I = 1,N
+            ZX(I) = ZA*ZX(I)
+         END DO
+      ELSE
+*
+*        code for increment not equal to 1
+*
+         NINCX = N*INCX
+         DO I = 1,NINCX,INCX
+            ZX(I) = ZA*ZX(I)
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/zswap.f b/superlu/BLAS/zswap.f
new file mode 100644
index 0000000..02a5b97
--- /dev/null
+++ b/superlu/BLAS/zswap.f
@@ -0,0 +1,98 @@
+*> \brief \b ZSWAP
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZSWAP(N,ZX,INCX,ZY,INCY)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,INCY,N
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 ZX(*),ZY(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*>    ZSWAP interchanges two vectors.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level1
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>     jack dongarra, 3/11/78.
+*>     modified 12/3/93, array(1) declarations changed to array(*)
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZSWAP(N,ZX,INCX,ZY,INCY)
+*
+*  -- Reference BLAS level1 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,INCY,N
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 ZX(*),ZY(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Local Scalars ..
+      COMPLEX*16 ZTEMP
+      INTEGER I,IX,IY
+*     ..
+      IF (N.LE.0) RETURN
+      IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN
+*
+*       code for both increments equal to 1
+         DO I = 1,N
+            ZTEMP = ZX(I)
+            ZX(I) = ZY(I)
+            ZY(I) = ZTEMP
+         END DO
+      ELSE
+*
+*       code for unequal increments or equal increments not equal
+*         to 1
+*
+         IX = 1
+         IY = 1
+         IF (INCX.LT.0) IX = (-N+1)*INCX + 1
+         IF (INCY.LT.0) IY = (-N+1)*INCY + 1
+         DO I = 1,N
+            ZTEMP = ZX(IX)
+            ZX(IX) = ZY(IY)
+            ZY(IY) = ZTEMP
+            IX = IX + INCX
+            IY = IY + INCY
+         END DO
+      END IF
+      RETURN
+      END
diff --git a/superlu/BLAS/zsymm.f b/superlu/BLAS/zsymm.f
new file mode 100644
index 0000000..1dc267a
--- /dev/null
+++ b/superlu/BLAS/zsymm.f
@@ -0,0 +1,369 @@
+*> \brief \b ZSYMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER LDA,LDB,LDC,M,N
+*       CHARACTER SIDE,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZSYMM  performs one of the matrix-matrix operations
+*>
+*>    C := alpha*A*B + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*B*A + beta*C,
+*>
+*> where  alpha and beta are scalars, A is a symmetric matrix and  B and
+*> C are m by n matrices.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE  specifies whether  the  symmetric matrix  A
+*>           appears on the  left or right  in the  operation as follows:
+*>
+*>              SIDE = 'L' or 'l'   C := alpha*A*B + beta*C,
+*>
+*>              SIDE = 'R' or 'r'   C := alpha*B*A + beta*C,
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of  the  symmetric  matrix   A  is  to  be
+*>           referenced as follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the upper triangular part of the
+*>                                  symmetric matrix is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the lower triangular part of the
+*>                                  symmetric matrix is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry,  M  specifies the number of rows of the matrix  C.
+*>           M  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of the matrix C.
+*>           N  must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, ka ), where ka is
+*>           m  when  SIDE = 'L' or 'l'  and is n  otherwise.
+*>           Before entry  with  SIDE = 'L' or 'l',  the  m by m  part of
+*>           the array  A  must contain the  symmetric matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading m by m upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  symmetric matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  m by m  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  symmetric
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*>           Before entry  with  SIDE = 'R' or 'r',  the  n by n  part of
+*>           the array  A  must contain the  symmetric matrix,  such that
+*>           when  UPLO = 'U' or 'u', the leading n by n upper triangular
+*>           part of the array  A  must contain the upper triangular part
+*>           of the  symmetric matrix and the  strictly  lower triangular
+*>           part of  A  is not referenced,  and when  UPLO = 'L' or 'l',
+*>           the leading  n by n  lower triangular part  of the  array  A
+*>           must  contain  the  lower triangular part  of the  symmetric
+*>           matrix and the  strictly upper triangular part of  A  is not
+*>           referenced.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the  calling (sub) program. When  SIDE = 'L' or 'l'  then
+*>           LDA must be at least  max( 1, m ), otherwise  LDA must be at
+*>           least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX*16 array of DIMENSION ( LDB, n ).
+*>           Before entry, the leading  m by n part of the array  B  must
+*>           contain the matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry,  BETA  specifies the scalar  beta.  When  BETA  is
+*>           supplied as zero then C need not be set on input.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX*16 array of DIMENSION ( LDC, n ).
+*>           Before entry, the leading  m by n  part of the array  C must
+*>           contain the matrix  C,  except when  beta  is zero, in which
+*>           case C need not be set on entry.
+*>           On exit, the array  C  is overwritten by the  m by n updated
+*>           matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZSYMM(SIDE,UPLO,M,N,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER LDA,LDB,LDC,M,N
+      CHARACTER SIDE,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP1,TEMP2
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Set NROWA as the number of rows of A.
+*
+      IF (LSAME(SIDE,'L')) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF ((.NOT.LSAME(SIDE,'L')) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF (M.LT.0) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,M)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZSYMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((M.EQ.0) .OR. (N.EQ.0) .OR.
+     +    ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (BETA.EQ.ZERO) THEN
+              DO 20 J = 1,N
+                  DO 10 I = 1,M
+                      C(I,J) = ZERO
+   10             CONTINUE
+   20         CONTINUE
+          ELSE
+              DO 40 J = 1,N
+                  DO 30 I = 1,M
+                      C(I,J) = BETA*C(I,J)
+   30             CONTINUE
+   40         CONTINUE
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(SIDE,'L')) THEN
+*
+*        Form  C := alpha*A*B + beta*C.
+*
+          IF (UPPER) THEN
+              DO 70 J = 1,N
+                  DO 60 I = 1,M
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 50 K = 1,I - 1
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   50                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   60             CONTINUE
+   70         CONTINUE
+          ELSE
+              DO 100 J = 1,N
+                  DO 90 I = M,1,-1
+                      TEMP1 = ALPHA*B(I,J)
+                      TEMP2 = ZERO
+                      DO 80 K = I + 1,M
+                          C(K,J) = C(K,J) + TEMP1*A(K,I)
+                          TEMP2 = TEMP2 + B(K,J)*A(K,I)
+   80                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = TEMP1*A(I,I) + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + TEMP1*A(I,I) +
+     +                             ALPHA*TEMP2
+                      END IF
+   90             CONTINUE
+  100         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*B*A + beta*C.
+*
+          DO 170 J = 1,N
+              TEMP1 = ALPHA*A(J,J)
+              IF (BETA.EQ.ZERO) THEN
+                  DO 110 I = 1,M
+                      C(I,J) = TEMP1*B(I,J)
+  110             CONTINUE
+              ELSE
+                  DO 120 I = 1,M
+                      C(I,J) = BETA*C(I,J) + TEMP1*B(I,J)
+  120             CONTINUE
+              END IF
+              DO 140 K = 1,J - 1
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(K,J)
+                  ELSE
+                      TEMP1 = ALPHA*A(J,K)
+                  END IF
+                  DO 130 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  130             CONTINUE
+  140         CONTINUE
+              DO 160 K = J + 1,N
+                  IF (UPPER) THEN
+                      TEMP1 = ALPHA*A(J,K)
+                  ELSE
+                      TEMP1 = ALPHA*A(K,J)
+                  END IF
+                  DO 150 I = 1,M
+                      C(I,J) = C(I,J) + TEMP1*B(I,K)
+  150             CONTINUE
+  160         CONTINUE
+  170     CONTINUE
+      END IF
+*
+      RETURN
+*
+*     End of ZSYMM .
+*
+      END
diff --git a/superlu/BLAS/zsyr2k.f b/superlu/BLAS/zsyr2k.f
new file mode 100644
index 0000000..d358ed0
--- /dev/null
+++ b/superlu/BLAS/zsyr2k.f
@@ -0,0 +1,396 @@
+*> \brief \b ZSYR2K
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZSYR2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER K,LDA,LDB,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZSYR2K  performs one of the symmetric rank 2k operations
+*>
+*>    C := alpha*A*B**T + alpha*B*A**T + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**T*B + alpha*B**T*A + beta*C,
+*>
+*> where  alpha and beta  are scalars,  C is an  n by n symmetric matrix
+*> and  A and B  are  n by k  matrices  in the  first  case  and  k by n
+*> matrices in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'    C := alpha*A*B**T + alpha*B*A**T +
+*>                                         beta*C.
+*>
+*>              TRANS = 'T' or 't'    C := alpha*A**T*B + alpha*B**T*A +
+*>                                         beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns  of the  matrices  A and B,  and on  entry  with
+*>           TRANS = 'T' or 't',  K  specifies  the number of rows of the
+*>           matrices  A and B.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is COMPLEX*16 array of DIMENSION ( LDB, kb ), where kb is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  B  must contain the matrix  B,  otherwise
+*>           the leading  k by n  part of the array  B  must contain  the
+*>           matrix B.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDB must be at least  max( 1, n ), otherwise  LDB must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX*16 array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZSYR2K(UPLO,TRANS,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER K,LDA,LDB,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),B(LDB,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP1,TEMP2
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDB.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 12
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZSYR2K',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*B**T + alpha*B*A**T + C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF ((A(J,L).NE.ZERO) .OR. (B(J,L).NE.ZERO)) THEN
+                          TEMP1 = ALPHA*B(J,L)
+                          TEMP2 = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + A(I,L)*TEMP1 +
+     +                                 B(I,L)*TEMP2
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**T*B + alpha*B**T*A + C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 190 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP1 = ZERO
+                      TEMP2 = ZERO
+                      DO 220 L = 1,K
+                          TEMP1 = TEMP1 + A(L,I)*B(L,J)
+                          TEMP2 = TEMP2 + B(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP1 + ALPHA*TEMP2
+                      ELSE
+                          C(I,J) = BETA*C(I,J) + ALPHA*TEMP1 +
+     +                             ALPHA*TEMP2
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZSYR2K.
+*
+      END
diff --git a/superlu/BLAS/zsyrk.f b/superlu/BLAS/zsyrk.f
new file mode 100644
index 0000000..79591b4
--- /dev/null
+++ b/superlu/BLAS/zsyrk.f
@@ -0,0 +1,363 @@
+*> \brief \b ZSYRK
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA,BETA
+*       INTEGER K,LDA,LDC,N
+*       CHARACTER TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),C(LDC,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZSYRK  performs one of the symmetric rank k operations
+*>
+*>    C := alpha*A*A**T + beta*C,
+*>
+*> or
+*>
+*>    C := alpha*A**T*A + beta*C,
+*>
+*> where  alpha and beta  are scalars,  C is an  n by n symmetric matrix
+*> and  A  is an  n by k  matrix in the first case and a  k by n  matrix
+*> in the second case.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On  entry,   UPLO  specifies  whether  the  upper  or  lower
+*>           triangular  part  of the  array  C  is to be  referenced  as
+*>           follows:
+*>
+*>              UPLO = 'U' or 'u'   Only the  upper triangular part of  C
+*>                                  is to be referenced.
+*>
+*>              UPLO = 'L' or 'l'   Only the  lower triangular part of  C
+*>                                  is to be referenced.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry,  TRANS  specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   C := alpha*A*A**T + beta*C.
+*>
+*>              TRANS = 'T' or 't'   C := alpha*A**T*A + beta*C.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry,  N specifies the order of the matrix C.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with  TRANS = 'N' or 'n',  K  specifies  the number
+*>           of  columns   of  the   matrix   A,   and  on   entry   with
+*>           TRANS = 'T' or 't',  K  specifies  the number of rows of the
+*>           matrix A.  K must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry, ALPHA specifies the scalar alpha.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, ka ), where ka is
+*>           k  when  TRANS = 'N' or 'n',  and is  n  otherwise.
+*>           Before entry with  TRANS = 'N' or 'n',  the  leading  n by k
+*>           part of the array  A  must contain the matrix  A,  otherwise
+*>           the leading  k by n  part of the array  A  must contain  the
+*>           matrix A.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in  the  calling  (sub)  program.   When  TRANS = 'N' or 'n'
+*>           then  LDA must be at least  max( 1, n ), otherwise  LDA must
+*>           be at least  max( 1, k ).
+*> \endverbatim
+*>
+*> \param[in] BETA
+*> \verbatim
+*>          BETA is COMPLEX*16
+*>           On entry, BETA specifies the scalar beta.
+*> \endverbatim
+*>
+*> \param[in,out] C
+*> \verbatim
+*>          C is COMPLEX*16 array of DIMENSION ( LDC, n ).
+*>           Before entry  with  UPLO = 'U' or 'u',  the leading  n by n
+*>           upper triangular part of the array C must contain the upper
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           lower triangular part of C is not referenced.  On exit, the
+*>           upper triangular part of the array  C is overwritten by the
+*>           upper triangular part of the updated matrix.
+*>           Before entry  with  UPLO = 'L' or 'l',  the leading  n by n
+*>           lower triangular part of the array C must contain the lower
+*>           triangular part  of the  symmetric matrix  and the strictly
+*>           upper triangular part of C is not referenced.  On exit, the
+*>           lower triangular part of the array  C is overwritten by the
+*>           lower triangular part of the updated matrix.
+*> \endverbatim
+*>
+*> \param[in] LDC
+*> \verbatim
+*>          LDC is INTEGER
+*>           On entry, LDC specifies the first dimension of C as declared
+*>           in  the  calling  (sub)  program.   LDC  must  be  at  least
+*>           max( 1, n ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZSYRK(UPLO,TRANS,N,K,ALPHA,A,LDA,BETA,C,LDC)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA,BETA
+      INTEGER K,LDA,LDC,N
+      CHARACTER TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),C(LDC,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,J,L,NROWA
+      LOGICAL UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      IF (LSAME(TRANS,'N')) THEN
+          NROWA = N
+      ELSE
+          NROWA = K
+      END IF
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.LSAME(TRANS,'N')) .AND.
+     +         (.NOT.LSAME(TRANS,'T'))) THEN
+          INFO = 2
+      ELSE IF (N.LT.0) THEN
+          INFO = 3
+      ELSE IF (K.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 7
+      ELSE IF (LDC.LT.MAX(1,N)) THEN
+          INFO = 10
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZSYRK ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF ((N.EQ.0) .OR. (((ALPHA.EQ.ZERO).OR.
+     +    (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          IF (UPPER) THEN
+              IF (BETA.EQ.ZERO) THEN
+                  DO 20 J = 1,N
+                      DO 10 I = 1,J
+                          C(I,J) = ZERO
+   10                 CONTINUE
+   20             CONTINUE
+              ELSE
+                  DO 40 J = 1,N
+                      DO 30 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+   30                 CONTINUE
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (BETA.EQ.ZERO) THEN
+                  DO 60 J = 1,N
+                      DO 50 I = J,N
+                          C(I,J) = ZERO
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 I = J,N
+                          C(I,J) = BETA*C(I,J)
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          END IF
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  C := alpha*A*A**T + beta*C.
+*
+          IF (UPPER) THEN
+              DO 130 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 90 I = 1,J
+                          C(I,J) = ZERO
+   90                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 100 I = 1,J
+                          C(I,J) = BETA*C(I,J)
+  100                 CONTINUE
+                  END IF
+                  DO 120 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 110 I = 1,J
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  110                     CONTINUE
+                      END IF
+  120             CONTINUE
+  130         CONTINUE
+          ELSE
+              DO 180 J = 1,N
+                  IF (BETA.EQ.ZERO) THEN
+                      DO 140 I = J,N
+                          C(I,J) = ZERO
+  140                 CONTINUE
+                  ELSE IF (BETA.NE.ONE) THEN
+                      DO 150 I = J,N
+                          C(I,J) = BETA*C(I,J)
+  150                 CONTINUE
+                  END IF
+                  DO 170 L = 1,K
+                      IF (A(J,L).NE.ZERO) THEN
+                          TEMP = ALPHA*A(J,L)
+                          DO 160 I = J,N
+                              C(I,J) = C(I,J) + TEMP*A(I,L)
+  160                     CONTINUE
+                      END IF
+  170             CONTINUE
+  180         CONTINUE
+          END IF
+      ELSE
+*
+*        Form  C := alpha*A**T*A + beta*C.
+*
+          IF (UPPER) THEN
+              DO 210 J = 1,N
+                  DO 200 I = 1,J
+                      TEMP = ZERO
+                      DO 190 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  190                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  200             CONTINUE
+  210         CONTINUE
+          ELSE
+              DO 240 J = 1,N
+                  DO 230 I = J,N
+                      TEMP = ZERO
+                      DO 220 L = 1,K
+                          TEMP = TEMP + A(L,I)*A(L,J)
+  220                 CONTINUE
+                      IF (BETA.EQ.ZERO) THEN
+                          C(I,J) = ALPHA*TEMP
+                      ELSE
+                          C(I,J) = ALPHA*TEMP + BETA*C(I,J)
+                      END IF
+  230             CONTINUE
+  240         CONTINUE
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZSYRK .
+*
+      END
diff --git a/superlu/BLAS/ztbmv.f b/superlu/BLAS/ztbmv.f
new file mode 100644
index 0000000..1e03f2b
--- /dev/null
+++ b/superlu/BLAS/ztbmv.f
@@ -0,0 +1,429 @@
+*> \brief \b ZTBMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZTBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,K,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZTBMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,   or   x := A**H*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular band matrix, with ( k + 1 ) diagonals.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**H*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with UPLO = 'U' or 'u', K specifies the number of
+*>           super-diagonals of the matrix A.
+*>           On entry with UPLO = 'L' or 'l', K specifies the number of
+*>           sub-diagonals of the matrix A.
+*>           K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer an upper
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer a lower
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that when DIAG = 'U' or 'u' the elements of the array A
+*>           corresponding to the diagonal elements of the matrix are not
+*>           referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is (input/output) COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZTBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZTBMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX   too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*         Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          L = KPLUS1 - J
+                          DO 10 I = MAX(1,J-K),J - 1
+                              X(I) = X(I) + TEMP*A(L+I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(KPLUS1,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          L = KPLUS1 - J
+                          DO 30 I = MAX(1,J-K),J - 1
+                              X(IX) = X(IX) + TEMP*A(L+I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(KPLUS1,J)
+                      END IF
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          L = 1 - J
+                          DO 50 I = MIN(N,J+K),J + 1,-1
+                              X(I) = X(I) + TEMP*A(L+I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(1,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          L = 1 - J
+                          DO 70 I = MIN(N,J+K),J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(L+I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(1,J)
+                      END IF
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x  or  x := A**H*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = N,1,-1
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)
+                          DO 90 I = J - 1,MAX(1,J-K),-1
+                              TEMP = TEMP + A(L+I,J)*X(I)
+   90                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(A(KPLUS1,J))
+                          DO 100 I = J - 1,MAX(1,J-K),-1
+                              TEMP = TEMP + DCONJG(A(L+I,J))*X(I)
+  100                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 140 J = N,1,-1
+                      TEMP = X(JX)
+                      KX = KX - INCX
+                      IX = KX
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)
+                          DO 120 I = J - 1,MAX(1,J-K),-1
+                              TEMP = TEMP + A(L+I,J)*X(IX)
+                              IX = IX - INCX
+  120                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(A(KPLUS1,J))
+                          DO 130 I = J - 1,MAX(1,J-K),-1
+                              TEMP = TEMP + DCONJG(A(L+I,J))*X(IX)
+                              IX = IX - INCX
+  130                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = 1,N
+                      TEMP = X(J)
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(1,J)
+                          DO 150 I = J + 1,MIN(N,J+K)
+                              TEMP = TEMP + A(L+I,J)*X(I)
+  150                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(A(1,J))
+                          DO 160 I = J + 1,MIN(N,J+K)
+                              TEMP = TEMP + DCONJG(A(L+I,J))*X(I)
+  160                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 200 J = 1,N
+                      TEMP = X(JX)
+                      KX = KX + INCX
+                      IX = KX
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(1,J)
+                          DO 180 I = J + 1,MIN(N,J+K)
+                              TEMP = TEMP + A(L+I,J)*X(IX)
+                              IX = IX + INCX
+  180                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(A(1,J))
+                          DO 190 I = J + 1,MIN(N,J+K)
+                              TEMP = TEMP + DCONJG(A(L+I,J))*X(IX)
+                              IX = IX + INCX
+  190                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTBMV .
+*
+      END
diff --git a/superlu/BLAS/ztbsv.f b/superlu/BLAS/ztbsv.f
new file mode 100644
index 0000000..50c4bb4
--- /dev/null
+++ b/superlu/BLAS/ztbsv.f
@@ -0,0 +1,432 @@
+*> \brief \b ZTBSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZTBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,K,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZTBSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,   or   A**H*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular band matrix, with ( k + 1 )
+*> diagonals.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**H*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] K
+*> \verbatim
+*>          K is INTEGER
+*>           On entry with UPLO = 'U' or 'u', K specifies the number of
+*>           super-diagonals of the matrix A.
+*>           On entry with UPLO = 'L' or 'l', K specifies the number of
+*>           sub-diagonals of the matrix A.
+*>           K must satisfy  0 .le. K.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )
+*>           by n part of the array A must contain the upper triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row
+*>           ( k + 1 ) of the array, the first super-diagonal starting at
+*>           position 2 in row k, and so on. The top left k by k triangle
+*>           of the array A is not referenced.
+*>           The following program segment will transfer an upper
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = K + 1 - J
+*>                    DO 10, I = MAX( 1, J - K ), J
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )
+*>           by n part of the array A must contain the lower triangular
+*>           band part of the matrix of coefficients, supplied column by
+*>           column, with the leading diagonal of the matrix in row 1 of
+*>           the array, the first sub-diagonal starting at position 1 in
+*>           row 2, and so on. The bottom right k by k triangle of the
+*>           array A is not referenced.
+*>           The following program segment will transfer a lower
+*>           triangular band matrix from conventional full matrix storage
+*>           to band storage:
+*>
+*>                 DO 20, J = 1, N
+*>                    M = 1 - J
+*>                    DO 10, I = J, MIN( N, J + K )
+*>                       A( M + I, J ) = matrix( I, J )
+*>              10    CONTINUE
+*>              20 CONTINUE
+*>
+*>           Note that when DIAG = 'U' or 'u' the elements of the array A
+*>           corresponding to the diagonal elements of the matrix are not
+*>           referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           ( k + 1 ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZTBSV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,K,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX,MIN
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (K.LT.0) THEN
+          INFO = 5
+      ELSE IF (LDA.LT. (K+1)) THEN
+          INFO = 7
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 9
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZTBSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed by sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(KPLUS1,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,MAX(1,J-K),-1
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 40 J = N,1,-1
+                      KX = KX - INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = KPLUS1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(KPLUS1,J)
+                          TEMP = X(JX)
+                          DO 30 I = J - 1,MAX(1,J-K),-1
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX - INCX
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          L = 1 - J
+                          IF (NOUNIT) X(J) = X(J)/A(1,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,MIN(N,J+K)
+                              X(I) = X(I) - TEMP*A(L+I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      KX = KX + INCX
+                      IF (X(JX).NE.ZERO) THEN
+                          IX = KX
+                          L = 1 - J
+                          IF (NOUNIT) X(JX) = X(JX)/A(1,J)
+                          TEMP = X(JX)
+                          DO 70 I = J + 1,MIN(N,J+K)
+                              X(IX) = X(IX) - TEMP*A(L+I,J)
+                              IX = IX + INCX
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x  or  x := inv( A**H )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KPLUS1 = K + 1
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = 1,N
+                      TEMP = X(J)
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          DO 90 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - A(L+I,J)*X(I)
+   90                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      ELSE
+                          DO 100 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - DCONJG(A(L+I,J))*X(I)
+  100                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(A(KPLUS1,J))
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 140 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      L = KPLUS1 - J
+                      IF (NOCONJ) THEN
+                          DO 120 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - A(L+I,J)*X(IX)
+                              IX = IX + INCX
+  120                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(KPLUS1,J)
+                      ELSE
+                          DO 130 I = MAX(1,J-K),J - 1
+                              TEMP = TEMP - DCONJG(A(L+I,J))*X(IX)
+                              IX = IX + INCX
+  130                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(A(KPLUS1,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      IF (J.GT.K) KX = KX + INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = N,1,-1
+                      TEMP = X(J)
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          DO 150 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - A(L+I,J)*X(I)
+  150                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      ELSE
+                          DO 160 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - DCONJG(A(L+I,J))*X(I)
+  160                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(A(1,J))
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 200 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      L = 1 - J
+                      IF (NOCONJ) THEN
+                          DO 180 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - A(L+I,J)*X(IX)
+                              IX = IX - INCX
+  180                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(1,J)
+                      ELSE
+                          DO 190 I = MIN(N,J+K),J + 1,-1
+                              TEMP = TEMP - DCONJG(A(L+I,J))*X(IX)
+                              IX = IX - INCX
+  190                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(A(1,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      IF ((N-J).GE.K) KX = KX - INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTBSV .
+*
+      END
diff --git a/superlu/BLAS/ztpmv.f b/superlu/BLAS/ztpmv.f
new file mode 100644
index 0000000..d9aae42
--- /dev/null
+++ b/superlu/BLAS/ztpmv.f
@@ -0,0 +1,388 @@
+*> \brief \b ZTPMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZTPMV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZTPMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,   or   x := A**H*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular matrix, supplied in packed form.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**H*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is COMPLEX*16 array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 )
+*>           respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 )
+*>           respectively, and so on.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is (input/output) COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZTPMV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZTPMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of AP are
+*     accessed sequentially with one pass through AP.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x:= A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          K = KK
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*AP(K)
+                              K = K + 1
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*AP(KK+J-1)
+                      END IF
+                      KK = KK + J
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 K = KK,KK + J - 2
+                              X(IX) = X(IX) + TEMP*AP(K)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*AP(KK+J-1)
+                      END IF
+                      JX = JX + INCX
+                      KK = KK + J
+   40             CONTINUE
+              END IF
+          ELSE
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          K = KK
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*AP(K)
+                              K = K - 1
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*AP(KK-N+J)
+                      END IF
+                      KK = KK - (N-J+1)
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 K = KK,KK - (N- (J+1)),-1
+                              X(IX) = X(IX) + TEMP*AP(K)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*AP(KK-N+J)
+                      END IF
+                      JX = JX - INCX
+                      KK = KK - (N-J+1)
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x  or  x := A**H*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = N,1,-1
+                      TEMP = X(J)
+                      K = KK - 1
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*AP(KK)
+                          DO 90 I = J - 1,1,-1
+                              TEMP = TEMP + AP(K)*X(I)
+                              K = K - 1
+   90                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(AP(KK))
+                          DO 100 I = J - 1,1,-1
+                              TEMP = TEMP + DCONJG(AP(K))*X(I)
+                              K = K - 1
+  100                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+                      KK = KK - J
+  110             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 140 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*AP(KK)
+                          DO 120 K = KK - 1,KK - J + 1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + AP(K)*X(IX)
+  120                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(AP(KK))
+                          DO 130 K = KK - 1,KK - J + 1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + DCONJG(AP(K))*X(IX)
+  130                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      KK = KK - J
+  140             CONTINUE
+              END IF
+          ELSE
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = 1,N
+                      TEMP = X(J)
+                      K = KK + 1
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*AP(KK)
+                          DO 150 I = J + 1,N
+                              TEMP = TEMP + AP(K)*X(I)
+                              K = K + 1
+  150                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(AP(KK))
+                          DO 160 I = J + 1,N
+                              TEMP = TEMP + DCONJG(AP(K))*X(I)
+                              K = K + 1
+  160                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+                      KK = KK + (N-J+1)
+  170             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 200 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*AP(KK)
+                          DO 180 K = KK + 1,KK + N - J
+                              IX = IX + INCX
+                              TEMP = TEMP + AP(K)*X(IX)
+  180                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(AP(KK))
+                          DO 190 K = KK + 1,KK + N - J
+                              IX = IX + INCX
+                              TEMP = TEMP + DCONJG(AP(K))*X(IX)
+  190                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      KK = KK + (N-J+1)
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTPMV .
+*
+      END
diff --git a/superlu/BLAS/ztpsv.f b/superlu/BLAS/ztpsv.f
new file mode 100644
index 0000000..5874fdc
--- /dev/null
+++ b/superlu/BLAS/ztpsv.f
@@ -0,0 +1,390 @@
+*> \brief \b ZTPSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZTPSV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 AP(*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZTPSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,   or   A**H*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular matrix, supplied in packed form.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**H*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] AP
+*> \verbatim
+*>          AP is COMPLEX*16 array of DIMENSION at least
+*>           ( ( n*( n + 1 ) )/2 ).
+*>           Before entry with  UPLO = 'U' or 'u', the array AP must
+*>           contain the upper triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 1, 2 ) and a( 2, 2 )
+*>           respectively, and so on.
+*>           Before entry with UPLO = 'L' or 'l', the array AP must
+*>           contain the lower triangular matrix packed sequentially,
+*>           column by column, so that AP( 1 ) contains a( 1, 1 ),
+*>           AP( 2 ) and AP( 3 ) contain a( 2, 1 ) and a( 3, 1 )
+*>           respectively, and so on.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZTPSV(UPLO,TRANS,DIAG,N,AP,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 AP(*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JX,K,KK,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 7
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZTPSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of AP are
+*     accessed sequentially with one pass through AP.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/AP(KK)
+                          TEMP = X(J)
+                          K = KK - 1
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*AP(K)
+                              K = K - 1
+   10                     CONTINUE
+                      END IF
+                      KK = KK - J
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/AP(KK)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 K = KK - 1,KK - J + 1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*AP(K)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+                      KK = KK - J
+   40             CONTINUE
+              END IF
+          ELSE
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/AP(KK)
+                          TEMP = X(J)
+                          K = KK + 1
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*AP(K)
+                              K = K + 1
+   50                     CONTINUE
+                      END IF
+                      KK = KK + (N-J+1)
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/AP(KK)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 K = KK + 1,KK + N - J
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*AP(K)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+                      KK = KK + (N-J+1)
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x  or  x := inv( A**H )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              KK = 1
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = 1,N
+                      TEMP = X(J)
+                      K = KK
+                      IF (NOCONJ) THEN
+                          DO 90 I = 1,J - 1
+                              TEMP = TEMP - AP(K)*X(I)
+                              K = K + 1
+   90                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/AP(KK+J-1)
+                      ELSE
+                          DO 100 I = 1,J - 1
+                              TEMP = TEMP - DCONJG(AP(K))*X(I)
+                              K = K + 1
+  100                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(AP(KK+J-1))
+                      END IF
+                      X(J) = TEMP
+                      KK = KK + J
+  110             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 140 J = 1,N
+                      TEMP = X(JX)
+                      IX = KX
+                      IF (NOCONJ) THEN
+                          DO 120 K = KK,KK + J - 2
+                              TEMP = TEMP - AP(K)*X(IX)
+                              IX = IX + INCX
+  120                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/AP(KK+J-1)
+                      ELSE
+                          DO 130 K = KK,KK + J - 2
+                              TEMP = TEMP - DCONJG(AP(K))*X(IX)
+                              IX = IX + INCX
+  130                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(AP(KK+J-1))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+                      KK = KK + J
+  140             CONTINUE
+              END IF
+          ELSE
+              KK = (N* (N+1))/2
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = N,1,-1
+                      TEMP = X(J)
+                      K = KK
+                      IF (NOCONJ) THEN
+                          DO 150 I = N,J + 1,-1
+                              TEMP = TEMP - AP(K)*X(I)
+                              K = K - 1
+  150                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/AP(KK-N+J)
+                      ELSE
+                          DO 160 I = N,J + 1,-1
+                              TEMP = TEMP - DCONJG(AP(K))*X(I)
+                              K = K - 1
+  160                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(AP(KK-N+J))
+                      END IF
+                      X(J) = TEMP
+                      KK = KK - (N-J+1)
+  170             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 200 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = KX
+                      IF (NOCONJ) THEN
+                          DO 180 K = KK,KK - (N- (J+1)),-1
+                              TEMP = TEMP - AP(K)*X(IX)
+                              IX = IX - INCX
+  180                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/AP(KK-N+J)
+                      ELSE
+                          DO 190 K = KK,KK - (N- (J+1)),-1
+                              TEMP = TEMP - DCONJG(AP(K))*X(IX)
+                              IX = IX - INCX
+  190                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(AP(KK-N+J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+                      KK = KK - (N-J+1)
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTPSV .
+*
+      END
diff --git a/superlu/BLAS/ztrmm.f b/superlu/BLAS/ztrmm.f
new file mode 100644
index 0000000..229f332
--- /dev/null
+++ b/superlu/BLAS/ztrmm.f
@@ -0,0 +1,452 @@
+*> \brief \b ZTRMM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZTRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA
+*       INTEGER LDA,LDB,M,N
+*       CHARACTER DIAG,SIDE,TRANSA,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),B(LDB,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZTRMM  performs one of the matrix-matrix operations
+*>
+*>    B := alpha*op( A )*B,   or   B := alpha*B*op( A )
+*>
+*> where  alpha  is a scalar,  B  is an m by n matrix,  A  is a unit, or
+*> non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*>
+*>    op( A ) = A   or   op( A ) = A**T   or   op( A ) = A**H.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry,  SIDE specifies whether  op( A ) multiplies B from
+*>           the left or right as follows:
+*>
+*>              SIDE = 'L' or 'l'   B := alpha*op( A )*B.
+*>
+*>              SIDE = 'R' or 'r'   B := alpha*B*op( A ).
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix A is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n'   op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't'   op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c'   op( A ) = A**H.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit triangular
+*>           as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of B. M must be at
+*>           least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of B.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*>           zero then  A is not referenced and  B need not be set before
+*>           entry.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, k ), where k is m
+*>           when  SIDE = 'L' or 'l'  and is  n  when  SIDE = 'R' or 'r'.
+*>           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*>           upper triangular part of the array  A must contain the upper
+*>           triangular matrix  and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*>           lower triangular part of the array  A must contain the lower
+*>           triangular matrix  and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*>           A  are not referenced either,  but are assumed to be  unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*>           then LDA must be at least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] B
+*> \verbatim
+*>          B is (input/output) COMPLEX*16 array of DIMENSION ( LDB, n ).
+*>           Before entry,  the leading  m by n part of the array  B must
+*>           contain the matrix  B,  and  on exit  is overwritten  by the
+*>           transformed matrix.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZTRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),B(LDB,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOCONJ,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOCONJ = LSAME(TRANSA,'T')
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZTRMM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*A*B.
+*
+              IF (UPPER) THEN
+                  DO 50 J = 1,N
+                      DO 40 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              DO 30 I = 1,K - 1
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   30                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP*A(K,K)
+                              B(K,J) = TEMP
+                          END IF
+   40                 CONTINUE
+   50             CONTINUE
+              ELSE
+                  DO 80 J = 1,N
+                      DO 70 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*B(K,J)
+                              B(K,J) = TEMP
+                              IF (NOUNIT) B(K,J) = B(K,J)*A(K,K)
+                              DO 60 I = K + 1,M
+                                  B(I,J) = B(I,J) + TEMP*A(I,K)
+   60                         CONTINUE
+                          END IF
+   70                 CONTINUE
+   80             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*A**T*B   or   B := alpha*A**H*B.
+*
+              IF (UPPER) THEN
+                  DO 120 J = 1,N
+                      DO 110 I = M,1,-1
+                          TEMP = B(I,J)
+                          IF (NOCONJ) THEN
+                              IF (NOUNIT) TEMP = TEMP*A(I,I)
+                              DO 90 K = 1,I - 1
+                                  TEMP = TEMP + A(K,I)*B(K,J)
+   90                         CONTINUE
+                          ELSE
+                              IF (NOUNIT) TEMP = TEMP*DCONJG(A(I,I))
+                              DO 100 K = 1,I - 1
+                                  TEMP = TEMP + DCONJG(A(K,I))*B(K,J)
+  100                         CONTINUE
+                          END IF
+                          B(I,J) = ALPHA*TEMP
+  110                 CONTINUE
+  120             CONTINUE
+              ELSE
+                  DO 160 J = 1,N
+                      DO 150 I = 1,M
+                          TEMP = B(I,J)
+                          IF (NOCONJ) THEN
+                              IF (NOUNIT) TEMP = TEMP*A(I,I)
+                              DO 130 K = I + 1,M
+                                  TEMP = TEMP + A(K,I)*B(K,J)
+  130                         CONTINUE
+                          ELSE
+                              IF (NOUNIT) TEMP = TEMP*DCONJG(A(I,I))
+                              DO 140 K = I + 1,M
+                                  TEMP = TEMP + DCONJG(A(K,I))*B(K,J)
+  140                         CONTINUE
+                          END IF
+                          B(I,J) = ALPHA*TEMP
+  150                 CONTINUE
+  160             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*A.
+*
+              IF (UPPER) THEN
+                  DO 200 J = N,1,-1
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 170 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  170                 CONTINUE
+                      DO 190 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 180 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  180                         CONTINUE
+                          END IF
+  190                 CONTINUE
+  200             CONTINUE
+              ELSE
+                  DO 240 J = 1,N
+                      TEMP = ALPHA
+                      IF (NOUNIT) TEMP = TEMP*A(J,J)
+                      DO 210 I = 1,M
+                          B(I,J) = TEMP*B(I,J)
+  210                 CONTINUE
+                      DO 230 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              TEMP = ALPHA*A(K,J)
+                              DO 220 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  220                         CONTINUE
+                          END IF
+  230                 CONTINUE
+  240             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*A**T   or   B := alpha*B*A**H.
+*
+              IF (UPPER) THEN
+                  DO 280 K = 1,N
+                      DO 260 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = ALPHA*A(J,K)
+                              ELSE
+                                  TEMP = ALPHA*DCONJG(A(J,K))
+                              END IF
+                              DO 250 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  250                         CONTINUE
+                          END IF
+  260                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = TEMP*A(K,K)
+                          ELSE
+                              TEMP = TEMP*DCONJG(A(K,K))
+                          END IF
+                      END IF
+                      IF (TEMP.NE.ONE) THEN
+                          DO 270 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  270                     CONTINUE
+                      END IF
+  280             CONTINUE
+              ELSE
+                  DO 320 K = N,1,-1
+                      DO 300 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = ALPHA*A(J,K)
+                              ELSE
+                                  TEMP = ALPHA*DCONJG(A(J,K))
+                              END IF
+                              DO 290 I = 1,M
+                                  B(I,J) = B(I,J) + TEMP*B(I,K)
+  290                         CONTINUE
+                          END IF
+  300                 CONTINUE
+                      TEMP = ALPHA
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = TEMP*A(K,K)
+                          ELSE
+                              TEMP = TEMP*DCONJG(A(K,K))
+                          END IF
+                      END IF
+                      IF (TEMP.NE.ONE) THEN
+                          DO 310 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  310                     CONTINUE
+                      END IF
+  320             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTRMM .
+*
+      END
diff --git a/superlu/BLAS/ztrmv.f b/superlu/BLAS/ztrmv.f
new file mode 100644
index 0000000..ab9065c
--- /dev/null
+++ b/superlu/BLAS/ztrmv.f
@@ -0,0 +1,373 @@
+*> \brief \b ZTRMV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZTRMV  performs one of the matrix-vector operations
+*>
+*>    x := A*x,   or   x := A**T*x,   or   x := A**H*x,
+*>
+*> where x is an n element vector and  A is an n by n unit, or non-unit,
+*> upper or lower triangular matrix.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the operation to be performed as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   x := A*x.
+*>
+*>              TRANS = 'T' or 't'   x := A**T*x.
+*>
+*>              TRANS = 'C' or 'c'   x := A**H*x.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular matrix and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular matrix and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced either, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in] X
+*> \verbatim
+*>          X is (input/output) COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element vector x. On exit, X is overwritten with the
+*>           transformed vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>  The vector and matrix arguments are not referenced when N = 0, or M = 0
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZTRMV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := A*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 10 I = 1,J - 1
+                              X(I) = X(I) + TEMP*A(I,J)
+   10                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 40 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 30 I = 1,J - 1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX + INCX
+   30                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX + INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          TEMP = X(J)
+                          DO 50 I = N,J + 1,-1
+                              X(I) = X(I) + TEMP*A(I,J)
+   50                     CONTINUE
+                          IF (NOUNIT) X(J) = X(J)*A(J,J)
+                      END IF
+   60             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 80 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          TEMP = X(JX)
+                          IX = KX
+                          DO 70 I = N,J + 1,-1
+                              X(IX) = X(IX) + TEMP*A(I,J)
+                              IX = IX - INCX
+   70                     CONTINUE
+                          IF (NOUNIT) X(JX) = X(JX)*A(J,J)
+                      END IF
+                      JX = JX - INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := A**T*x  or  x := A**H*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 90 I = J - 1,1,-1
+                              TEMP = TEMP + A(I,J)*X(I)
+   90                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(A(J,J))
+                          DO 100 I = J - 1,1,-1
+                              TEMP = TEMP + DCONJG(A(I,J))*X(I)
+  100                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 140 J = N,1,-1
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 120 I = J - 1,1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + A(I,J)*X(IX)
+  120                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(A(J,J))
+                          DO 130 I = J - 1,1,-1
+                              IX = IX - INCX
+                              TEMP = TEMP + DCONJG(A(I,J))*X(IX)
+  130                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = 1,N
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 150 I = J + 1,N
+                              TEMP = TEMP + A(I,J)*X(I)
+  150                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(A(J,J))
+                          DO 160 I = J + 1,N
+                              TEMP = TEMP + DCONJG(A(I,J))*X(I)
+  160                     CONTINUE
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 200 J = 1,N
+                      TEMP = X(JX)
+                      IX = JX
+                      IF (NOCONJ) THEN
+                          IF (NOUNIT) TEMP = TEMP*A(J,J)
+                          DO 180 I = J + 1,N
+                              IX = IX + INCX
+                              TEMP = TEMP + A(I,J)*X(IX)
+  180                     CONTINUE
+                      ELSE
+                          IF (NOUNIT) TEMP = TEMP*DCONJG(A(J,J))
+                          DO 190 I = J + 1,N
+                              IX = IX + INCX
+                              TEMP = TEMP + DCONJG(A(I,J))*X(IX)
+  190                     CONTINUE
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTRMV .
+*
+      END
diff --git a/superlu/BLAS/ztrsm.f b/superlu/BLAS/ztrsm.f
new file mode 100644
index 0000000..cc1af76
--- /dev/null
+++ b/superlu/BLAS/ztrsm.f
@@ -0,0 +1,477 @@
+*> \brief \b ZTRSM
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*       .. Scalar Arguments ..
+*       COMPLEX*16 ALPHA
+*       INTEGER LDA,LDB,M,N
+*       CHARACTER DIAG,SIDE,TRANSA,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),B(LDB,*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZTRSM  solves one of the matrix equations
+*>
+*>    op( A )*X = alpha*B,   or   X*op( A ) = alpha*B,
+*>
+*> where alpha is a scalar, X and B are m by n matrices, A is a unit, or
+*> non-unit,  upper or lower triangular matrix  and  op( A )  is one  of
+*>
+*>    op( A ) = A   or   op( A ) = A**T   or   op( A ) = A**H.
+*>
+*> The matrix X is overwritten on B.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] SIDE
+*> \verbatim
+*>          SIDE is CHARACTER*1
+*>           On entry, SIDE specifies whether op( A ) appears on the left
+*>           or right of X as follows:
+*>
+*>              SIDE = 'L' or 'l'   op( A )*X = alpha*B.
+*>
+*>              SIDE = 'R' or 'r'   X*op( A ) = alpha*B.
+*> \endverbatim
+*>
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix A is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANSA
+*> \verbatim
+*>          TRANSA is CHARACTER*1
+*>           On entry, TRANSA specifies the form of op( A ) to be used in
+*>           the matrix multiplication as follows:
+*>
+*>              TRANSA = 'N' or 'n'   op( A ) = A.
+*>
+*>              TRANSA = 'T' or 't'   op( A ) = A**T.
+*>
+*>              TRANSA = 'C' or 'c'   op( A ) = A**H.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit triangular
+*>           as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] M
+*> \verbatim
+*>          M is INTEGER
+*>           On entry, M specifies the number of rows of B. M must be at
+*>           least zero.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the number of columns of B.  N must be
+*>           at least zero.
+*> \endverbatim
+*>
+*> \param[in] ALPHA
+*> \verbatim
+*>          ALPHA is COMPLEX*16
+*>           On entry,  ALPHA specifies the scalar  alpha. When  alpha is
+*>           zero then  A is not referenced and  B need not be set before
+*>           entry.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, k ),
+*>           where k is m when SIDE = 'L' or 'l'
+*>             and k is n when SIDE = 'R' or 'r'.
+*>           Before entry  with  UPLO = 'U' or 'u',  the  leading  k by k
+*>           upper triangular part of the array  A must contain the upper
+*>           triangular matrix  and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry  with  UPLO = 'L' or 'l',  the  leading  k by k
+*>           lower triangular part of the array  A must contain the lower
+*>           triangular matrix  and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u',  the diagonal elements of
+*>           A  are not referenced either,  but are assumed to be  unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program.  When  SIDE = 'L' or 'l'  then
+*>           LDA  must be at least  max( 1, m ),  when  SIDE = 'R' or 'r'
+*>           then LDA must be at least max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] B
+*> \verbatim
+*>          B is COMPLEX*16 array of DIMENSION ( LDB, n ).
+*>           Before entry,  the leading  m by n part of the array  B must
+*>           contain  the  right-hand  side  matrix  B,  and  on exit  is
+*>           overwritten by the solution matrix  X.
+*> \endverbatim
+*>
+*> \param[in] LDB
+*> \verbatim
+*>          LDB is INTEGER
+*>           On entry, LDB specifies the first dimension of B as declared
+*>           in  the  calling  (sub)  program.   LDB  must  be  at  least
+*>           max( 1, m ).
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level3
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 3 Blas routine.
+*>
+*>  -- Written on 8-February-1989.
+*>     Jack Dongarra, Argonne National Laboratory.
+*>     Iain Duff, AERE Harwell.
+*>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
+*>     Sven Hammarling, Numerical Algorithms Group Ltd.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZTRSM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB)
+*
+*  -- Reference BLAS level3 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      COMPLEX*16 ALPHA
+      INTEGER LDA,LDB,M,N
+      CHARACTER DIAG,SIDE,TRANSA,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),B(LDB,*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,J,K,NROWA
+      LOGICAL LSIDE,NOCONJ,NOUNIT,UPPER
+*     ..
+*     .. Parameters ..
+      COMPLEX*16 ONE
+      PARAMETER (ONE= (1.0D+0,0.0D+0))
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*
+*     Test the input parameters.
+*
+      LSIDE = LSAME(SIDE,'L')
+      IF (LSIDE) THEN
+          NROWA = M
+      ELSE
+          NROWA = N
+      END IF
+      NOCONJ = LSAME(TRANSA,'T')
+      NOUNIT = LSAME(DIAG,'N')
+      UPPER = LSAME(UPLO,'U')
+*
+      INFO = 0
+      IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN
+          INFO = 1
+      ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN
+          INFO = 2
+      ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND.
+     +         (.NOT.LSAME(TRANSA,'T')) .AND.
+     +         (.NOT.LSAME(TRANSA,'C'))) THEN
+          INFO = 3
+      ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN
+          INFO = 4
+      ELSE IF (M.LT.0) THEN
+          INFO = 5
+      ELSE IF (N.LT.0) THEN
+          INFO = 6
+      ELSE IF (LDA.LT.MAX(1,NROWA)) THEN
+          INFO = 9
+      ELSE IF (LDB.LT.MAX(1,M)) THEN
+          INFO = 11
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZTRSM ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (M.EQ.0 .OR. N.EQ.0) RETURN
+*
+*     And when  alpha.eq.zero.
+*
+      IF (ALPHA.EQ.ZERO) THEN
+          DO 20 J = 1,N
+              DO 10 I = 1,M
+                  B(I,J) = ZERO
+   10         CONTINUE
+   20     CONTINUE
+          RETURN
+      END IF
+*
+*     Start the operations.
+*
+      IF (LSIDE) THEN
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*inv( A )*B.
+*
+              IF (UPPER) THEN
+                  DO 60 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 30 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   30                     CONTINUE
+                      END IF
+                      DO 50 K = M,1,-1
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 40 I = 1,K - 1
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   40                         CONTINUE
+                          END IF
+   50                 CONTINUE
+   60             CONTINUE
+              ELSE
+                  DO 100 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 70 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+   70                     CONTINUE
+                      END IF
+                      DO 90 K = 1,M
+                          IF (B(K,J).NE.ZERO) THEN
+                              IF (NOUNIT) B(K,J) = B(K,J)/A(K,K)
+                              DO 80 I = K + 1,M
+                                  B(I,J) = B(I,J) - B(K,J)*A(I,K)
+   80                         CONTINUE
+                          END IF
+   90                 CONTINUE
+  100             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*inv( A**T )*B
+*           or    B := alpha*inv( A**H )*B.
+*
+              IF (UPPER) THEN
+                  DO 140 J = 1,N
+                      DO 130 I = 1,M
+                          TEMP = ALPHA*B(I,J)
+                          IF (NOCONJ) THEN
+                              DO 110 K = 1,I - 1
+                                  TEMP = TEMP - A(K,I)*B(K,J)
+  110                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          ELSE
+                              DO 120 K = 1,I - 1
+                                  TEMP = TEMP - DCONJG(A(K,I))*B(K,J)
+  120                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/DCONJG(A(I,I))
+                          END IF
+                          B(I,J) = TEMP
+  130                 CONTINUE
+  140             CONTINUE
+              ELSE
+                  DO 180 J = 1,N
+                      DO 170 I = M,1,-1
+                          TEMP = ALPHA*B(I,J)
+                          IF (NOCONJ) THEN
+                              DO 150 K = I + 1,M
+                                  TEMP = TEMP - A(K,I)*B(K,J)
+  150                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/A(I,I)
+                          ELSE
+                              DO 160 K = I + 1,M
+                                  TEMP = TEMP - DCONJG(A(K,I))*B(K,J)
+  160                         CONTINUE
+                              IF (NOUNIT) TEMP = TEMP/DCONJG(A(I,I))
+                          END IF
+                          B(I,J) = TEMP
+  170                 CONTINUE
+  180             CONTINUE
+              END IF
+          END IF
+      ELSE
+          IF (LSAME(TRANSA,'N')) THEN
+*
+*           Form  B := alpha*B*inv( A ).
+*
+              IF (UPPER) THEN
+                  DO 230 J = 1,N
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 190 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  190                     CONTINUE
+                      END IF
+                      DO 210 K = 1,J - 1
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 200 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  200                         CONTINUE
+                          END IF
+  210                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 220 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  220                     CONTINUE
+                      END IF
+  230             CONTINUE
+              ELSE
+                  DO 280 J = N,1,-1
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 240 I = 1,M
+                              B(I,J) = ALPHA*B(I,J)
+  240                     CONTINUE
+                      END IF
+                      DO 260 K = J + 1,N
+                          IF (A(K,J).NE.ZERO) THEN
+                              DO 250 I = 1,M
+                                  B(I,J) = B(I,J) - A(K,J)*B(I,K)
+  250                         CONTINUE
+                          END IF
+  260                 CONTINUE
+                      IF (NOUNIT) THEN
+                          TEMP = ONE/A(J,J)
+                          DO 270 I = 1,M
+                              B(I,J) = TEMP*B(I,J)
+  270                     CONTINUE
+                      END IF
+  280             CONTINUE
+              END IF
+          ELSE
+*
+*           Form  B := alpha*B*inv( A**T )
+*           or    B := alpha*B*inv( A**H ).
+*
+              IF (UPPER) THEN
+                  DO 330 K = N,1,-1
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = ONE/A(K,K)
+                          ELSE
+                              TEMP = ONE/DCONJG(A(K,K))
+                          END IF
+                          DO 290 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  290                     CONTINUE
+                      END IF
+                      DO 310 J = 1,K - 1
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = A(J,K)
+                              ELSE
+                                  TEMP = DCONJG(A(J,K))
+                              END IF
+                              DO 300 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  300                         CONTINUE
+                          END IF
+  310                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 320 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  320                     CONTINUE
+                      END IF
+  330             CONTINUE
+              ELSE
+                  DO 380 K = 1,N
+                      IF (NOUNIT) THEN
+                          IF (NOCONJ) THEN
+                              TEMP = ONE/A(K,K)
+                          ELSE
+                              TEMP = ONE/DCONJG(A(K,K))
+                          END IF
+                          DO 340 I = 1,M
+                              B(I,K) = TEMP*B(I,K)
+  340                     CONTINUE
+                      END IF
+                      DO 360 J = K + 1,N
+                          IF (A(J,K).NE.ZERO) THEN
+                              IF (NOCONJ) THEN
+                                  TEMP = A(J,K)
+                              ELSE
+                                  TEMP = DCONJG(A(J,K))
+                              END IF
+                              DO 350 I = 1,M
+                                  B(I,J) = B(I,J) - TEMP*B(I,K)
+  350                         CONTINUE
+                          END IF
+  360                 CONTINUE
+                      IF (ALPHA.NE.ONE) THEN
+                          DO 370 I = 1,M
+                              B(I,K) = ALPHA*B(I,K)
+  370                     CONTINUE
+                      END IF
+  380             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTRSM .
+*
+      END
diff --git a/superlu/BLAS/ztrsv.f b/superlu/BLAS/ztrsv.f
new file mode 100644
index 0000000..577b5ca
--- /dev/null
+++ b/superlu/BLAS/ztrsv.f
@@ -0,0 +1,375 @@
+*> \brief \b ZTRSV
+*
+*  =========== DOCUMENTATION ===========
+*
+* Online html documentation available at
+*            http://www.netlib.org/lapack/explore-html/
+*
+*  Definition:
+*  ===========
+*
+*       SUBROUTINE ZTRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*       .. Scalar Arguments ..
+*       INTEGER INCX,LDA,N
+*       CHARACTER DIAG,TRANS,UPLO
+*       ..
+*       .. Array Arguments ..
+*       COMPLEX*16 A(LDA,*),X(*)
+*       ..
+*
+*
+*> \par Purpose:
+*  =============
+*>
+*> \verbatim
+*>
+*> ZTRSV  solves one of the systems of equations
+*>
+*>    A*x = b,   or   A**T*x = b,   or   A**H*x = b,
+*>
+*> where b and x are n element vectors and A is an n by n unit, or
+*> non-unit, upper or lower triangular matrix.
+*>
+*> No test for singularity or near-singularity is included in this
+*> routine. Such tests must be performed before calling this routine.
+*> \endverbatim
+*
+*  Arguments:
+*  ==========
+*
+*> \param[in] UPLO
+*> \verbatim
+*>          UPLO is CHARACTER*1
+*>           On entry, UPLO specifies whether the matrix is an upper or
+*>           lower triangular matrix as follows:
+*>
+*>              UPLO = 'U' or 'u'   A is an upper triangular matrix.
+*>
+*>              UPLO = 'L' or 'l'   A is a lower triangular matrix.
+*> \endverbatim
+*>
+*> \param[in] TRANS
+*> \verbatim
+*>          TRANS is CHARACTER*1
+*>           On entry, TRANS specifies the equations to be solved as
+*>           follows:
+*>
+*>              TRANS = 'N' or 'n'   A*x = b.
+*>
+*>              TRANS = 'T' or 't'   A**T*x = b.
+*>
+*>              TRANS = 'C' or 'c'   A**H*x = b.
+*> \endverbatim
+*>
+*> \param[in] DIAG
+*> \verbatim
+*>          DIAG is CHARACTER*1
+*>           On entry, DIAG specifies whether or not A is unit
+*>           triangular as follows:
+*>
+*>              DIAG = 'U' or 'u'   A is assumed to be unit triangular.
+*>
+*>              DIAG = 'N' or 'n'   A is not assumed to be unit
+*>                                  triangular.
+*> \endverbatim
+*>
+*> \param[in] N
+*> \verbatim
+*>          N is INTEGER
+*>           On entry, N specifies the order of the matrix A.
+*>           N must be at least zero.
+*> \endverbatim
+*>
+*> \param[in] A
+*> \verbatim
+*>          A is COMPLEX*16 array of DIMENSION ( LDA, n ).
+*>           Before entry with  UPLO = 'U' or 'u', the leading n by n
+*>           upper triangular part of the array A must contain the upper
+*>           triangular matrix and the strictly lower triangular part of
+*>           A is not referenced.
+*>           Before entry with UPLO = 'L' or 'l', the leading n by n
+*>           lower triangular part of the array A must contain the lower
+*>           triangular matrix and the strictly upper triangular part of
+*>           A is not referenced.
+*>           Note that when  DIAG = 'U' or 'u', the diagonal elements of
+*>           A are not referenced either, but are assumed to be unity.
+*> \endverbatim
+*>
+*> \param[in] LDA
+*> \verbatim
+*>          LDA is INTEGER
+*>           On entry, LDA specifies the first dimension of A as declared
+*>           in the calling (sub) program. LDA must be at least
+*>           max( 1, n ).
+*> \endverbatim
+*>
+*> \param[in,out] X
+*> \verbatim
+*>          X is COMPLEX*16 array of dimension at least
+*>           ( 1 + ( n - 1 )*abs( INCX ) ).
+*>           Before entry, the incremented array X must contain the n
+*>           element right-hand side vector b. On exit, X is overwritten
+*>           with the solution vector x.
+*> \endverbatim
+*>
+*> \param[in] INCX
+*> \verbatim
+*>          INCX is INTEGER
+*>           On entry, INCX specifies the increment for the elements of
+*>           X. INCX must not be zero.
+*> \endverbatim
+*
+*  Authors:
+*  ========
+*
+*> \author Univ. of Tennessee
+*> \author Univ. of California Berkeley
+*> \author Univ. of Colorado Denver
+*> \author NAG Ltd.
+*
+*> \date December 2016
+*
+*> \ingroup complex16_blas_level2
+*
+*> \par Further Details:
+*  =====================
+*>
+*> \verbatim
+*>
+*>  Level 2 Blas routine.
+*>
+*>  -- Written on 22-October-1986.
+*>     Jack Dongarra, Argonne National Lab.
+*>     Jeremy Du Croz, Nag Central Office.
+*>     Sven Hammarling, Nag Central Office.
+*>     Richard Hanson, Sandia National Labs.
+*> \endverbatim
+*>
+*  =====================================================================
+      SUBROUTINE ZTRSV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
+*
+*  -- Reference BLAS level2 routine (version 3.7.0) --
+*  -- Reference BLAS is a software package provided by Univ. of Tennessee,    --
+*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
+*     December 2016
+*
+*     .. Scalar Arguments ..
+      INTEGER INCX,LDA,N
+      CHARACTER DIAG,TRANS,UPLO
+*     ..
+*     .. Array Arguments ..
+      COMPLEX*16 A(LDA,*),X(*)
+*     ..
+*
+*  =====================================================================
+*
+*     .. Parameters ..
+      COMPLEX*16 ZERO
+      PARAMETER (ZERO= (0.0D+0,0.0D+0))
+*     ..
+*     .. Local Scalars ..
+      COMPLEX*16 TEMP
+      INTEGER I,INFO,IX,J,JX,KX
+      LOGICAL NOCONJ,NOUNIT
+*     ..
+*     .. External Functions ..
+      LOGICAL LSAME
+      EXTERNAL LSAME
+*     ..
+*     .. External Subroutines ..
+      EXTERNAL XERBLA
+*     ..
+*     .. Intrinsic Functions ..
+      INTRINSIC DCONJG,MAX
+*     ..
+*
+*     Test the input parameters.
+*
+      INFO = 0
+      IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
+          INFO = 1
+      ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.
+     +         .NOT.LSAME(TRANS,'C')) THEN
+          INFO = 2
+      ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
+          INFO = 3
+      ELSE IF (N.LT.0) THEN
+          INFO = 4
+      ELSE IF (LDA.LT.MAX(1,N)) THEN
+          INFO = 6
+      ELSE IF (INCX.EQ.0) THEN
+          INFO = 8
+      END IF
+      IF (INFO.NE.0) THEN
+          CALL XERBLA('ZTRSV ',INFO)
+          RETURN
+      END IF
+*
+*     Quick return if possible.
+*
+      IF (N.EQ.0) RETURN
+*
+      NOCONJ = LSAME(TRANS,'T')
+      NOUNIT = LSAME(DIAG,'N')
+*
+*     Set up the start point in X if the increment is not unity. This
+*     will be  ( N - 1 )*INCX  too small for descending loops.
+*
+      IF (INCX.LE.0) THEN
+          KX = 1 - (N-1)*INCX
+      ELSE IF (INCX.NE.1) THEN
+          KX = 1
+      END IF
+*
+*     Start the operations. In this version the elements of A are
+*     accessed sequentially with one pass through A.
+*
+      IF (LSAME(TRANS,'N')) THEN
+*
+*        Form  x := inv( A )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 20 J = N,1,-1
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 10 I = J - 1,1,-1
+                              X(I) = X(I) - TEMP*A(I,J)
+   10                     CONTINUE
+                      END IF
+   20             CONTINUE
+              ELSE
+                  JX = KX + (N-1)*INCX
+                  DO 40 J = N,1,-1
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 30 I = J - 1,1,-1
+                              IX = IX - INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   30                     CONTINUE
+                      END IF
+                      JX = JX - INCX
+   40             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 60 J = 1,N
+                      IF (X(J).NE.ZERO) THEN
+                          IF (NOUNIT) X(J) = X(J)/A(J,J)
+                          TEMP = X(J)
+                          DO 50 I = J + 1,N
+                              X(I) = X(I) - TEMP*A(I,J)
+   50                     CONTINUE
+                      END IF
+   60             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 80 J = 1,N
+                      IF (X(JX).NE.ZERO) THEN
+                          IF (NOUNIT) X(JX) = X(JX)/A(J,J)
+                          TEMP = X(JX)
+                          IX = JX
+                          DO 70 I = J + 1,N
+                              IX = IX + INCX
+                              X(IX) = X(IX) - TEMP*A(I,J)
+   70                     CONTINUE
+                      END IF
+                      JX = JX + INCX
+   80             CONTINUE
+              END IF
+          END IF
+      ELSE
+*
+*        Form  x := inv( A**T )*x  or  x := inv( A**H )*x.
+*
+          IF (LSAME(UPLO,'U')) THEN
+              IF (INCX.EQ.1) THEN
+                  DO 110 J = 1,N
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          DO 90 I = 1,J - 1
+                              TEMP = TEMP - A(I,J)*X(I)
+   90                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 100 I = 1,J - 1
+                              TEMP = TEMP - DCONJG(A(I,J))*X(I)
+  100                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(A(J,J))
+                      END IF
+                      X(J) = TEMP
+  110             CONTINUE
+              ELSE
+                  JX = KX
+                  DO 140 J = 1,N
+                      IX = KX
+                      TEMP = X(JX)
+                      IF (NOCONJ) THEN
+                          DO 120 I = 1,J - 1
+                              TEMP = TEMP - A(I,J)*X(IX)
+                              IX = IX + INCX
+  120                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 130 I = 1,J - 1
+                              TEMP = TEMP - DCONJG(A(I,J))*X(IX)
+                              IX = IX + INCX
+  130                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(A(J,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX + INCX
+  140             CONTINUE
+              END IF
+          ELSE
+              IF (INCX.EQ.1) THEN
+                  DO 170 J = N,1,-1
+                      TEMP = X(J)
+                      IF (NOCONJ) THEN
+                          DO 150 I = N,J + 1,-1
+                              TEMP = TEMP - A(I,J)*X(I)
+  150                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 160 I = N,J + 1,-1
+                              TEMP = TEMP - DCONJG(A(I,J))*X(I)
+  160                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(A(J,J))
+                      END IF
+                      X(J) = TEMP
+  170             CONTINUE
+              ELSE
+                  KX = KX + (N-1)*INCX
+                  JX = KX
+                  DO 200 J = N,1,-1
+                      IX = KX
+                      TEMP = X(JX)
+                      IF (NOCONJ) THEN
+                          DO 180 I = N,J + 1,-1
+                              TEMP = TEMP - A(I,J)*X(IX)
+                              IX = IX - INCX
+  180                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/A(J,J)
+                      ELSE
+                          DO 190 I = N,J + 1,-1
+                              TEMP = TEMP - DCONJG(A(I,J))*X(IX)
+                              IX = IX - INCX
+  190                     CONTINUE
+                          IF (NOUNIT) TEMP = TEMP/DCONJG(A(J,J))
+                      END IF
+                      X(JX) = TEMP
+                      JX = JX - INCX
+  200             CONTINUE
+              END IF
+          END IF
+      END IF
+*
+      RETURN
+*
+*     End of ZTRSV .
+*
+      END
diff --git a/superlu/BLAS_f2c.h b/superlu/BLAS_f2c.h
index d4eaf1f..ad4552a 100644
--- a/superlu/BLAS_f2c.h
+++ b/superlu/BLAS_f2c.h
@@ -1,5 +1,24 @@
 /* f2c.h  --  Standard Fortran to C header file */
 
+/*
+// Copyright (C) 2004 
+// Christian Stimming <stimming at tuhh.de>
+ 
+// This library 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 2, or (at
+// your option) any later version.
+ 
+// This library 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 this library; see the file COPYING.  If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
 /**  barf  [ba:rf]  2.  "He suggested using FORTRAN, and everybody barfed."
 
 	- From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) */
diff --git a/superlu/Makefile.am b/superlu/Makefile.am
index b12c5a7..16bd181 100644
--- a/superlu/Makefile.am
+++ b/superlu/Makefile.am
@@ -1,3 +1,31 @@
+#
+# Copyright (c) 2003, The Regents of the University of California, through
+# Lawrence Berkeley National Laboratory (subject to receipt of any required 
+# approvals from U.S. Dept. of Energy) 
+#
+# All rights reserved. 
+#
+# The source code is distributed under BSD license, see the file License.txt
+#
+
+
+#  Copyright (C) 2004-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 noinst_HEADERS=\
 	slu_Cnames.h slu_dcomplex.h slu_scomplex.h slu_util.h\
 	supermatrix.h colamd.h slu_cdefs.h slu_ddefs.h\
@@ -146,4 +174,156 @@ libsuperlu_la_CPPFLAGS = @SUPERLU_CPPFLAGS@
 
 CLEANFILES = ii_files/* *.o.d
 
-EXTRA_DIST=License.txt
+EXTRA_DIST=License.txt \
+BLAS/License.txt \
+BLAS/caxpy.f \
+BLAS/ccopy.f \
+BLAS/cdotc.f \
+BLAS/cdotu.f \
+BLAS/cgbmv.f \
+BLAS/cgemm.f \
+BLAS/cgemv.f \
+BLAS/cgerc.f \
+BLAS/cgeru.f \
+BLAS/chbmv.f \
+BLAS/chemm.f \
+BLAS/chemv.f \
+BLAS/cher2.f \
+BLAS/cher2k.f \
+BLAS/cher.f \
+BLAS/cherk.f \
+BLAS/chpmv.f \
+BLAS/chpr2.f \
+BLAS/chpr.f \
+BLAS/crotg.f \
+BLAS/cscal.f \
+BLAS/csrot.f \
+BLAS/csscal.f \
+BLAS/cswap.f \
+BLAS/csymm.f \
+BLAS/csyr2k.f \
+BLAS/csyrk.f \
+BLAS/ctbmv.f \
+BLAS/ctbsv.f \
+BLAS/ctpmv.f \
+BLAS/ctpsv.f \
+BLAS/ctrmm.f \
+BLAS/ctrmv.f \
+BLAS/ctrsm.f \
+BLAS/ctrsv.f \
+BLAS/dasum.f \
+BLAS/daxpy.f \
+BLAS/dcabs1.f \
+BLAS/dcopy.f \
+BLAS/ddot.f \
+BLAS/dgbmv.f \
+BLAS/dgemm.f \
+BLAS/dgemv.f \
+BLAS/dger.f \
+BLAS/dnrm2.f \
+BLAS/drot.f \
+BLAS/drotg.f \
+BLAS/drotm.f \
+BLAS/drotmg.f \
+BLAS/dsbmv.f \
+BLAS/dscal.f \
+BLAS/dsdot.f \
+BLAS/dspmv.f \
+BLAS/dspr2.f \
+BLAS/dspr.f \
+BLAS/dswap.f \
+BLAS/dsymm.f \
+BLAS/dsymv.f \
+BLAS/dsyr2.f \
+BLAS/dsyr2k.f \
+BLAS/dsyr.f \
+BLAS/dsyrk.f \
+BLAS/dtbmv.f \
+BLAS/dtbsv.f \
+BLAS/dtpmv.f \
+BLAS/dtpsv.f \
+BLAS/dtrmm.f \
+BLAS/dtrmv.f \
+BLAS/dtrsm.f \
+BLAS/dtrsv.f \
+BLAS/dzasum.f \
+BLAS/dznrm2.f \
+BLAS/icamax.f \
+BLAS/idamax.f \
+BLAS/isamax.f \
+BLAS/izamax.f \
+BLAS/lsame.f \
+BLAS/sasum.f \
+BLAS/saxpy.f \
+BLAS/scabs1.f \
+BLAS/scasum.f \
+BLAS/scnrm2.f \
+BLAS/scopy.f \
+BLAS/sdot.f \
+BLAS/sdsdot.f \
+BLAS/sgbmv.f \
+BLAS/sgemm.f \
+BLAS/sgemv.f \
+BLAS/sger.f \
+BLAS/snrm2.f \
+BLAS/srot.f \
+BLAS/srotg.f \
+BLAS/srotm.f \
+BLAS/srotmg.f \
+BLAS/ssbmv.f \
+BLAS/sscal.f \
+BLAS/sspmv.f \
+BLAS/sspr2.f \
+BLAS/sspr.f \
+BLAS/sswap.f \
+BLAS/ssymm.f \
+BLAS/ssymv.f \
+BLAS/ssyr2.f \
+BLAS/ssyr2k.f \
+BLAS/ssyr.f \
+BLAS/ssyrk.f \
+BLAS/stbmv.f \
+BLAS/stbsv.f \
+BLAS/stpmv.f \
+BLAS/stpsv.f \
+BLAS/strmm.f \
+BLAS/strmv.f \
+BLAS/strsm.f \
+BLAS/strsv.f \
+BLAS/xerbla_array.f \
+BLAS/xerbla.f \
+BLAS/zaxpy.f \
+BLAS/zcopy.f \
+BLAS/zdotc.f \
+BLAS/zdotu.f \
+BLAS/zdrot.f \
+BLAS/zdscal.f \
+BLAS/zgbmv.f \
+BLAS/zgemm.f \
+BLAS/zgemv.f \
+BLAS/zgerc.f \
+BLAS/zgeru.f \
+BLAS/zhbmv.f \
+BLAS/zhemm.f \
+BLAS/zhemv.f \
+BLAS/zher2.f \
+BLAS/zher2k.f \
+BLAS/zher.f \
+BLAS/zherk.f \
+BLAS/zhpmv.f \
+BLAS/zhpr2.f \
+BLAS/zhpr.f \
+BLAS/zrotg.f \
+BLAS/zscal.f \
+BLAS/zswap.f \
+BLAS/zsymm.f \
+BLAS/zsyr2k.f \
+BLAS/zsyrk.f \
+BLAS/ztbmv.f \
+BLAS/ztbsv.f \
+BLAS/ztpmv.f \
+BLAS/ztpsv.f \
+BLAS/ztrmm.f \
+BLAS/ztrmv.f \
+BLAS/ztrsm.f \
+BLAS/ztrsv.f
diff --git a/superlu/Makefile.in b/superlu/Makefile.in
index c52aaed..9ba0240 100644
--- a/superlu/Makefile.in
+++ b/superlu/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,19 +14,36 @@
 
 @SET_MAKE@
 
+#
+# Copyright (c) 2003, The Regents of the University of California, through
+# Lawrence Berkeley National Laboratory (subject to receipt of any required 
+# approvals from U.S. Dept. of Energy) 
+#
+# All rights reserved. 
+#
+# The source code is distributed under BSD license, see the file License.txt
+#
+
+#  Copyright (C) 2004-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -90,6 +107,9 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = superlu
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(noinst_HEADERS)
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -105,8 +125,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
-	$(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -269,8 +287,6 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -338,7 +354,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -371,8 +386,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -453,7 +470,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -601,7 +617,160 @@ libsuperlu_la_SOURCES = $(SRC)
 #libsuperlu_la_LDFLAGS = ${LIBTOOL_VERSION_INFO}
 libsuperlu_la_CPPFLAGS = @SUPERLU_CPPFLAGS@
 CLEANFILES = ii_files/* *.o.d
-EXTRA_DIST = License.txt
+EXTRA_DIST = License.txt \
+BLAS/License.txt \
+BLAS/caxpy.f \
+BLAS/ccopy.f \
+BLAS/cdotc.f \
+BLAS/cdotu.f \
+BLAS/cgbmv.f \
+BLAS/cgemm.f \
+BLAS/cgemv.f \
+BLAS/cgerc.f \
+BLAS/cgeru.f \
+BLAS/chbmv.f \
+BLAS/chemm.f \
+BLAS/chemv.f \
+BLAS/cher2.f \
+BLAS/cher2k.f \
+BLAS/cher.f \
+BLAS/cherk.f \
+BLAS/chpmv.f \
+BLAS/chpr2.f \
+BLAS/chpr.f \
+BLAS/crotg.f \
+BLAS/cscal.f \
+BLAS/csrot.f \
+BLAS/csscal.f \
+BLAS/cswap.f \
+BLAS/csymm.f \
+BLAS/csyr2k.f \
+BLAS/csyrk.f \
+BLAS/ctbmv.f \
+BLAS/ctbsv.f \
+BLAS/ctpmv.f \
+BLAS/ctpsv.f \
+BLAS/ctrmm.f \
+BLAS/ctrmv.f \
+BLAS/ctrsm.f \
+BLAS/ctrsv.f \
+BLAS/dasum.f \
+BLAS/daxpy.f \
+BLAS/dcabs1.f \
+BLAS/dcopy.f \
+BLAS/ddot.f \
+BLAS/dgbmv.f \
+BLAS/dgemm.f \
+BLAS/dgemv.f \
+BLAS/dger.f \
+BLAS/dnrm2.f \
+BLAS/drot.f \
+BLAS/drotg.f \
+BLAS/drotm.f \
+BLAS/drotmg.f \
+BLAS/dsbmv.f \
+BLAS/dscal.f \
+BLAS/dsdot.f \
+BLAS/dspmv.f \
+BLAS/dspr2.f \
+BLAS/dspr.f \
+BLAS/dswap.f \
+BLAS/dsymm.f \
+BLAS/dsymv.f \
+BLAS/dsyr2.f \
+BLAS/dsyr2k.f \
+BLAS/dsyr.f \
+BLAS/dsyrk.f \
+BLAS/dtbmv.f \
+BLAS/dtbsv.f \
+BLAS/dtpmv.f \
+BLAS/dtpsv.f \
+BLAS/dtrmm.f \
+BLAS/dtrmv.f \
+BLAS/dtrsm.f \
+BLAS/dtrsv.f \
+BLAS/dzasum.f \
+BLAS/dznrm2.f \
+BLAS/icamax.f \
+BLAS/idamax.f \
+BLAS/isamax.f \
+BLAS/izamax.f \
+BLAS/lsame.f \
+BLAS/sasum.f \
+BLAS/saxpy.f \
+BLAS/scabs1.f \
+BLAS/scasum.f \
+BLAS/scnrm2.f \
+BLAS/scopy.f \
+BLAS/sdot.f \
+BLAS/sdsdot.f \
+BLAS/sgbmv.f \
+BLAS/sgemm.f \
+BLAS/sgemv.f \
+BLAS/sger.f \
+BLAS/snrm2.f \
+BLAS/srot.f \
+BLAS/srotg.f \
+BLAS/srotm.f \
+BLAS/srotmg.f \
+BLAS/ssbmv.f \
+BLAS/sscal.f \
+BLAS/sspmv.f \
+BLAS/sspr2.f \
+BLAS/sspr.f \
+BLAS/sswap.f \
+BLAS/ssymm.f \
+BLAS/ssymv.f \
+BLAS/ssyr2.f \
+BLAS/ssyr2k.f \
+BLAS/ssyr.f \
+BLAS/ssyrk.f \
+BLAS/stbmv.f \
+BLAS/stbsv.f \
+BLAS/stpmv.f \
+BLAS/stpsv.f \
+BLAS/strmm.f \
+BLAS/strmv.f \
+BLAS/strsm.f \
+BLAS/strsv.f \
+BLAS/xerbla_array.f \
+BLAS/xerbla.f \
+BLAS/zaxpy.f \
+BLAS/zcopy.f \
+BLAS/zdotc.f \
+BLAS/zdotu.f \
+BLAS/zdrot.f \
+BLAS/zdscal.f \
+BLAS/zgbmv.f \
+BLAS/zgemm.f \
+BLAS/zgemv.f \
+BLAS/zgerc.f \
+BLAS/zgeru.f \
+BLAS/zhbmv.f \
+BLAS/zhemm.f \
+BLAS/zhemv.f \
+BLAS/zher2.f \
+BLAS/zher2k.f \
+BLAS/zher.f \
+BLAS/zherk.f \
+BLAS/zhpmv.f \
+BLAS/zhpr2.f \
+BLAS/zhpr.f \
+BLAS/zrotg.f \
+BLAS/zscal.f \
+BLAS/zswap.f \
+BLAS/zsymm.f \
+BLAS/zsyr2k.f \
+BLAS/zsyrk.f \
+BLAS/ztbmv.f \
+BLAS/ztbsv.f \
+BLAS/ztpmv.f \
+BLAS/ztpsv.f \
+BLAS/ztrmm.f \
+BLAS/ztrmv.f \
+BLAS/ztrsm.f \
+BLAS/ztrsv.f
+
 all: all-am
 
 .SUFFIXES:
@@ -618,6 +787,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu superlu/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu superlu/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -1896,8 +2066,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/superlu/ccolumn_bmod.c b/superlu/ccolumn_bmod.c
index 72ae5be..d6341af 100644
--- a/superlu/ccolumn_bmod.c
+++ b/superlu/ccolumn_bmod.c
@@ -7,21 +7,22 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
+
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_cdefs.h"
+extern void ctrsv_();
+extern void cgemv_();
+
 
 /* 
  * Function prototypes 
diff --git a/superlu/ccolumn_dfs.c b/superlu/ccolumn_dfs.c
index 10f0fb6..e60ba5a 100644
--- a/superlu/ccolumn_dfs.c
+++ b/superlu/ccolumn_dfs.c
@@ -7,16 +7,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_cdefs.h"
diff --git a/superlu/ccopy_to_ucol.c b/superlu/ccopy_to_ucol.c
index a0972fa..a0554a9 100644
--- a/superlu/ccopy_to_ucol.c
+++ b/superlu/ccopy_to_ucol.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/cgscon.c b/superlu/cgscon.c
index ee8bb4b..5bd3c49 100644
--- a/superlu/cgscon.c
+++ b/superlu/cgscon.c
@@ -7,6 +7,18 @@
  *
  */
 /*
+  Copyright (c) 2003 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:	cgscon.c
  * History:     Modified from lapack routines CGECON.
  */
diff --git a/superlu/cgsequ.c b/superlu/cgsequ.c
index 77a4961..9dbacef 100644
--- a/superlu/cgsequ.c
+++ b/superlu/cgsequ.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:	cgsequ.c
  * History:     Modified from LAPACK routine CGEEQU
  */
diff --git a/superlu/cgsrfs.c b/superlu/cgsrfs.c
index 68568cf..7b06fee 100644
--- a/superlu/cgsrfs.c
+++ b/superlu/cgsrfs.c
@@ -7,6 +7,16 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
+/*
  * File name:	cgsrfs.c
  * History:     Modified from lapack routine CGERFS
  */
diff --git a/superlu/cgssv.c b/superlu/cgssv.c
index d0ecf19..04f62b8 100644
--- a/superlu/cgssv.c
+++ b/superlu/cgssv.c
@@ -6,6 +6,16 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
 #include "slu_cdefs.h"
 
 void
diff --git a/superlu/cgssvx.c b/superlu/cgssvx.c
index d6ba4e2..905e7c7 100644
--- a/superlu/cgssvx.c
+++ b/superlu/cgssvx.c
@@ -6,6 +6,17 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
+
 #include "slu_cdefs.h"
 
 void
diff --git a/superlu/cgstrf.c b/superlu/cgstrf.c
index 401fff7..bd3cee0 100644
--- a/superlu/cgstrf.c
+++ b/superlu/cgstrf.c
@@ -7,20 +7,21 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
+
 #include "slu_cdefs.h"
 
+extern void countnz();
+extern void fixupL();
+
 void
 cgstrf (superlu_options_t *options, SuperMatrix *A, float drop_tol,
         int relax, int panel_size, int *etree, void *work, int lwork,
diff --git a/superlu/cgstrs.c b/superlu/cgstrs.c
index 6ddfef3..b2d1997 100644
--- a/superlu/cgstrs.c
+++ b/superlu/cgstrs.c
@@ -7,20 +7,19 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
-#include "slu_cdefs.h"
 
+#include "slu_cdefs.h"
+extern void ctrsm_();
+extern void cgemm_();
 
 /* 
  * Function prototypes 
diff --git a/superlu/clacon.c b/superlu/clacon.c
index 704f1bf..6e332f6 100644
--- a/superlu/clacon.c
+++ b/superlu/clacon.c
@@ -6,9 +6,32 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 #include <math.h>
 #include "slu_Cnames.h"
 #include "slu_scomplex.h"
+extern void ccopy_();
 
 int
 clacon_(int *n, complex *v, complex *x, float *est, int *kase)
diff --git a/superlu/clangs.c b/superlu/clangs.c
index de7f91f..f24c380 100644
--- a/superlu/clangs.c
+++ b/superlu/clangs.c
@@ -7,6 +7,28 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:	clangs.c
  * History:     Modified from lapack routine CLANGE
  */
diff --git a/superlu/claqgs.c b/superlu/claqgs.c
index 377b501..cfecc37 100644
--- a/superlu/claqgs.c
+++ b/superlu/claqgs.c
@@ -7,6 +7,28 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:	claqgs.c
  * History:     Modified from LAPACK routine CLAQGE
  */
diff --git a/superlu/cmemory.c b/superlu/cmemory.c
index d50f58d..3f364b4 100644
--- a/superlu/cmemory.c
+++ b/superlu/cmemory.c
@@ -6,6 +6,17 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
+
 #include "slu_cdefs.h"
 
 /* Constants */
diff --git a/superlu/cmyblas2.c b/superlu/cmyblas2.c
index 5998f87..7717bae 100644
--- a/superlu/cmyblas2.c
+++ b/superlu/cmyblas2.c
@@ -7,6 +7,28 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:		cmyblas2.c
  * Purpose:
  *     Level 2 BLAS operations: solves and matvec, written in C.
diff --git a/superlu/cpanel_bmod.c b/superlu/cpanel_bmod.c
index c1246a1..b899953 100644
--- a/superlu/cpanel_bmod.c
+++ b/superlu/cpanel_bmod.c
@@ -7,22 +7,22 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_cdefs.h"
 
+extern void ctrsv_();
+extern void cgemv_();
+
 /* 
  * Function prototypes 
  */
diff --git a/superlu/cpanel_dfs.c b/superlu/cpanel_dfs.c
index f20a8d2..8d7b983 100644
--- a/superlu/cpanel_dfs.c
+++ b/superlu/cpanel_dfs.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/cpivotL.c b/superlu/cpivotL.c
index db24a0d..006be07 100644
--- a/superlu/cpivotL.c
+++ b/superlu/cpivotL.c
@@ -7,16 +7,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <math.h>
diff --git a/superlu/cpivotgrowth.c b/superlu/cpivotgrowth.c
index 63bd7bf..c1dd72a 100644
--- a/superlu/cpivotgrowth.c
+++ b/superlu/cpivotgrowth.c
@@ -6,6 +6,28 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 #include <math.h>
 #include "slu_cdefs.h"
 
diff --git a/superlu/cpruneL.c b/superlu/cpruneL.c
index 29f20d4..f43617f 100644
--- a/superlu/cpruneL.c
+++ b/superlu/cpruneL.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/creadhb.c b/superlu/creadhb.c
index d8a707e..4757207 100644
--- a/superlu/creadhb.c
+++ b/superlu/creadhb.c
@@ -6,6 +6,28 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_cdefs.h"
diff --git a/superlu/csnode_bmod.c b/superlu/csnode_bmod.c
index 041737f..8c4812c 100644
--- a/superlu/csnode_bmod.c
+++ b/superlu/csnode_bmod.c
@@ -7,20 +7,19 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
-#include "slu_cdefs.h"
 
+#include "slu_cdefs.h"
+extern void ctrsv_();
+extern void cgemv_();
 
 /*
  * Performs numeric block updates within the relaxed snode. 
diff --git a/superlu/csnode_dfs.c b/superlu/csnode_dfs.c
index 19fb10c..c979aa2 100644
--- a/superlu/csnode_dfs.c
+++ b/superlu/csnode_dfs.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/csp_blas2.c b/superlu/csp_blas2.c
index d1a0a53..f24fa80 100644
--- a/superlu/csp_blas2.c
+++ b/superlu/csp_blas2.c
@@ -7,11 +7,23 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
+/*
  * File name:		csp_blas2.c
  * Purpose:		Sparse BLAS 2, using some dense BLAS 2 operations.
  */
 
 #include "slu_cdefs.h"
+extern void ctrsv_();
+extern void cgemv_();
 
 /* 
  * Function prototypes 
diff --git a/superlu/csp_blas3.c b/superlu/csp_blas3.c
index e11c11d..1f5e628 100644
--- a/superlu/csp_blas3.c
+++ b/superlu/csp_blas3.c
@@ -7,6 +7,28 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:		sp_blas3.c
  * Purpose:		Sparse BLAS3, using some dense BLAS3 operations.
  */
diff --git a/superlu/cutil.c b/superlu/cutil.c
index bb50965..91b45fa 100644
--- a/superlu/cutil.c
+++ b/superlu/cutil.c
@@ -7,16 +7,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <math.h>
@@ -475,7 +472,7 @@ cPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage,
 
 
 
-print_complex_vec(char *what, int n, complex *vec)
+int print_complex_vec(char *what, int n, complex *vec)
 {
     int i;
     printf("%s: n %d\n", what, n);
diff --git a/superlu/dcolumn_bmod.c b/superlu/dcolumn_bmod.c
index cdaecd2..0f4e2b3 100644
--- a/superlu/dcolumn_bmod.c
+++ b/superlu/dcolumn_bmod.c
@@ -7,21 +7,20 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_ddefs.h"
+extern void dtrsv_();
+extern void dgemv_();
 
 /* 
  * Function prototypes 
diff --git a/superlu/dcolumn_dfs.c b/superlu/dcolumn_dfs.c
index c644ef7..f62ab50 100644
--- a/superlu/dcolumn_dfs.c
+++ b/superlu/dcolumn_dfs.c
@@ -7,18 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
+
 #include "slu_ddefs.h"
 
 /* What type of supernodes we want */
diff --git a/superlu/dcomplex.c b/superlu/dcomplex.c
index 396c15c..b8e41c7 100644
--- a/superlu/dcomplex.c
+++ b/superlu/dcomplex.c
@@ -7,6 +7,16 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
+/*
  * This file defines common arithmetic operations for complex type.
  */
 #include <math.h>
diff --git a/superlu/dcopy_to_ucol.c b/superlu/dcopy_to_ucol.c
index 453e33a..4d2bed0 100644
--- a/superlu/dcopy_to_ucol.c
+++ b/superlu/dcopy_to_ucol.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/dgscon.c b/superlu/dgscon.c
index 059da61..2e8e81b 100644
--- a/superlu/dgscon.c
+++ b/superlu/dgscon.c
@@ -7,6 +7,16 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
+/*
  * File name:	dgscon.c
  * History:     Modified from lapack routines DGECON.
  */
diff --git a/superlu/dgsequ.c b/superlu/dgsequ.c
index 0daee10..dcd42a5 100644
--- a/superlu/dgsequ.c
+++ b/superlu/dgsequ.c
@@ -7,6 +7,28 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:	dgsequ.c
  * History:     Modified from LAPACK routine DGEEQU
  */
diff --git a/superlu/dgsrfs.c b/superlu/dgsrfs.c
index a71cc38..c92aecd 100644
--- a/superlu/dgsrfs.c
+++ b/superlu/dgsrfs.c
@@ -7,6 +7,16 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
+/*
  * File name:	dgsrfs.c
  * History:     Modified from lapack routine DGERFS
  */
diff --git a/superlu/dgssv.c b/superlu/dgssv.c
index 99e84dd..25469f4 100644
--- a/superlu/dgssv.c
+++ b/superlu/dgssv.c
@@ -6,6 +6,16 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
 #include "slu_ddefs.h"
 
 void
diff --git a/superlu/dgssvx.c b/superlu/dgssvx.c
index 94c7c07..bc7efc3 100644
--- a/superlu/dgssvx.c
+++ b/superlu/dgssvx.c
@@ -6,6 +6,16 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
 #include "slu_ddefs.h"
 
 void
diff --git a/superlu/dgstrf.c b/superlu/dgstrf.c
index 198c9b7..035e624 100644
--- a/superlu/dgstrf.c
+++ b/superlu/dgstrf.c
@@ -7,16 +7,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_ddefs.h"
diff --git a/superlu/dgstrs.c b/superlu/dgstrs.c
index 04cb38d..8735b87 100644
--- a/superlu/dgstrs.c
+++ b/superlu/dgstrs.c
@@ -7,20 +7,18 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_ddefs.h"
-
+extern void dtrsm_();
+extern void dgemm_();
 
 /* 
  * Function prototypes 
diff --git a/superlu/dlacon.c b/superlu/dlacon.c
index 932b891..26d2122 100644
--- a/superlu/dlacon.c
+++ b/superlu/dlacon.c
@@ -6,6 +6,28 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 #include <math.h>
 #include "slu_Cnames.h"
 
diff --git a/superlu/dlamch.c b/superlu/dlamch.c
index 15a6461..e01db46 100644
--- a/superlu/dlamch.c
+++ b/superlu/dlamch.c
@@ -10,9 +10,48 @@
 double dlamch_(char *cmach)
 {
 /*  -- LAPACK auxiliary routine (version 2.0) --   
-       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
-       Courant Institute, Argonne National Lab, and Rice University   
-       October 31, 1992   
+       Copyright (c) 1992-2013 The University of Tennessee and The University
+                        of Tennessee Research Foundation.  All rights
+                        reserved.
+       Copyright (c) 2000-2013 The University of California Berkeley. All
+                        rights reserved.
+       Copyright (c) 2006-2013 The University of Colorado Denver.  All rights
+                        reserved.
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are
+       met:
+
+       - Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+
+       - Redistributions in binary form must reproduce the above copyright
+         notice, this list of conditions and the following disclaimer listed
+         in this license in the documentation and/or other materials
+         provided with the distribution.
+
+       - Neither the name of the copyright holders nor the names of its
+         contributors may be used to endorse or promote products derived from
+         this software without specific prior written permission.
+
+       The copyright holders provide no reassurances that the source code
+       provided does not infringe any patent, copyright, or any other
+       intellectual property rights of third parties.  The copyright holders
+       disclaim any liability to any recipient for claims brought against
+       recipient by any third party for infringement of that parties
+       intellectual property rights.
+
+       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+       "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+       LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+       A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+       OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+       SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+       LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+       DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+       THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+       OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
     Purpose   
     =======   
diff --git a/superlu/dlangs.c b/superlu/dlangs.c
index 1dd5dfc..811fb47 100644
--- a/superlu/dlangs.c
+++ b/superlu/dlangs.c
@@ -7,6 +7,28 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:	dlangs.c
  * History:     Modified from lapack routine DLANGE
  */
diff --git a/superlu/dlaqgs.c b/superlu/dlaqgs.c
index 6a7a7b8..807a5c1 100644
--- a/superlu/dlaqgs.c
+++ b/superlu/dlaqgs.c
@@ -7,6 +7,28 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:	dlaqgs.c
  * History:     Modified from LAPACK routine DLAQGE
  */
diff --git a/superlu/dmemory.c b/superlu/dmemory.c
index c56cb10..4ca2336 100644
--- a/superlu/dmemory.c
+++ b/superlu/dmemory.c
@@ -6,6 +6,16 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
 #include "slu_ddefs.h"
 
 /* Constants */
diff --git a/superlu/dmyblas2.c b/superlu/dmyblas2.c
index e02660a..c5dad34 100644
--- a/superlu/dmyblas2.c
+++ b/superlu/dmyblas2.c
@@ -7,6 +7,28 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:		dmyblas2.c
  * Purpose:
  *     Level 2 BLAS operations: solves and matvec, written in C.
diff --git a/superlu/dpanel_bmod.c b/superlu/dpanel_bmod.c
index 0019fe8..0e1cc00 100644
--- a/superlu/dpanel_bmod.c
+++ b/superlu/dpanel_bmod.c
@@ -7,21 +7,20 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_ddefs.h"
+extern void dtrsv_();
+extern void dgemv_();
 
 /* 
  * Function prototypes 
diff --git a/superlu/dpanel_dfs.c b/superlu/dpanel_dfs.c
index 6a4c742..75783bc 100644
--- a/superlu/dpanel_dfs.c
+++ b/superlu/dpanel_dfs.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/dpivotL.c b/superlu/dpivotL.c
index bf43e6a..6ba206b 100644
--- a/superlu/dpivotL.c
+++ b/superlu/dpivotL.c
@@ -7,16 +7,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <math.h>
diff --git a/superlu/dpivotgrowth.c b/superlu/dpivotgrowth.c
index 41924f7..6e64119 100644
--- a/superlu/dpivotgrowth.c
+++ b/superlu/dpivotgrowth.c
@@ -6,6 +6,28 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 #include <math.h>
 #include "slu_ddefs.h"
 
diff --git a/superlu/dpruneL.c b/superlu/dpruneL.c
index c782ca1..670d061 100644
--- a/superlu/dpruneL.c
+++ b/superlu/dpruneL.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/dreadhb.c b/superlu/dreadhb.c
index 4956352..fb22c54 100644
--- a/superlu/dreadhb.c
+++ b/superlu/dreadhb.c
@@ -6,6 +6,28 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_ddefs.h"
diff --git a/superlu/dsnode_bmod.c b/superlu/dsnode_bmod.c
index ec06144..e2bac68 100644
--- a/superlu/dsnode_bmod.c
+++ b/superlu/dsnode_bmod.c
@@ -7,20 +7,18 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_ddefs.h"
-
+extern void dtrsv_();
+extern void dgemv_();
 
 /*
  * Performs numeric block updates within the relaxed snode. 
diff --git a/superlu/dsnode_dfs.c b/superlu/dsnode_dfs.c
index 3823e85..d1c3c48 100644
--- a/superlu/dsnode_dfs.c
+++ b/superlu/dsnode_dfs.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/dsp_blas2.c b/superlu/dsp_blas2.c
index 05ed9d9..5ef8c22 100644
--- a/superlu/dsp_blas2.c
+++ b/superlu/dsp_blas2.c
@@ -7,11 +7,23 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+
+/*
  * File name:		dsp_blas2.c
  * Purpose:		Sparse BLAS 2, using some dense BLAS 2 operations.
  */
 
 #include "slu_ddefs.h"
+extern void dtrsv_();
+extern void dgemv_();
 
 /* 
  * Function prototypes 
diff --git a/superlu/dsp_blas3.c b/superlu/dsp_blas3.c
index 3aaf3c7..00d200a 100644
--- a/superlu/dsp_blas3.c
+++ b/superlu/dsp_blas3.c
@@ -7,6 +7,28 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:		sp_blas3.c
  * Purpose:		Sparse BLAS3, using some dense BLAS3 operations.
  */
diff --git a/superlu/dutil.c b/superlu/dutil.c
index 6956c29..bb4c5c4 100644
--- a/superlu/dutil.c
+++ b/superlu/dutil.c
@@ -7,18 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
+
 #include <math.h>
 #include "slu_ddefs.h"
 
@@ -471,7 +469,7 @@ dPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage,
 
 
 
-print_double_vec(char *what, int n, double *vec)
+int print_double_vec(char *what, int n, double *vec)
 {
     int i;
     printf("%s: n %d\n", what, n);
diff --git a/superlu/dzsum1.c b/superlu/dzsum1.c
index 1f0c8a8..d968326 100644
--- a/superlu/dzsum1.c
+++ b/superlu/dzsum1.c
@@ -3,10 +3,28 @@
 
 double dzsum1_(int *n, doublecomplex *cx, int *incx)
 {
-/*  -- LAPACK auxiliary routine (version 2.0) --   
-       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
-       Courant Institute, Argonne National Lab, and Rice University   
-       October 31, 1992   
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*! @file dzsum1.c
+ * \brief Takes sum of the absolute values of a complex vector and returns a double precision result
+ *
+ * <pre>
+ *     -- LAPACK auxiliary routine (version 2.0) --   
+ *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
+ *     Courant Institute, Argonne National Lab, and Rice University   
+ *     October 31, 1992   
+ * </pre>
+ */
+/*
+
+
 
     Purpose   
     =======   
diff --git a/superlu/f2c_lite.c b/superlu/f2c_lite.c
index 94733b0..7dfb0d7 100644
--- a/superlu/f2c_lite.c
+++ b/superlu/f2c_lite.c
@@ -1,3 +1,18 @@
+/*
+  Copyright: 1992-2007 The University of Tennessee.  All rights reserved.
+  License:
+    LAPACK is a freely-available software package. It is available from
+    netlib via anonymous ftp and the World Wide Web. Thus, it can be
+    included in commercial software packages (and has been). We only ask
+    that proper credit be given to the authors.
+ 
+    Like all software, it is copyrighted. It is not trademarked, but we do
+    ask the following:
+
+    If you modify the source for these routines we ask that you change the
+    name of the routine and comment the changes made to the original.
+*/
+
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/superlu/get_perm_c.c b/superlu/get_perm_c.c
index fa8fe6b..dd6558a 100644
--- a/superlu/get_perm_c.c
+++ b/superlu/get_perm_c.c
@@ -5,6 +5,28 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 #include "slu_ddefs.h"
 #include "colamd.h"
 
diff --git a/superlu/heap_relax_snode.c b/superlu/heap_relax_snode.c
index 1a40e26..80ed279 100644
--- a/superlu/heap_relax_snode.c
+++ b/superlu/heap_relax_snode.c
@@ -6,16 +6,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_ddefs.h"
diff --git a/superlu/icmax1.c b/superlu/icmax1.c
index 1e254b0..d5d1541 100644
--- a/superlu/icmax1.c
+++ b/superlu/icmax1.c
@@ -4,11 +4,26 @@
 
 int icmax1_(int *n, complex *cx, int *incx)
 {
-/*  -- LAPACK auxiliary routine (version 2.0) --   
-       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
-       Courant Institute, Argonne National Lab, and Rice University   
-       September 30, 1994   
-
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*! @file icmax1.c
+ * \brief Finds the index of the element whose real part has maximum absolute value
+ *
+ * <pre>
+ *     -- LAPACK auxiliary routine (version 2.0) --   
+ *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
+ *     Courant Institute, Argonne National Lab, and Rice University   
+ *     October 31, 1992   
+ * </pre>
+ */
+/*
 
     Purpose   
     =======   
diff --git a/superlu/izmax1.c b/superlu/izmax1.c
index 1a73e1f..75b3279 100644
--- a/superlu/izmax1.c
+++ b/superlu/izmax1.c
@@ -5,12 +5,26 @@
 int
 izmax1_(int *n, doublecomplex *cx, int *incx)
 {
-/*  -- LAPACK auxiliary routine (version 2.0) --   
-       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
-       Courant Institute, Argonne National Lab, and Rice University   
-       September 30, 1994   
-
-
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*! @file izmax1.c
+ * \brief Finds the index of the element whose real part has maximum absolute value
+ *
+ * <pre>
+ *     -- LAPACK auxiliary routine (version 2.0) --   
+ *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
+ *     Courant Institute, Argonne National Lab, and Rice University   
+ *     October 31, 1992   
+ * </pre>
+ */
+/*  
     Purpose   
     =======   
 
diff --git a/superlu/lsame.c b/superlu/lsame.c
index 113c6d0..e235b88 100644
--- a/superlu/lsame.c
+++ b/superlu/lsame.c
@@ -3,9 +3,48 @@
 int lsame_(char *ca, char *cb)
 {
 /*  -- LAPACK auxiliary routine (version 2.0) --   
-       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
-       Courant Institute, Argonne National Lab, and Rice University   
-       September 30, 1994   
+       Copyright (c) 1992-2013 The University of Tennessee and The University
+                        of Tennessee Research Foundation.  All rights
+                        reserved.
+       Copyright (c) 2000-2013 The University of California Berkeley. All
+                        rights reserved.
+       Copyright (c) 2006-2013 The University of Colorado Denver.  All rights
+                        reserved.
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are
+       met:
+
+       - Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+
+       - Redistributions in binary form must reproduce the above copyright
+         notice, this list of conditions and the following disclaimer listed
+         in this license in the documentation and/or other materials
+         provided with the distribution.
+
+       - Neither the name of the copyright holders nor the names of its
+         contributors may be used to endorse or promote products derived from
+         this software without specific prior written permission.
+
+       The copyright holders provide no reassurances that the source code
+       provided does not infringe any patent, copyright, or any other
+       intellectual property rights of third parties.  The copyright holders
+       disclaim any liability to any recipient for claims brought against
+       recipient by any third party for infringement of that parties
+       intellectual property rights.
+
+       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+       "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+       LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+       A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+       OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+       SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+       LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+       DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+       THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+       OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
     Purpose   
     =======   
diff --git a/superlu/memory.c b/superlu/memory.c
index 25868f6..c614e14 100644
--- a/superlu/memory.c
+++ b/superlu/memory.c
@@ -5,6 +5,28 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 /** Precision-independent memory-related routines.
     (Shared by [sdcz]memory.c) **/
 
diff --git a/superlu/mmd.c b/superlu/mmd.c
index 05f26ce..1fb196c 100644
--- a/superlu/mmd.c
+++ b/superlu/mmd.c
@@ -1,3 +1,12 @@
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 
 typedef int shortint;
 
diff --git a/superlu/relax_snode.c b/superlu/relax_snode.c
index ef20127..8937ac0 100644
--- a/superlu/relax_snode.c
+++ b/superlu/relax_snode.c
@@ -6,7 +6,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/scolumn_bmod.c b/superlu/scolumn_bmod.c
index 303b3d4..64a1d0b 100644
--- a/superlu/scolumn_bmod.c
+++ b/superlu/scolumn_bmod.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
@@ -22,6 +31,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_sdefs.h"
+extern void strsv_();
+extern void sgemv_();
+
 
 /* 
  * Function prototypes 
diff --git a/superlu/scolumn_dfs.c b/superlu/scolumn_dfs.c
index 923b25d..a9bd3c2 100644
--- a/superlu/scolumn_dfs.c
+++ b/superlu/scolumn_dfs.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/scomplex.c b/superlu/scomplex.c
index d353281..d916f06 100644
--- a/superlu/scomplex.c
+++ b/superlu/scomplex.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * This file defines common arithmetic operations for complex type.
  */
 #include <math.h>
diff --git a/superlu/scopy_to_ucol.c b/superlu/scopy_to_ucol.c
index daed16a..44a237e 100644
--- a/superlu/scopy_to_ucol.c
+++ b/superlu/scopy_to_ucol.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/scsum1.c b/superlu/scsum1.c
index 5ab8fc2..42ebfe3 100644
--- a/superlu/scsum1.c
+++ b/superlu/scsum1.c
@@ -3,11 +3,26 @@
 
 double scsum1_(int *n, complex *cx, int *incx)
 {
-/*  -- LAPACK auxiliary routine (version 2.0) --   
-       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
-       Courant Institute, Argonne National Lab, and Rice University   
-       October 31, 1992   
-
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*! @file scsum1.c
+ * \brief Takes sum of the absolute values of a complex vector and returns a single precision result
+ *
+ * <pre>
+ *     -- LAPACK auxiliary routine (version 2.0) --   
+ *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
+ *     Courant Institute, Argonne National Lab, and Rice University   
+ *     October 31, 1992   
+ * </pre>
+ */
+/* 
 
     Purpose   
     =======   
diff --git a/superlu/sgscon.c b/superlu/sgscon.c
index 9080602..cc44712 100644
--- a/superlu/sgscon.c
+++ b/superlu/sgscon.c
@@ -7,6 +7,15 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
  * File name:	sgscon.c
  * History:     Modified from lapack routines SGECON.
  */
diff --git a/superlu/sgsequ.c b/superlu/sgsequ.c
index 10a2ffc..b24e147 100644
--- a/superlu/sgsequ.c
+++ b/superlu/sgsequ.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:	sgsequ.c
  * History:     Modified from LAPACK routine SGEEQU
  */
diff --git a/superlu/sgsrfs.c b/superlu/sgsrfs.c
index 9d03b04..c95c443 100644
--- a/superlu/sgsrfs.c
+++ b/superlu/sgsrfs.c
@@ -7,6 +7,15 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
  * File name:	sgsrfs.c
  * History:     Modified from lapack routine SGERFS
  */
diff --git a/superlu/sgssv.c b/superlu/sgssv.c
index 2e622bf..3c65780 100644
--- a/superlu/sgssv.c
+++ b/superlu/sgssv.c
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #include "slu_sdefs.h"
 
 void
diff --git a/superlu/sgssvx.c b/superlu/sgssvx.c
index f611b9f..c8392ab 100644
--- a/superlu/sgssvx.c
+++ b/superlu/sgssvx.c
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #include "slu_sdefs.h"
 
 void
diff --git a/superlu/sgstrf.c b/superlu/sgstrf.c
index b65f93d..4da4204 100644
--- a/superlu/sgstrf.c
+++ b/superlu/sgstrf.c
@@ -7,19 +7,17 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
-*/
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
 
+The source code is distributed under BSD license, see the file License.txt
+*/
 #include "slu_sdefs.h"
+extern void countnz();
+extern void fixupL();
 
 void
 sgstrf (superlu_options_t *options, SuperMatrix *A, float drop_tol,
diff --git a/superlu/sgstrs.c b/superlu/sgstrs.c
index 367e088..7e2c6ec 100644
--- a/superlu/sgstrs.c
+++ b/superlu/sgstrs.c
@@ -7,19 +7,18 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_sdefs.h"
+extern void strsm_();
+extern void sgemm_();
 
 
 /* 
diff --git a/superlu/slacon.c b/superlu/slacon.c
index ccf4d3a..27b7d40 100644
--- a/superlu/slacon.c
+++ b/superlu/slacon.c
@@ -6,6 +6,27 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #include <math.h>
 #include "slu_Cnames.h"
 
diff --git a/superlu/slamch.c b/superlu/slamch.c
index 2952222..08148e2 100644
--- a/superlu/slamch.c
+++ b/superlu/slamch.c
@@ -11,9 +11,48 @@
 double slamch_(char *cmach)
 {
 /*  -- LAPACK auxiliary routine (version 2.0) --   
-       Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
-       Courant Institute, Argonne National Lab, and Rice University   
-       October 31, 1992   
+       Copyright (c) 1992-2013 The University of Tennessee and The University
+                        of Tennessee Research Foundation.  All rights
+                        reserved.
+       Copyright (c) 2000-2013 The University of California Berkeley. All
+                        rights reserved.
+       Copyright (c) 2006-2013 The University of Colorado Denver.  All rights
+                        reserved.
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are
+       met:
+
+       - Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+
+       - Redistributions in binary form must reproduce the above copyright
+         notice, this list of conditions and the following disclaimer listed
+         in this license in the documentation and/or other materials
+         provided with the distribution.
+
+       - Neither the name of the copyright holders nor the names of its
+         contributors may be used to endorse or promote products derived from
+         this software without specific prior written permission.
+
+       The copyright holders provide no reassurances that the source code
+       provided does not infringe any patent, copyright, or any other
+       intellectual property rights of third parties.  The copyright holders
+       disclaim any liability to any recipient for claims brought against
+       recipient by any third party for infringement of that parties
+       intellectual property rights.
+
+       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+       "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+       LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+       A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+       OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+       SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+       LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+       DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+       THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+       OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
     Purpose   
diff --git a/superlu/slangs.c b/superlu/slangs.c
index a680db4..f82368f 100644
--- a/superlu/slangs.c
+++ b/superlu/slangs.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:	slangs.c
  * History:     Modified from lapack routine SLANGE
  */
diff --git a/superlu/slaqgs.c b/superlu/slaqgs.c
index f65931e..083d665 100644
--- a/superlu/slaqgs.c
+++ b/superlu/slaqgs.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:	slaqgs.c
  * History:     Modified from LAPACK routine SLAQGE
  */
diff --git a/superlu/slu_Cnames.h b/superlu/slu_Cnames.h
index 8b8df4e..7c8e7dd 100644
--- a/superlu/slu_Cnames.h
+++ b/superlu/slu_Cnames.h
@@ -5,6 +5,27 @@
  * November 1, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #ifndef __SUPERLU_CNAMES /* allow multiple inclusions */
 #define __SUPERLU_CNAMES
 
diff --git a/superlu/slu_cdefs.h b/superlu/slu_cdefs.h
index 3cef9dc..ade6a02 100644
--- a/superlu/slu_cdefs.h
+++ b/superlu/slu_cdefs.h
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #ifndef __SUPERLU_cSP_DEFS /* allow multiple inclusions */
 #define __SUPERLU_cSP_DEFS
 
diff --git a/superlu/slu_dcomplex.h b/superlu/slu_dcomplex.h
index 04de089..68dc1ce 100644
--- a/superlu/slu_dcomplex.h
+++ b/superlu/slu_dcomplex.h
@@ -6,6 +6,27 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #ifndef __SUPERLU_DCOMPLEX /* allow multiple inclusions */
 #define __SUPERLU_DCOMPLEX
 
diff --git a/superlu/slu_ddefs.h b/superlu/slu_ddefs.h
index 292622f..de3f7e8 100644
--- a/superlu/slu_ddefs.h
+++ b/superlu/slu_ddefs.h
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #ifndef __SUPERLU_dSP_DEFS /* allow multiple inclusions */
 #define __SUPERLU_dSP_DEFS
 
diff --git a/superlu/slu_scomplex.h b/superlu/slu_scomplex.h
index d7d70f1..4f653b1 100644
--- a/superlu/slu_scomplex.h
+++ b/superlu/slu_scomplex.h
@@ -6,6 +6,27 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #ifndef __SUPERLU_SCOMPLEX /* allow multiple inclusions */
 #define __SUPERLU_SCOMPLEX
 
diff --git a/superlu/slu_sdefs.h b/superlu/slu_sdefs.h
index 24bce4f..5177d5c 100644
--- a/superlu/slu_sdefs.h
+++ b/superlu/slu_sdefs.h
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #ifndef __SUPERLU_sSP_DEFS /* allow multiple inclusions */
 #define __SUPERLU_sSP_DEFS
 
diff --git a/superlu/slu_util.h b/superlu/slu_util.h
index bf115c6..afed257 100644
--- a/superlu/slu_util.h
+++ b/superlu/slu_util.h
@@ -1,3 +1,25 @@
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 #ifndef __SUPERLU_UTIL /* allow multiple inclusions */
 #define __SUPERLU_UTIL
 
diff --git a/superlu/slu_zdefs.h b/superlu/slu_zdefs.h
index d26a6cb..2659d6a 100644
--- a/superlu/slu_zdefs.h
+++ b/superlu/slu_zdefs.h
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #ifndef __SUPERLU_zSP_DEFS /* allow multiple inclusions */
 #define __SUPERLU_zSP_DEFS
 
diff --git a/superlu/smemory.c b/superlu/smemory.c
index 0278615..0f2fbda 100644
--- a/superlu/smemory.c
+++ b/superlu/smemory.c
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #include "slu_sdefs.h"
 
 /* Constants */
diff --git a/superlu/smyblas2.c b/superlu/smyblas2.c
index 00f65c5..8e9bb09 100644
--- a/superlu/smyblas2.c
+++ b/superlu/smyblas2.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:		smyblas2.c
  * Purpose:
  *     Level 2 BLAS operations: solves and matvec, written in C.
diff --git a/superlu/sp_coletree.c b/superlu/sp_coletree.c
index 1685661..4848708 100644
--- a/superlu/sp_coletree.c
+++ b/superlu/sp_coletree.c
@@ -1,4 +1,26 @@
 
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 /*  Elimination tree computation and layout routines */
 
 #include <stdio.h>
diff --git a/superlu/sp_ienv.c b/superlu/sp_ienv.c
index 0680e02..66a854d 100644
--- a/superlu/sp_ienv.c
+++ b/superlu/sp_ienv.c
@@ -1,8 +1,31 @@
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
+/*
  * File name:		sp_ienv.c
  * History:             Modified from lapack routine ILAENV
  */
 #include "slu_Cnames.h"
+extern void xerbla_();
 
 int
 sp_ienv(int ispec)
diff --git a/superlu/sp_preorder.c b/superlu/sp_preorder.c
index 524a8ee..cd1a526 100644
--- a/superlu/sp_preorder.c
+++ b/superlu/sp_preorder.c
@@ -1,3 +1,24 @@
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #include "slu_ddefs.h"
 
 void
diff --git a/superlu/spanel_bmod.c b/superlu/spanel_bmod.c
index e98ac9b..91bbb73 100644
--- a/superlu/spanel_bmod.c
+++ b/superlu/spanel_bmod.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
@@ -22,6 +31,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_sdefs.h"
+extern void strsv_();
+extern void sgemv_();
+
 
 /* 
  * Function prototypes 
diff --git a/superlu/spanel_dfs.c b/superlu/spanel_dfs.c
index cb4417c..d32af40 100644
--- a/superlu/spanel_dfs.c
+++ b/superlu/spanel_dfs.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/spivotL.c b/superlu/spivotL.c
index 9c300a4..ee66dbc 100644
--- a/superlu/spivotL.c
+++ b/superlu/spivotL.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/spivotgrowth.c b/superlu/spivotgrowth.c
index 6aac212..05a2446 100644
--- a/superlu/spivotgrowth.c
+++ b/superlu/spivotgrowth.c
@@ -6,6 +6,28 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+
 #include <math.h>
 #include "slu_sdefs.h"
 
diff --git a/superlu/spruneL.c b/superlu/spruneL.c
index 6a32424..0d5755f 100644
--- a/superlu/spruneL.c
+++ b/superlu/spruneL.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/sreadhb.c b/superlu/sreadhb.c
index 31a35bf..938f30a 100644
--- a/superlu/sreadhb.c
+++ b/superlu/sreadhb.c
@@ -6,6 +6,27 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_sdefs.h"
diff --git a/superlu/ssnode_bmod.c b/superlu/ssnode_bmod.c
index 6ba0f52..a476dd5 100644
--- a/superlu/ssnode_bmod.c
+++ b/superlu/ssnode_bmod.c
@@ -7,19 +7,18 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_sdefs.h"
+extern void strsv_();
+extern void sgemv_();
 
 
 /*
diff --git a/superlu/ssnode_dfs.c b/superlu/ssnode_dfs.c
index eb14fc0..b1536c2 100644
--- a/superlu/ssnode_dfs.c
+++ b/superlu/ssnode_dfs.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/ssp_blas2.c b/superlu/ssp_blas2.c
index 174db34..0e14c00 100644
--- a/superlu/ssp_blas2.c
+++ b/superlu/ssp_blas2.c
@@ -7,11 +7,22 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
  * File name:		ssp_blas2.c
  * Purpose:		Sparse BLAS 2, using some dense BLAS 2 operations.
  */
 
 #include "slu_sdefs.h"
+extern void strsv_();
+extern void sgemv_();
 
 /* 
  * Function prototypes 
diff --git a/superlu/ssp_blas3.c b/superlu/ssp_blas3.c
index 6a416a5..f958ac8 100644
--- a/superlu/ssp_blas3.c
+++ b/superlu/ssp_blas3.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:		sp_blas3.c
  * Purpose:		Sparse BLAS3, using some dense BLAS3 operations.
  */
diff --git a/superlu/superlu_timer.c b/superlu/superlu_timer.c
index fb1deae..dedf19e 100644
--- a/superlu/superlu_timer.c
+++ b/superlu/superlu_timer.c
@@ -1,3 +1,24 @@
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 /* 
  * Purpose
  * ======= 
diff --git a/superlu/supermatrix.h b/superlu/supermatrix.h
index fccc6ee..c3dd640 100644
--- a/superlu/supermatrix.h
+++ b/superlu/supermatrix.h
@@ -1,3 +1,24 @@
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #ifndef __SUPERLU_SUPERMATRIX /* allow multiple inclusions */
 #define __SUPERLU_SUPERMATRIX
 
diff --git a/superlu/sutil.c b/superlu/sutil.c
index a023a3f..09b51d4 100644
--- a/superlu/sutil.c
+++ b/superlu/sutil.c
@@ -7,16 +7,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <math.h>
@@ -471,7 +468,7 @@ sPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage,
 
 
 
-print_float_vec(char *what, int n, float *vec)
+int print_float_vec(char *what, int n, float *vec)
 {
     int i;
     printf("%s: n %d\n", what, n);
diff --git a/superlu/util.c b/superlu/util.c
index 0ea0051..c803162 100644
--- a/superlu/util.c
+++ b/superlu/util.c
@@ -6,16 +6,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <math.h>
diff --git a/superlu/zcolumn_bmod.c b/superlu/zcolumn_bmod.c
index 2082ad6..f5168ba 100644
--- a/superlu/zcolumn_bmod.c
+++ b/superlu/zcolumn_bmod.c
@@ -7,21 +7,21 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_zdefs.h"
+extern void ztrsv_();
+extern void zgemv_();
+
 
 /* 
  * Function prototypes 
diff --git a/superlu/zcolumn_dfs.c b/superlu/zcolumn_dfs.c
index 92a20e2..0c7f5a0 100644
--- a/superlu/zcolumn_dfs.c
+++ b/superlu/zcolumn_dfs.c
@@ -7,16 +7,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_zdefs.h"
diff --git a/superlu/zcopy_to_ucol.c b/superlu/zcopy_to_ucol.c
index e5731cf..375a50b 100644
--- a/superlu/zcopy_to_ucol.c
+++ b/superlu/zcopy_to_ucol.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/zgscon.c b/superlu/zgscon.c
index 4e254c8..2014c9c 100644
--- a/superlu/zgscon.c
+++ b/superlu/zgscon.c
@@ -7,6 +7,15 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
  * File name:	zgscon.c
  * History:     Modified from lapack routines ZGECON.
  */
diff --git a/superlu/zgsequ.c b/superlu/zgsequ.c
index 40e64e9..4f9f520 100644
--- a/superlu/zgsequ.c
+++ b/superlu/zgsequ.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:	zgsequ.c
  * History:     Modified from LAPACK routine ZGEEQU
  */
diff --git a/superlu/zgsrfs.c b/superlu/zgsrfs.c
index 9cb57fd..e87c361 100644
--- a/superlu/zgsrfs.c
+++ b/superlu/zgsrfs.c
@@ -7,6 +7,15 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
  * File name:	zgsrfs.c
  * History:     Modified from lapack routine ZGERFS
  */
diff --git a/superlu/zgssv.c b/superlu/zgssv.c
index dbbd870..73bf9a8 100644
--- a/superlu/zgssv.c
+++ b/superlu/zgssv.c
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #include "slu_zdefs.h"
 
 void
diff --git a/superlu/zgssvx.c b/superlu/zgssvx.c
index 65ea538..09979b5 100644
--- a/superlu/zgssvx.c
+++ b/superlu/zgssvx.c
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #include "slu_zdefs.h"
 
 void
diff --git a/superlu/zgstrf.c b/superlu/zgstrf.c
index 5cfef9b..1aaec38 100644
--- a/superlu/zgstrf.c
+++ b/superlu/zgstrf.c
@@ -7,19 +7,18 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_zdefs.h"
+extern void countnz();
+extern void fixupL();
 
 void
 zgstrf (superlu_options_t *options, SuperMatrix *A, double drop_tol,
diff --git a/superlu/zgstrs.c b/superlu/zgstrs.c
index cfa720f..e415e47 100644
--- a/superlu/zgstrs.c
+++ b/superlu/zgstrs.c
@@ -7,19 +7,18 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include "slu_zdefs.h"
+extern void ztrsm_();
+extern void zgemm_();
 
 
 /* 
diff --git a/superlu/zlacon.c b/superlu/zlacon.c
index 19382a2..33822b3 100644
--- a/superlu/zlacon.c
+++ b/superlu/zlacon.c
@@ -6,9 +6,32 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #include <math.h>
 #include "slu_Cnames.h"
 #include "slu_dcomplex.h"
+extern void zcopy_();
+
 
 int
 zlacon_(int *n, doublecomplex *v, doublecomplex *x, double *est, int *kase)
diff --git a/superlu/zlangs.c b/superlu/zlangs.c
index ad09d3d..bb3f95a 100644
--- a/superlu/zlangs.c
+++ b/superlu/zlangs.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:	zlangs.c
  * History:     Modified from lapack routine ZLANGE
  */
diff --git a/superlu/zlaqgs.c b/superlu/zlaqgs.c
index 5b9d503..1753737 100644
--- a/superlu/zlaqgs.c
+++ b/superlu/zlaqgs.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:	zlaqgs.c
  * History:     Modified from LAPACK routine ZLAQGE
  */
diff --git a/superlu/zmemory.c b/superlu/zmemory.c
index 02ac640..36968d6 100644
--- a/superlu/zmemory.c
+++ b/superlu/zmemory.c
@@ -6,6 +6,15 @@
  * October 15, 2003
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
 #include "slu_zdefs.h"
 
 /* Constants */
diff --git a/superlu/zmyblas2.c b/superlu/zmyblas2.c
index 45c67c1..5f2f324 100644
--- a/superlu/zmyblas2.c
+++ b/superlu/zmyblas2.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:		zmyblas2.c
  * Purpose:
  *     Level 2 BLAS operations: solves and matvec, written in C.
diff --git a/superlu/zpanel_bmod.c b/superlu/zpanel_bmod.c
index f910635..ba9dc0e 100644
--- a/superlu/zpanel_bmod.c
+++ b/superlu/zpanel_bmod.c
@@ -7,21 +7,20 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_zdefs.h"
+extern void ztrsv_();
+extern void zgemv_();
 
 /* 
  * Function prototypes 
diff --git a/superlu/zpanel_dfs.c b/superlu/zpanel_dfs.c
index 3e535a8..4fbc963 100644
--- a/superlu/zpanel_dfs.c
+++ b/superlu/zpanel_dfs.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/zpivotL.c b/superlu/zpivotL.c
index 20aacda..484ebfa 100644
--- a/superlu/zpivotL.c
+++ b/superlu/zpivotL.c
@@ -7,16 +7,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <math.h>
diff --git a/superlu/zpivotgrowth.c b/superlu/zpivotgrowth.c
index b8afeef..1d598cf 100644
--- a/superlu/zpivotgrowth.c
+++ b/superlu/zpivotgrowth.c
@@ -6,6 +6,27 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #include <math.h>
 #include "slu_zdefs.h"
 
diff --git a/superlu/zpruneL.c b/superlu/zpruneL.c
index 25d003c..854038d 100644
--- a/superlu/zpruneL.c
+++ b/superlu/zpruneL.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/zreadhb.c b/superlu/zreadhb.c
index ed81ef9..0522a67 100644
--- a/superlu/zreadhb.c
+++ b/superlu/zreadhb.c
@@ -6,6 +6,27 @@
  * November 15, 1997
  *
  */
+/*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
 #include <stdio.h>
 #include <stdlib.h>
 #include "slu_zdefs.h"
diff --git a/superlu/zsnode_bmod.c b/superlu/zsnode_bmod.c
index c36d0fa..e10da82 100644
--- a/superlu/zsnode_bmod.c
+++ b/superlu/zsnode_bmod.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
@@ -20,6 +29,8 @@
 */
 
 #include "slu_zdefs.h"
+extern void ztrsv_();
+extern void zgemv_();
 
 
 /*
diff --git a/superlu/zsnode_dfs.c b/superlu/zsnode_dfs.c
index a6bab8f..c860a6f 100644
--- a/superlu/zsnode_dfs.c
+++ b/superlu/zsnode_dfs.c
@@ -7,7 +7,16 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
  
   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
diff --git a/superlu/zsp_blas2.c b/superlu/zsp_blas2.c
index e94c519..525f753 100644
--- a/superlu/zsp_blas2.c
+++ b/superlu/zsp_blas2.c
@@ -7,11 +7,22 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
  * File name:		zsp_blas2.c
  * Purpose:		Sparse BLAS 2, using some dense BLAS 2 operations.
  */
 
 #include "slu_zdefs.h"
+extern void ztrsv_();
+extern void zgemv_();
 
 /* 
  * Function prototypes 
diff --git a/superlu/zsp_blas3.c b/superlu/zsp_blas3.c
index 5dddf5a..7a815e2 100644
--- a/superlu/zsp_blas3.c
+++ b/superlu/zsp_blas3.c
@@ -7,6 +7,27 @@
  *
  */
 /*
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
+*/
+/*
+  Copyright (c) 1997 by Xerox Corporation.  All rights reserved.
+ 
+  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ 
+  Permission is hereby granted to use or copy this program for any
+  purpose, provided the above notices are retained on all copies.
+  Permission to modify the code and to distribute modified code is
+  granted, provided the above notices are retained, and a notice that
+  the code was modified is included with the above copyright notice.
+*/
+/*
  * File name:		sp_blas3.c
  * Purpose:		Sparse BLAS3, using some dense BLAS3 operations.
  */
diff --git a/superlu/zutil.c b/superlu/zutil.c
index 8e9dcba..30bcca7 100644
--- a/superlu/zutil.c
+++ b/superlu/zutil.c
@@ -7,16 +7,13 @@
  *
  */
 /*
-  Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
- 
-  THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
-  EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
- 
-  Permission is hereby granted to use or copy this program for any
-  purpose, provided the above notices are retained on all copies.
-  Permission to modify the code and to distribute modified code is
-  granted, provided the above notices are retained, and a notice that
-  the code was modified is included with the above copyright notice.
+Copyright (c) 2003, The Regents of the University of California, through
+Lawrence Berkeley National Laboratory (subject to receipt of any required 
+approvals from U.S. Dept. of Energy) 
+
+All rights reserved. 
+
+The source code is distributed under BSD license, see the file License.txt
 */
 
 #include <math.h>
@@ -475,7 +472,7 @@ zPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage,
 
 
 
-print_doublecomplex_vec(char *what, int n, doublecomplex *vec)
+int print_doublecomplex_vec(char *what, int n, doublecomplex *vec)
 {
     int i;
     printf("%s: n %d\n", what, n);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d64a01c..4e9d42f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,3 +1,20 @@
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+
 if QHULL
 optprogs = test_mesh_generation test_mesh_im_level_set crack thermo_elasticity_electrical_coupling
 optpl = test_mesh_im_level_set.pl \
diff --git a/tests/Makefile.in b/tests/Makefile.in
index b2689b3..d4d517f 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -13,18 +13,25 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
+
+#  Copyright (C) 1999-2017 Yves Renard
+#
+#  This file is a part of GetFEM++
+#
+#  GetFEM++  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 along with the GCC Runtime Library
+#  Exception either version 3.1 or (at your option) any later version.
+#  This program  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 and GCC Runtime Library Exception for more details.
+#  You  should  have received a copy of the GNU Lesser General Public License
+#  along  with  this program;  if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -115,6 +122,9 @@ TESTS = dynamic_array.pl dynamic_tas.pl test_int_set.pl \
 	wave_equation.pl test_gmm_matrix_functions.pl cyl_slicer.pl \
 	make_gmm_test.pl
 subdir = tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/ax_boost_base.m4 \
@@ -130,7 +140,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_python_devel.m4 \
 	$(top_srcdir)/m4/scilab.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -608,8 +617,6 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
 TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -677,7 +684,6 @@ LIBTOOL_VERSION_INFO = @LIBTOOL_VERSION_INFO@
 LIPO = @LIPO@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MATLAB_COM_EXT = @MATLAB_COM_EXT@
@@ -710,8 +716,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
 PSEUDO_FUNCTIONS = @PSEUDO_FUNCTIONS@
 PSEUDO_FUNCTIONS_LOC = @PSEUDO_FUNCTIONS_LOC@
 PYTHON = @PYTHON@
+PYTHON_CC_ARG = @PYTHON_CC_ARG@
 PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_EXT_PARAM = @PYTHON_EXTRA_EXT_PARAM@
 PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
 PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
 PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
@@ -792,7 +800,6 @@ program_transform_name = @program_transform_name@
 psdir = @psdir@
 pyexecdir = @pyexecdir@
 pythondir = @pythondir@
-runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -964,6 +971,7 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu tests/Makefile
+.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -1292,7 +1300,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
+	else \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1841,8 +1849,6 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	recheck tags tags-am uninstall uninstall-am
 
-.PRECIOUS: Makefile
-
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tests/bilaplacian.cc b/tests/bilaplacian.cc
index d30b467..6151240 100644
--- a/tests/bilaplacian.cc
+++ b/tests/bilaplacian.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2006-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2006-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -313,10 +313,11 @@ void bilaplacian_problem::init(void) {
         un /= gmm::vect_norm2(un);
 	if (un[0] < - 0.5 ) { 
            mesh.region(CLAMPED_BOUNDARY_NUM).add(i.cv(), i.f());
- 	   mesh.region(SIMPLE_SUPPORT_BOUNDARY_NUM).add(i.cv(), i.f()); }
-	else
-	   mesh.region(FORCE_BOUNDARY_NUM).add(i.cv(), i.f());
-           mesh.region(MOMENTUM_BOUNDARY_NUM).add(i.cv(), i.f());
+ 	   mesh.region(SIMPLE_SUPPORT_BOUNDARY_NUM).add(i.cv(), i.f());
+	} else { 
+	  mesh.region(FORCE_BOUNDARY_NUM).add(i.cv(), i.f());
+	  mesh.region(MOMENTUM_BOUNDARY_NUM).add(i.cv(), i.f());
+	}
      }
   }
 }
diff --git a/tests/bilaplacian.param b/tests/bilaplacian.param
index 2856f10..c03e991 100644
--- a/tests/bilaplacian.param
+++ b/tests/bilaplacian.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program bilaplacian                      %
diff --git a/tests/bilaplacian.pl b/tests/bilaplacian.pl
index eccdee9..f8339b2 100644
--- a/tests/bilaplacian.pl
+++ b/tests/bilaplacian.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/crack.cc b/tests/crack.cc
index 349dcb5..98dec6a 100644
--- a/tests/crack.cc
+++ b/tests/crack.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -42,6 +42,8 @@
 
 using std::endl; using std::cout; using std::cerr;
 using std::ends; using std::cin;
+template <typename T> std::ostream &operator <<
+  (std::ostream &o, const std::vector<T>& m) { gmm::write(o,m); return o; }
 
 /* some GetFEM++ types that we will be using */
 using bgeot::base_small_vector; /* special class for small (dim<16) vectors */
@@ -229,13 +231,13 @@ void sol_ref_infinite_plane(scalar_type nu, scalar_type E, scalar_type sigma,
 				+9*cost*s2*mu*c2*c2)/(lambda-3*mu);
     }
   } else GMM_ASSERT1(false, "Unvalid mode");
-  if (!finite(U[0]))
+  if (!std::isfinite(U[0]))
     cerr << "raaah not a number ... nu=" << nu << ", E=" << E << ", sig="
 	 << sigma << ", a=" << a << ", xx=" << xx << ", y=" << y << ", r="
 	 << r << ", sqrtr=" << sqrtr << ", cost=" << cost << ", U=" << U[0]
 	 << "," << U[1] << endl;
-  assert(finite(U[0]));
-  assert(finite(U[1]));
+  assert(std::isfinite(U[0]));
+  assert(std::isfinite(U[1]));
 }
 
 struct exact_solution {
@@ -549,7 +551,6 @@ base_small_vector ls_function(const base_node P, int num = 0) {
 bool crack_problem::solve(plain_vector &U) {
   size_type N = mesh.dim();
   ls.reinit();  
-  cout << "ls.get_mesh_fem().nb_dof() = " << ls.get_mesh_fem().nb_dof() << "\n";
   for (size_type d = 0; d < ls.get_mesh_fem().nb_basic_dof(); ++d) {
     ls.values(0)[d] = ls_function(ls.get_mesh_fem().point_of_basic_dof(d), 0)[0];
     ls.values(1)[d] = ls_function(ls.get_mesh_fem().point_of_basic_dof(d), 0)[1];
@@ -791,6 +792,7 @@ bool crack_problem::solve(plain_vector &U) {
     GMM_ASSERT1(!mf_mortar.is_reduced(), "To be adapted");
     sparse_matrix M(mf_mortar.nb_dof(), mf_mortar.nb_dof());
     getfem::asm_mass_matrix(M, mim, mf_mortar, MORTAR_BOUNDARY_OUT);
+    
     for (dal::bv_visitor_c d(mf_mortar.basic_dof_on_region(MORTAR_BOUNDARY_OUT)); 
 	 !d.finished(); ++d) {
       if (M(d,d) > 1e-8) ind_mortar.push_back(d);
@@ -809,14 +811,13 @@ bool crack_problem::solve(plain_vector &U) {
     /* build the mortar constraint matrix -- note that the integration
        method is conformal to the crack
      */
-    getfem::asm_mass_matrix(H0, mim, mf_mortar, mf_u(), 
-			    MORTAR_BOUNDARY_OUT);
+    getfem::asm_mass_matrix(H0, mim, mf_mortar, mf_u(), MORTAR_BOUNDARY_OUT);   
     gmm::copy(gmm::sub_matrix(H0, sub_i, sub_j), H);
 
     gmm::clear(H0);
     getfem::asm_mass_matrix(H0, mim, mf_mortar, mf_u(), 
 			    MORTAR_BOUNDARY_IN);
-    gmm::add(gmm::scaled(gmm::sub_matrix(H0, sub_i, sub_j), -1), H);
+    gmm::add(gmm::scaled(gmm::sub_matrix(H0, sub_i, sub_j), -1.0), H);
 
 
     /* because of the discontinuous partition of mf_u(), some levelset
diff --git a/tests/crack.param b/tests/crack.param
index 068dfb7..b016b5b 100644
--- a/tests/crack.param
+++ b/tests/crack.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program crack                                            %
@@ -24,7 +40,7 @@ else
 end;
 
 
-NX = 20;            	% space step.
+NX = 10;            	% space step.
 MODE = 1;               % Mode for the reference solution
 
 MESH_NOISED = 0;	% Set to one if you want to "shake" the mesh
@@ -66,7 +82,7 @@ ADDITIONAL_CRACK = 0;
 %GLOBAL_FUNCTION_MF = "crack.meshfem"
 %GLOBAL_FUNCTION_U  = "crack.U"
 
-ENRICHMENT_OPTION = 3;  % 0 = Pas d'enrichissement
+ENRICHMENT_OPTION = 2;  % 0 = Pas d'enrichissement
 	                % 1 = standard XFEM on a fixed zone
 			% 2 = global functions with mortar junction
 		        % 3 = global functions with cutoff
diff --git a/tests/crack.pl b/tests/crack.pl
index 7194a2e..7f293a9 100644
--- a/tests/crack.pl
+++ b/tests/crack.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/cyl_slicer.cc b/tests/cyl_slicer.cc
index 284bf68..d69b44d 100644
--- a/tests/cyl_slicer.cc
+++ b/tests/cyl_slicer.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2010-2016 Roman Putanowicz.
+ Copyright (C) 2010-2017 Roman Putanowicz.
 
  This file is a part of GetFEM++
 
diff --git a/tests/cyl_slicer.pl b/tests/cyl_slicer.pl
index 24ad0ed..b00cbb7 100644
--- a/tests/cyl_slicer.pl
+++ b/tests/cyl_slicer.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/dynamic_array.cc b/tests/dynamic_array.cc
index d0aefc5..a7ae4a4 100644
--- a/tests/dynamic_array.cc
+++ b/tests/dynamic_array.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard.
+ Copyright (C) 2002-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/tests/dynamic_array.pl b/tests/dynamic_array.pl
index 33dff1a..61c0429 100644
--- a/tests/dynamic_array.pl
+++ b/tests/dynamic_array.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/dynamic_tas.cc b/tests/dynamic_tas.cc
index 06b87d5..d800e6b 100644
--- a/tests/dynamic_tas.cc
+++ b/tests/dynamic_tas.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard.
+ Copyright (C) 2002-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/tests/dynamic_tas.pl b/tests/dynamic_tas.pl
index be952bc..47a870c 100644
--- a/tests/dynamic_tas.pl
+++ b/tests/dynamic_tas.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/elastostatic.cc b/tests/elastostatic.cc
index 2dbfb82..cd06936 100644
--- a/tests/elastostatic.cc
+++ b/tests/elastostatic.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/elastostatic.param b/tests/elastostatic.param
index 587865d..9a3f196 100644
--- a/tests/elastostatic.param
+++ b/tests/elastostatic.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program elastostatic                                     %
diff --git a/tests/elastostatic.pl b/tests/elastostatic.pl
index 49e7f4c..5798924 100644
--- a/tests/elastostatic.pl
+++ b/tests/elastostatic.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/geo_trans_inv.cc b/tests/geo_trans_inv.cc
index dbcde91..448b70e 100644
--- a/tests/geo_trans_inv.cc
+++ b/tests/geo_trans_inv.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -60,7 +60,7 @@ void check_inversion(bgeot::pgeometric_trans pgt, const std::vector<base_node>&
   bool multiple_solutions = false;
   if (err < 1e-10 && gmm::vect_dist2(Pref,expected_Pref) > 1e-5) { multiple_solutions = true; }
   if ((is_in != expected_in && !multiple_solutions) || err > 1e-10) {
-    cerr << "Error with inversion of " << bgeot::name_of_geometric_trans(pgt) << " on convex: " << cvpts << "\n";
+    cerr << "Error with inversion of " << bgeot::name_of_geometric_trans(pgt) << " on convex: " << gmm::vref(cvpts) << "\n";
     cerr << "  inversion of point " << P << " gave point " << Pref;
     if (expected_in) cerr << "  the point is known to be IN the convex.";
     else cerr << "  the point is known to be OUTSIDE the convex.";
diff --git a/tests/geo_trans_inv.param b/tests/geo_trans_inv.param
old mode 100755
new mode 100644
index 7598f99..10c0715
--- a/tests/geo_trans_inv.param
+++ b/tests/geo_trans_inv.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program laplacian                                        %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/tests/geo_trans_inv.pl b/tests/geo_trans_inv.pl
index 1b63abd..79f6346 100644
--- a/tests/geo_trans_inv.pl
+++ b/tests/geo_trans_inv.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/gmm_torture01_lusolve.cc b/tests/gmm_torture01_lusolve.cc
index 2d50a98..0b3369c 100644
--- a/tests/gmm_torture01_lusolve.cc
+++ b/tests/gmm_torture01_lusolve.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/gmm_torture05_mult.cc b/tests/gmm_torture05_mult.cc
index 8cb8530..a44f01b 100644
--- a/tests/gmm_torture05_mult.cc
+++ b/tests/gmm_torture05_mult.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/gmm_torture06_mat_mult.cc b/tests/gmm_torture06_mat_mult.cc
index 96284be..c301337 100644
--- a/tests/gmm_torture06_mat_mult.cc
+++ b/tests/gmm_torture06_mat_mult.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/gmm_torture10_qr.cc b/tests/gmm_torture10_qr.cc
index 77cd738..51ea571 100644
--- a/tests/gmm_torture10_qr.cc
+++ b/tests/gmm_torture10_qr.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -203,7 +203,7 @@ bool test_procedure(const MAT1 &m1_, const MAT2 &m2_) {
   std::complex<R> det1(gmm::lu_det(ca)), det2(1);
   implicit_qr_algorithm(ca, eigc, cq);
   for (size_type i = 0; i < m; ++i) det2 *= eigc[i];
-  if (gmm::abs(det1 - det2) > (gmm::abs(det1)+gmm::abs(det2))/R(100))
+  if (gmm::abs(det1 - det2) > (gmm::abs(det1)+gmm::abs(det2))/R(50))
     GMM_ASSERT1(false, "Error in QR or det. det lu: " << det1
 	      << " det qr: " << det2);
   if (print_debug)
diff --git a/tests/gmm_torture15_sub.cc b/tests/gmm_torture15_sub.cc
index 6949b9c..0a14414 100644
--- a/tests/gmm_torture15_sub.cc
+++ b/tests/gmm_torture15_sub.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/gmm_torture20_iterative_solvers.cc b/tests/gmm_torture20_iterative_solvers.cc
index 5d44974..94c622e 100644
--- a/tests/gmm_torture20_iterative_solvers.cc
+++ b/tests/gmm_torture20_iterative_solvers.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -163,14 +163,15 @@ bool test_procedure(const MAT1 &m1_, const VECT1 &v1_, const VECT2 &v2_) {
     gmm::set_warning_level(3);
   }
   
-  R det = gmm::abs(gmm::lu_det(m1)), cond = gmm::condest(m1);
-  
+  R det = gmm::abs(gmm::lu_det(m1));
+  if (det < sqrt(prec)*R(10)) return false;
+  R cond = gmm::condest(m1);
   if (print_debug)
     cout << "condition number = " << cond << " det = " << det << endl;
   if (det == R(0) && cond < R(1) / prec && cond != R(0))
     GMM_ASSERT1(false, "Inconsistent condition number: " << cond);
 
-  if (sqrt(prec) * cond >= R(1)/R(100) || det < sqrt(prec)*R(10)) return false;
+  if (sqrt(prec) * cond >= R(1)/R(100)) return false;
     
   ++effexpe; cout << "."; cout.flush();
   
@@ -229,7 +230,7 @@ bool test_procedure(const MAT1 &m1_, const VECT1 &v1_, const VECT2 &v2_) {
   if (print_debug) cout << "\nGmres with ilutp preconditionner\n";
   do_test(GMRES(), m1, v1, v2, P5b, cond);
   
-  if (sizeof(R) > 4 || m < 20) {
+  if (sizeof(R) > 5 || m < 15) {
 
     if (print_debug) cout << "\nQmr with no preconditionner\n";
     do_test(QMR(), m1, v1, v2, P1, cond);
@@ -291,7 +292,10 @@ bool test_procedure(const MAT1 &m1_, const VECT1 &v1_, const VECT2 &v2_) {
     print_stat(P5b, "ilutp precond");
     print_stat(P6, "ildlt precond");
     print_stat(P7, "ildltt precond");
-    if (ratio_max > 0.2) GMM_ASSERT1(false, "something wrong ..");
+    if (sizeof(R) > 4 && ratio_max > 0.16)
+      GMM_ASSERT1(false, "something wrong ..");
+    if (sizeof(R) <= 4 && ratio_max > 0.3)
+      GMM_ASSERT1(false, "something wrong ..");
     return true;
   }
  
diff --git a/tests/heat_equation.cc b/tests/heat_equation.cc
index 192d474..4943475 100644
--- a/tests/heat_equation.cc
+++ b/tests/heat_equation.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard.
+ Copyright (C) 2009-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/tests/heat_equation.param b/tests/heat_equation.param
index 0d4a2c9..3cafdd9 100644
--- a/tests/heat_equation.param
+++ b/tests/heat_equation.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program heat equation                                    %
diff --git a/tests/heat_equation.pl b/tests/heat_equation.pl
index cf689f7..7226bd7 100644
--- a/tests/heat_equation.pl
+++ b/tests/heat_equation.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/helmholtz.cc b/tests/helmholtz.cc
index dd2859c..aafa32a 100644
--- a/tests/helmholtz.cc
+++ b/tests/helmholtz.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -209,7 +209,7 @@ bool Helmholtz_problem::solve(plain_vector &U) {
   gmm::resize(U, mf_u.nb_dof());
   gmm::copy(Helmholtz_model.complex_variable("u"), U);
 
-  cout << "U = " << U << endl;
+  // cout << "U = " << U << endl;
 
   return (iter.converged());
 }
@@ -223,27 +223,24 @@ int main(int argc, char *argv[]) {
   GMM_SET_EXCEPTION_DEBUG; // Exceptions make a memory fault, to debug.
   FE_ENABLE_EXCEPT;        // Enable floating point exception for Nan.
 
-  try {    
-    Helmholtz_problem p;
-    p.PARAM.read_command_line(argc, argv);
-    p.init();
-    plain_vector U(p.mf_u.nb_dof());
-    if (!p.solve(U)) GMM_ASSERT1(false, "Solve has failed");
-
-    if (p.PARAM.int_value("VTK_EXPORT")) {
-      cout << "export to " << p.datafilename + ".vtk" << "..\n";
-      getfem::vtk_export exp(p.datafilename + ".vtk",
-			     p.PARAM.int_value("VTK_EXPORT")==1);
-      getfem::stored_mesh_slice sl(p.mesh, p.mesh.nb_convex() < 2000 ? 8 : 6);
-      exp.exporting(sl);
-      exp.write_point_data(p.mf_u, gmm::real_part(U), "helmholtz_rfield");
-      exp.write_point_data(p.mf_u, gmm::imag_part(U), "helmholtz_ifield");
-      cout << "export done, you can view the data file with (for example)\n"
-	"mayavi2 -d helmholtz.vtk -f WarpScalar -m Surface -m Outline"
-	"\n";
-    }
+  Helmholtz_problem p;
+  p.PARAM.read_command_line(argc, argv);
+  p.init();
+  plain_vector U(p.mf_u.nb_dof());
+  if (!p.solve(U)) GMM_ASSERT1(false, "Solve has failed");
+  
+  if (p.PARAM.int_value("VTK_EXPORT")) {
+    cout << "export to " << p.datafilename + ".vtk" << "..\n";
+    getfem::vtk_export exp(p.datafilename + ".vtk",
+			   p.PARAM.int_value("VTK_EXPORT")==1);
+    getfem::stored_mesh_slice sl(p.mesh, p.mesh.nb_convex() < 2000 ? 8 : 6);
+    exp.exporting(sl);
+    exp.write_point_data(p.mf_u, gmm::real_part(U), "helmholtz_rfield");
+    exp.write_point_data(p.mf_u, gmm::imag_part(U), "helmholtz_ifield");
+    cout << "export done, you can view the data file with (for example)\n"
+      "mayavi2 -d helmholtz.vtk -f WarpScalar -m Surface -m Outline"
+      "\n";
   }
-  GMM_STANDARD_CATCH_ERROR;
 
   return 0; 
 }
diff --git a/tests/helmholtz.pl b/tests/helmholtz.pl
index a90c67b..8591726 100755
--- a/tests/helmholtz.pl
+++ b/tests/helmholtz.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/integration.cc b/tests/integration.cc
index d281307..4d2ba11 100644
--- a/tests/integration.cc
+++ b/tests/integration.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -27,7 +27,8 @@
 #include <map>
 using std::endl; using std::cout; using std::cerr;
 using std::ends; using std::cin;
-
+template <typename T> std::ostream &operator <<
+  (std::ostream &o, const std::vector<T>& m) { gmm::write(o,m); return o; }
 
 using getfem::size_type;
 using getfem::short_type;
@@ -455,13 +456,11 @@ int main(/* int argc, char **argv */) {
     getfem::pfem pf = getfem::QK_fem(2,1); //getfem::classical_fem(bgeot::parallelepiped_linear_geotrans(2),1);
     return 100;*/
 
-
-
     int ok = 0;
     getfem::pintegration_method im_none = getfem::int_method_descriptor("IM_NONE()");
     try {
       cout << "nbpts=" << im_none->structure()->nb_points() << "\n";
-    } catch (gmm::gmm_error e) {
+    } catch (const gmm::gmm_error &e) {
       ok = 1;
     }
     GMM_ASSERT1(ok, "IM_NONE failed");
diff --git a/tests/integration.pl b/tests/integration.pl
index 9c06156..e2a26ac 100644
--- a/tests/integration.pl
+++ b/tests/integration.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/laplacian.cc b/tests/laplacian.cc
index 0221b70..0590cfe 100644
--- a/tests/laplacian.cc
+++ b/tests/laplacian.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -221,7 +221,7 @@ void laplacian_problem::assembly(void) {
   if (!gen_dirichlet) {    
     std::vector<scalar_type> D(nb_dof);
     getfem::interpolation_function(mf_u, D, sol_u);
-    getfem::assembling_Dirichlet_condition(SM, B, mf_u, 
+    getfem::assembling_Dirichlet_condition(SM, B, mf_u,
 					   DIRICHLET_BOUNDARY_NUM, D);
   } else {
     gmm::resize(F, nb_dof_rhs);
diff --git a/tests/laplacian.param b/tests/laplacian.param
index 2e00646..8f596c0 100644
--- a/tests/laplacian.param
+++ b/tests/laplacian.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program laplacian                                        %
@@ -8,7 +24,7 @@ INCLINE = 0;                % Incline of the mesh.
 FT = 0.1;                   % parameter for the exact solution.
 N = 2;                      % domain in dimension N
 QUAD = 0;                   % use quadrilaterons or not
-NX = 100;                   % space step.
+NX = 40;                   % space step.
 MESH_NOISED = 0;            % Set to one if you want to "shake" the mesh
 
 if (N == 1)
diff --git a/tests/laplacian.pl b/tests/laplacian.pl
index daace1b..038ced1 100644
--- a/tests/laplacian.pl
+++ b/tests/laplacian.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/laplacian_with_bricks.cc b/tests/laplacian_with_bricks.cc
index c7483fc..2712ef6 100644
--- a/tests/laplacian_with_bricks.cc
+++ b/tests/laplacian_with_bricks.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/laplacian_with_bricks.param b/tests/laplacian_with_bricks.param
index 449ec47..c79c2ba 100644
--- a/tests/laplacian_with_bricks.param
+++ b/tests/laplacian_with_bricks.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program laplacian                                        %
diff --git a/tests/laplacian_with_bricks.pl b/tests/laplacian_with_bricks.pl
index 661fdf1..cddca6b 100644
--- a/tests/laplacian_with_bricks.pl
+++ b/tests/laplacian_with_bricks.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
@@ -97,6 +97,10 @@ start_program("-d 'MESH_TYPE=\"GT_QK(2,1)\"' -d 'FEM_TYPE=\"FEM_QK(2,1)\"' -d 'I
 #start_program("-d INTEGRATION=1  -d MESH_TYPE=1");
 print ".";
 start_program("-d 'MESH_TYPE=\"GT_QK(2,1)\"' -d 'FEM_TYPE=\"FEM_QK(2,1)\"' -d 'INTEGRATION=\"IM_QUAD(3)\"'");
+print ".";
+start_program("-d 'MESH_TYPE=\"GT_PK(2,1)\"' -d 'FEM_TYPE=\"FEM_ARGYRIS\"' -d 'INTEGRATION=\"IM_TRIANGLE(5)\"' -d 'DATA_FEM_TYPE=\"FEM_PK(2,5)\"'");
+print ".";
+start_program("-d 'MESH_TYPE=\"GT_PK(2,1)\"' -d 'FEM_TYPE=\"FEM_REDUCED_HCT_TRIANGLE\"' -d 'INTEGRATION=\"IM_HCT_COMPOSITE(IM_TRIANGLE(6))\"' -d 'DATA_FEM_TYPE=\"FEM_PK(2,3)\"'");
 #start_program("-d INTEGRATION=33 -d MESH_TYPE=1");
 print ".";
 start_program("-d 'MESH_TYPE=\"GT_QK(2,1)\"' -d 'FEM_TYPE=\"FEM_QK(2,1)\"' -d 'INTEGRATION=\"IM_QUAD(17)\"'");
diff --git a/tests/make_gmm_test.pl b/tests/make_gmm_test.pl
index 43c0103..c2325b3 100755
--- a/tests/make_gmm_test.pl
+++ b/tests/make_gmm_test.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/meshes/disc_2D_degree3.mesh b/tests/meshes/disc_2D_degree3.mesh
old mode 100755
new mode 100644
index 2faedd9..439d102
--- a/tests/meshes/disc_2D_degree3.mesh
+++ b/tests/meshes/disc_2D_degree3.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 2.0-20050204
 
diff --git a/tests/meshes/disc_P2_h0_3.mesh b/tests/meshes/disc_P2_h0_3.mesh
index 6c6c5fc..987e438 100644
--- a/tests/meshes/disc_P2_h0_3.mesh
+++ b/tests/meshes/disc_P2_h0_3.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 3.0
 
diff --git a/tests/meshes/disc_P2_h0_5.mesh b/tests/meshes/disc_P2_h0_5.mesh
index 3d336e3..5eaeb04 100644
--- a/tests/meshes/disc_P2_h0_5.mesh
+++ b/tests/meshes/disc_P2_h0_5.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040316
 
diff --git a/tests/meshes/disc_P2_h1.mesh b/tests/meshes/disc_P2_h1.mesh
index 90ef1cb..5ceaf6a 100644
--- a/tests/meshes/disc_P2_h1.mesh
+++ b/tests/meshes/disc_P2_h1.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040316
 
diff --git a/tests/meshes/disc_P2_h10.mesh b/tests/meshes/disc_P2_h10.mesh
index 6629562..485d8f2 100644
--- a/tests/meshes/disc_P2_h10.mesh
+++ b/tests/meshes/disc_P2_h10.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040316
 
diff --git a/tests/meshes/disc_P2_h2.mesh b/tests/meshes/disc_P2_h2.mesh
index 35b2731..6d76bc9 100644
--- a/tests/meshes/disc_P2_h2.mesh
+++ b/tests/meshes/disc_P2_h2.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040316
 
diff --git a/tests/meshes/disc_P2_h4.mesh b/tests/meshes/disc_P2_h4.mesh
index 8a11842..d740e89 100644
--- a/tests/meshes/disc_P2_h4.mesh
+++ b/tests/meshes/disc_P2_h4.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040316
 
diff --git a/tests/meshes/disc_P2_h6.mesh b/tests/meshes/disc_P2_h6.mesh
index 1f08563..7033dd7 100644
--- a/tests/meshes/disc_P2_h6.mesh
+++ b/tests/meshes/disc_P2_h6.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040316
 
diff --git a/tests/meshes/disc_P2_h8.mesh b/tests/meshes/disc_P2_h8.mesh
index cf5de4c..29d82c2 100644
--- a/tests/meshes/disc_P2_h8.mesh
+++ b/tests/meshes/disc_P2_h8.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040316
 
diff --git a/tests/meshes/disc_with_a_hole.mesh b/tests/meshes/disc_with_a_hole.mesh
index 4ad9757..e5ca387 100644
--- a/tests/meshes/disc_with_a_hole.mesh
+++ b/tests/meshes/disc_with_a_hole.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 4.2
 
diff --git a/tests/meshes/donut_regulier_32_elements.mesh b/tests/meshes/donut_regulier_32_elements.mesh
old mode 100755
new mode 100644
index 7b2f7e5..6b7ed26
--- a/tests/meshes/donut_regulier_32_elements.mesh
+++ b/tests/meshes/donut_regulier_32_elements.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040330
 
diff --git a/tests/meshes/donut_regulier_512_elements.mesh b/tests/meshes/donut_regulier_512_elements.mesh
old mode 100755
new mode 100644
index 6d87a17..b3ca25f
--- a/tests/meshes/donut_regulier_512_elements.mesh
+++ b/tests/meshes/donut_regulier_512_elements.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040330
 
diff --git a/tests/meshes/donut_regulier_72_elements.mesh b/tests/meshes/donut_regulier_72_elements.mesh
old mode 100755
new mode 100644
index 2abebcd..8fa6d5c
--- a/tests/meshes/donut_regulier_72_elements.mesh
+++ b/tests/meshes/donut_regulier_72_elements.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040330
 
diff --git a/tests/meshes/donut_regulier_8_elements_288ddl.mesh b/tests/meshes/donut_regulier_8_elements_288ddl.mesh
old mode 100755
new mode 100644
index 6a3a07d..b2f954b
--- a/tests/meshes/donut_regulier_8_elements_288ddl.mesh
+++ b/tests/meshes/donut_regulier_8_elements_288ddl.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 1.7-20040330
 
diff --git a/tests/meshes/multi_body.mesh b/tests/meshes/multi_body.mesh
index 1bd907a..ee2348e 100644
--- a/tests/meshes/multi_body.mesh
+++ b/tests/meshes/multi_body.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 4.2
 
diff --git a/tests/meshes/punch2D_1.mesh b/tests/meshes/punch2D_1.mesh
index a8687f5..435cb4a 100644
--- a/tests/meshes/punch2D_1.mesh
+++ b/tests/meshes/punch2D_1.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 4.1.1
 
diff --git a/tests/meshes/punch2D_2.mesh b/tests/meshes/punch2D_2.mesh
index e77caed..6aec54c 100644
--- a/tests/meshes/punch2D_2.mesh
+++ b/tests/meshes/punch2D_2.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 4.2
 
diff --git a/tests/meshes/sphere_with_quadratic_tetra_16000_elts.mesh b/tests/meshes/sphere_with_quadratic_tetra_16000_elts.mesh
old mode 100755
new mode 100644
index 5624001..6d21b26
--- a/tests/meshes/sphere_with_quadratic_tetra_16000_elts.mesh
+++ b/tests/meshes/sphere_with_quadratic_tetra_16000_elts.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 3.0
 
diff --git a/tests/meshes/sphere_with_quadratic_tetra_2000_elts.mesh b/tests/meshes/sphere_with_quadratic_tetra_2000_elts.mesh
old mode 100755
new mode 100644
index 4300679..7e28434
--- a/tests/meshes/sphere_with_quadratic_tetra_2000_elts.mesh
+++ b/tests/meshes/sphere_with_quadratic_tetra_2000_elts.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 3.0
 
diff --git a/tests/meshes/sphere_with_quadratic_tetra_400_elts.mesh b/tests/meshes/sphere_with_quadratic_tetra_400_elts.mesh
old mode 100755
new mode 100644
index 2a15890..9a5786a
--- a/tests/meshes/sphere_with_quadratic_tetra_400_elts.mesh
+++ b/tests/meshes/sphere_with_quadratic_tetra_400_elts.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 3.0
 
diff --git a/tests/meshes/sphere_with_quadratic_tetra_80_elts.mesh b/tests/meshes/sphere_with_quadratic_tetra_80_elts.mesh
old mode 100755
new mode 100644
index 96b39a5..6dd81e4
--- a/tests/meshes/sphere_with_quadratic_tetra_80_elts.mesh
+++ b/tests/meshes/sphere_with_quadratic_tetra_80_elts.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 3.0
 
diff --git a/tests/meshes/sphere_with_quadratic_tetra_8_elts.mesh b/tests/meshes/sphere_with_quadratic_tetra_8_elts.mesh
old mode 100755
new mode 100644
index 82a81e7..10da087
--- a/tests/meshes/sphere_with_quadratic_tetra_8_elts.mesh
+++ b/tests/meshes/sphere_with_quadratic_tetra_8_elts.mesh
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % GETFEM MESH FILE 
 % GETFEM VERSION 3.0
 
diff --git a/tests/nonlinear_elastostatic.cc b/tests/nonlinear_elastostatic.cc
index cabf62e..2d65cff 100644
--- a/tests/nonlinear_elastostatic.cc
+++ b/tests/nonlinear_elastostatic.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/nonlinear_elastostatic.param b/tests/nonlinear_elastostatic.param
index d1321dc..ad1fb31 100644
--- a/tests/nonlinear_elastostatic.param
+++ b/tests/nonlinear_elastostatic.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program nonlinear elastostatic problem                   %
diff --git a/tests/nonlinear_elastostatic.pl b/tests/nonlinear_elastostatic.pl
index 0eff274..d26d9de 100644
--- a/tests/nonlinear_elastostatic.pl
+++ b/tests/nonlinear_elastostatic.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/nonlinear_membrane.cc b/tests/nonlinear_membrane.cc
index 122d55c..b436a86 100644
--- a/tests/nonlinear_membrane.cc
+++ b/tests/nonlinear_membrane.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Jean-Yves Heddebaut.
+ Copyright (C) 2002-2017 Jean-Yves Heddebaut.
 
  This file is a part of GetFEM++
 
@@ -36,6 +36,8 @@
 
 using std::endl; using std::cout; using std::cerr;
 using std::ends; using std::cin;
+template <typename T> std::ostream &operator <<
+  (std::ostream &o, const std::vector<T>& m) { gmm::write(o,m); return o; }
 
 /* some GetFEM++ types that we will be using */
 using bgeot::base_small_vector; /* special class for small (dim<16) vectors */
diff --git a/tests/nonlinear_membrane.param b/tests/nonlinear_membrane.param
index fddb1fe..bb5daf5 100644
--- a/tests/nonlinear_membrane.param
+++ b/tests/nonlinear_membrane.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for nonlinear membrane 
diff --git a/tests/nonlinear_membrane.pl b/tests/nonlinear_membrane.pl
index f86b48c..d4dfd9a 100644
--- a/tests/nonlinear_membrane.pl
+++ b/tests/nonlinear_membrane.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/plasticity.cc b/tests/plasticity.cc
index a265d92..fe7d16f 100644
--- a/tests/plasticity.cc
+++ b/tests/plasticity.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2000-2016 Yves Renard
+ Copyright (C) 2000-2017 Yves Renard
 
  This file is a part of GetFEM++
 
diff --git a/tests/plasticity.param b/tests/plasticity.param
index e3c2b95..8ca9824 100644
--- a/tests/plasticity.param
+++ b/tests/plasticity.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for plasticity program                                       %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/tests/plasticity.pl b/tests/plasticity.pl
index dd1c77a..5b69019 100644
--- a/tests/plasticity.pl
+++ b/tests/plasticity.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/plate.cc b/tests/plate.cc
index 670c172..d733d78 100644
--- a/tests/plate.cc
+++ b/tests/plate.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Michel Sala�n.
+ Copyright (C) 2002-2017 Yves Renard, Michel Sala�n.
 
  This file is a part of GetFEM++
 
diff --git a/tests/plate.param b/tests/plate.param
index 418ad31..fbf5ec7 100644
--- a/tests/plate.param
+++ b/tests/plate.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
 
      
diff --git a/tests/plate.pl b/tests/plate.pl
index 0613247..866ab61 100644
--- a/tests/plate.pl
+++ b/tests/plate.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/poly.cc b/tests/poly.cc
index 79d347f..20b1d25 100644
--- a/tests/poly.cc
+++ b/tests/poly.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard.
+ Copyright (C) 2002-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/tests/poly.pl b/tests/poly.pl
index a548e93..27d89e5 100644
--- a/tests/poly.pl
+++ b/tests/poly.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/schwarz_additive.cc b/tests/schwarz_additive.cc
index 7028106..094615b 100644
--- a/tests/schwarz_additive.cc
+++ b/tests/schwarz_additive.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -166,11 +166,9 @@ void pb_data::init(bgeot::md_param &params) {
 
   dal::bit_vector nn = mesh.convex_index(dim_type(N));
   char method[500];
-  sprintf(method, "IM_EXACT_SIMPLEX(%d)", N);
-  getfem::pintegration_method ppi = getfem::int_method_descriptor(method);
   
   sprintf(method, "FEM_PK(%d, %d)", N, K);
-  mim.set_integration_method(nn, ppi);
+  mim.set_integration_method(nn, bgeot::dim_type(2*K));
   mef.set_finite_element(nn, getfem::fem_descriptor(method));
   mef_coarse.set_finite_element(mesh_coarse.convex_index(dim_type(N)),
 				getfem::fem_descriptor(method));
diff --git a/tests/schwarz_additive.param b/tests/schwarz_additive.param
old mode 100755
new mode 100644
index 1225282..994b78a
--- a/tests/schwarz_additive.param
+++ b/tests/schwarz_additive.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters of test program schwarz additive             	          %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/tests/schwarz_additive.pl b/tests/schwarz_additive.pl
index 0e87c66..fee2ac2 100644
--- a/tests/schwarz_additive.pl
+++ b/tests/schwarz_additive.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/stokes.cc b/tests/stokes.cc
index 8bcc71b..03a2d75 100644
--- a/tests/stokes.cc
+++ b/tests/stokes.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2002-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/stokes.param b/tests/stokes.param
old mode 100755
new mode 100644
index 356f9f6..270067d
--- a/tests/stokes.param
+++ b/tests/stokes.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program stokes                                           %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/tests/stokes.pl b/tests/stokes.pl
index 435a957..0e64a30 100644
--- a/tests/stokes.pl
+++ b/tests/stokes.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_assembly.cc b/tests/test_assembly.cc
index 0ef8063..30fde32 100644
--- a/tests/test_assembly.cc
+++ b/tests/test_assembly.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -33,6 +33,8 @@
 #endif
 using std::endl; using std::cout; using std::cerr;
 using std::ends; using std::cin;
+template <typename T> std::ostream &operator <<
+  (std::ostream &o, const std::vector<T>& m) { gmm::write(o,m); return o; }
 
 using bgeot::base_vector;
 using bgeot::base_matrix;
@@ -62,6 +64,292 @@ int fail_cnt = 0;
 //   //mf.set_classical_finite_element(K,2*K);
 // }
 
+// old assembly functions. To compare
+namespace getfem { // old assembly procedures with low level generic assembly
+
+  template<typename VEC>
+  scalar_type old_asm_L2_norm
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg=mesh_region::all_convexes()) {
+    return
+      sqrt(old_asm_L2_norm_sqr(mim, mf, U, rg,
+			   typename gmm::linalg_traits<VEC>::value_type()));
+  }
+  
+  template<typename VEC, typename T>
+  scalar_type old_asm_L2_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
+				  const VEC &U, const mesh_region &rg_, T) {
+    mesh_region rg(rg_);
+    mim.linked_mesh().intersect_with_mpi_region(rg);
+    generic_assembly assem;    
+    if (mf.get_qdim() == 1)
+      assem.set("u=data(#1); V()+=u(i).u(j).comp(Base(#1).Base(#1))(i,j)");
+    else
+      assem.set("u=data(#1);"
+		"V()+=u(i).u(j).comp(vBase(#1).vBase(#1))(i,k,j,k)");
+    assem.push_mi(mim);
+    assem.push_mf(mf);
+    assem.push_data(U);
+    std::vector<scalar_type> v(1);
+    assem.push_vec(v);
+    assem.assembly(rg);
+    MPI_SUM_SCALAR(v[0]);
+    return v[0];
+  }
+
+  template<typename VEC, typename T>
+  scalar_type old_asm_L2_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
+				  const VEC &U,
+				  const mesh_region &rg, std::complex<T>) {
+    return asm_L2_norm_sqr(mim, mf,gmm::real_part(U),rg,T()) + 
+      asm_L2_norm_sqr(mim, mf,gmm::imag_part(U),rg,T());
+  }
+
+
+  
+  template<typename VEC>
+  scalar_type old_asm_H1_semi_norm
+  (const mesh_im &mim, const mesh_fem &mf, const VEC &U,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    typedef typename gmm::linalg_traits<VEC>::value_type T;
+    return sqrt(old_asm_H1_semi_norm_sqr(mim, mf, U, rg, T()));
+  }
+
+  template<typename VEC, typename T>
+  scalar_type old_asm_H1_semi_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
+				   const VEC &U, const mesh_region &rg_, T) {
+
+    mesh_region rg(rg_);
+    mim.linked_mesh().intersect_with_mpi_region(rg);
+    generic_assembly assem;    
+    if (mf.get_qdim() == 1)
+      assem.set("u=data(#1); V()+=u(i).u(j).comp(Grad(#1).Grad(#1))(i,d,j,d)");
+    else
+      assem.set("u=data(#1);"
+		"V()+=u(i).u(j).comp(vGrad(#1).vGrad(#1))(i,k,d,j,k,d)");
+    assem.push_mi(mim);
+    assem.push_mf(mf);
+    assem.push_data(U);
+    std::vector<scalar_type> v(1);
+    assem.push_vec(v);
+    assem.assembly(rg);
+    return MPI_SUM_SCALAR(v[0]);
+  }
+
+  
+
+  template<typename VEC, typename T>
+  scalar_type old_asm_H1_semi_norm_sqr(const mesh_im &mim, const mesh_fem &mf,
+				   const VEC &U,
+				   const mesh_region &rg, std::complex<T>) {
+    return old_asm_H1_semi_norm_sqr(mim, mf, gmm::real_part(U), rg, T()) + 
+      old_asm_H1_semi_norm_sqr(mim, mf, gmm::imag_part(U), rg, T());
+  }
+
+
+  /*
+    assembly of a matrix with 1 parameter (real or complex)
+    (the most common here for the assembly routines below)
+  */
+  template <typename MAT, typename VECT>
+  void old_asm_real_or_complex_1_param
+  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_data,
+   const VECT &A, const mesh_region &rg, const char *assembly_description,
+   const mesh_fem *mf_mult = 0) {
+    old_asm_real_or_complex_1_param_
+      (M, mim, mf_u, mf_data, A, rg, assembly_description, mf_mult,
+       typename gmm::linalg_traits<VECT>::value_type());
+  }
+
+  /* real version */
+  template<typename MAT, typename VECT, typename T>
+  void old_asm_real_or_complex_1_param_
+  (const MAT &M, const mesh_im &mim,  const mesh_fem &mf_u,
+   const mesh_fem &mf_data, const VECT &A,  const mesh_region &rg,
+   const char *assembly_description, const mesh_fem *mf_mult, T) {
+    generic_assembly assem(assembly_description);
+    assem.push_mi(mim);
+    assem.push_mf(mf_u);
+    assem.push_mf(mf_data);
+    if (mf_mult) assem.push_mf(*mf_mult);
+    assem.push_data(A);
+    assem.push_mat_or_vec(const_cast<MAT&>(M));
+    assem.assembly(rg);
+  }
+
+  /* complex version */
+  template<typename MAT, typename VECT, typename T>
+  void old_asm_real_or_complex_1_param_
+  (MAT &M, const mesh_im &mim, const mesh_fem &mf_u, const mesh_fem &mf_data,
+   const VECT &A, const mesh_region &rg,const char *assembly_description,
+   const mesh_fem *mf_mult, std::complex<T>) {
+    old_asm_real_or_complex_1_param_(gmm::real_part(M),mim,mf_u,mf_data,
+				 gmm::real_part(A),rg,
+				 assembly_description, mf_mult, T());
+    old_asm_real_or_complex_1_param_(gmm::imag_part(M),mim,mf_u,mf_data,
+				 gmm::imag_part(A),rg,
+				 assembly_description, mf_mult, T());
+  }
+
+  
+  template<typename VECT1, typename VECT2>
+  void old_asm_source_term
+  (const VECT1 &B, const mesh_im &mim, const mesh_fem &mf,
+   const mesh_fem &mf_data, const VECT2 &F,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    GMM_ASSERT1(mf_data.get_qdim() == 1 ||
+		mf_data.get_qdim() == mf.get_qdim(),
+		"invalid data mesh fem (same Qdim or Qdim=1 required)");
+
+    const char *st;
+    if (mf.get_qdim() == 1)
+      st = "F=data(#2); V(#1)+=comp(Base(#1).Base(#2))(:,j).F(j);";
+    else if (mf_data.get_qdim() == 1)
+      st = "F=data(qdim(#1),#2);"
+	"V(#1)+=comp(vBase(#1).Base(#2))(:,i,j).F(i,j);";
+    else
+      st = "F=data(#2);"
+	"V(#1)+=comp(vBase(#1).vBase(#2))(:,i,j,i).F(j);";
+    
+    old_asm_real_or_complex_1_param(const_cast<VECT1 &>(B),mim,mf,
+				    mf_data,F,rg,st);
+  }
+
+  template<typename VECT1, typename VECT2>
+  void old_asm_normal_source_term(VECT1 &B, const mesh_im &mim,
+				  const mesh_fem &mf,
+				  const mesh_fem &mf_data, const VECT2 &F,
+				  const mesh_region &rg) {
+    GMM_ASSERT1(mf_data.get_qdim() == 1 ||
+		mf_data.get_qdim() == mf.get_qdim(),
+		"invalid data mesh_fem (same Qdim or Qdim=1 required)");
+
+    const char *st;
+    if (mf.get_qdim() == 1)
+      st = "F=data(mdim(#1),#2);"
+	"V(#1)+=comp(Base(#1).Base(#2).Normal())(:,j,k).F(k,j);";
+    else if (mf_data.get_qdim() == 1)
+      st = "F=data(qdim(#1),mdim(#1),#2);"
+	"V(#1)+=comp(vBase(#1).Base(#2).Normal())(:,i,j,k).F(i,k,j);";
+    else
+      st = "F=data(mdim(#1),#2);"
+	"V(#1)+=comp(vBase(#1).vBase(#2).Normal())(:,i,j,i,k).F(k,j);";
+
+    old_asm_real_or_complex_1_param(B, mim, mf, mf_data, F, rg, st);
+  }
+
+  template<typename MAT>
+  void old_asm_mass_matrix(const MAT &M, const mesh_im &mim,
+		       const mesh_fem &mf_u1,
+		       const mesh_region &rg = mesh_region::all_convexes()) {
+    generic_assembly assem;
+    if (mf_u1.get_qdim() == 1)
+      assem.set("M(#1,#1)+=sym(comp(Base(#1).Base(#1)))");
+    else
+      assem.set("M(#1,#1)+=sym(comp(vBase(#1).vBase(#1))(:,i,:,i));");
+    assem.push_mi(mim);
+    assem.push_mf(mf_u1);
+    assem.push_mat(const_cast<MAT &>(M));
+    assem.assembly(rg);
+  }
+
+  template<typename MAT>
+  void old_asm_mass_matrix(const MAT &M, const mesh_im &mim, const mesh_fem &mf_u1,
+		       const mesh_fem &mf_u2,
+		       const mesh_region &rg = mesh_region::all_convexes()) {
+    generic_assembly assem;
+    if (mf_u1.get_qdim() == 1 && mf_u2.get_qdim() == 1)
+      assem.set("M(#1,#2)+=comp(Base(#1).Base(#2))");
+    else if (mf_u1.get_qdim() == 1)
+      assem.set("M(#1,#2)+=comp(Base(#1).vBase(#2))(:,:,1);"); // could be i in place of 1
+    else if (mf_u2.get_qdim() == 1)
+      assem.set("M(#1,#2)+=comp(vBase(#1).Base(#2))(:,1,:);");
+    else
+      assem.set("M(#1,#2)+=comp(vBase(#1).vBase(#2))(:,i,:,i);");
+    assem.push_mi(mim);
+    assem.push_mf(mf_u1);
+    assem.push_mf(mf_u2);
+    assem.push_mat(const_cast<MAT &>(M));
+    assem.assembly(rg);
+  }
+
+  /** 
+      Stiffness matrix for linear elasticity, with Lam� coefficients
+      @ingroup asm
+  */
+  template<class MAT, class VECT>
+  void old_asm_stiffness_matrix_for_linear_elasticity
+  (const MAT &RM_, const mesh_im &mim, const mesh_fem &mf,
+   const mesh_fem &mf_data, const VECT &LAMBDA, const VECT &MU,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    MAT &RM = const_cast<MAT &>(RM_);
+    GMM_ASSERT1(mf_data.get_qdim() == 1,
+		"invalid data mesh fem (Qdim=1 required)");
+    
+    GMM_ASSERT1(mf.get_qdim() == mf.linked_mesh().dim(),
+		"wrong qdim for the mesh_fem");
+    /* e = strain tensor,
+       M = 2*mu*e(u):e(v) + lambda*tr(e(u))*tr(e(v))
+    */
+    generic_assembly assem("lambda=data$1(#2); mu=data$2(#2);"
+			   "t=comp(vGrad(#1).vGrad(#1).Base(#2));"
+			   //"e=(t{:,2,3,:,5,6,:}+t{:,3,2,:,5,6,:}"
+			   //"+t{:,2,3,:,6,5,:}+t{:,3,2,:,6,5,:})/4;"
+			   //"e=(t{:,2,3,:,5,6,:}+t{:,3,2,:,5,6,:})*0.5;"
+			   /*"M(#1,#1)+= sym(2*e(:,i,j,:,i,j,k).mu(k)"
+                             " + e(:,i,i,:,j,j,k).lambda(k))");*/
+                           "M(#1,#1)+= sym(t(:,i,j,:,i,j,k).mu(k)"
+			   "+ t(:,j,i,:,i,j,k).mu(k)"
+			   "+ t(:,i,i,:,j,j,k).lambda(k))");
+    assem.push_mi(mim);
+    assem.push_mf(mf);
+    assem.push_mf(mf_data);
+    assem.push_data(LAMBDA);
+    assem.push_data(MU);
+    assem.push_mat(RM);
+    assem.assembly(rg);
+  }
+
+
+  /** 
+      Stiffness matrix for linear elasticity, with constant Lam� coefficients
+      @ingroup asm
+  */
+  template<class MAT, class VECT>
+  void old_asm_stiffness_matrix_for_homogeneous_linear_elasticity
+  (const MAT &RM_, const mesh_im &mim, const mesh_fem &mf,
+   const VECT &LAMBDA, const VECT &MU,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    MAT &RM = const_cast<MAT &>(RM_);
+    GMM_ASSERT1(mf.get_qdim() == mf.linked_mesh().dim(),
+		"wrong qdim for the mesh_fem");
+    generic_assembly assem("lambda=data$1(1); mu=data$2(1);"
+			   "t=comp(vGrad(#1).vGrad(#1));"
+                           "M(#1,#1)+= sym(t(:,i,j,:,i,j).mu(1)"
+			   "+ t(:,j,i,:,i,j).mu(1)"
+			   "+ t(:,i,i,:,j,j).lambda(1))");
+    assem.push_mi(mim);
+    assem.push_mf(mf);
+    assem.push_data(LAMBDA);
+    assem.push_data(MU);
+    assem.push_mat(RM);
+    assem.assembly(rg);
+  }
+
+  template<typename MAT>
+  void old_asm_stiffness_matrix_for_homogeneous_laplacian
+  (const MAT &M_, const mesh_im &mim, const mesh_fem &mf,
+   const mesh_region &rg = mesh_region::all_convexes()) {
+    MAT &M = const_cast<MAT &>(M_);
+    generic_assembly 
+      assem("M$1(#1,#1)+=sym(comp(Grad(#1).Grad(#1))(:,i,:,i))");
+    assem.push_mi(mim);
+    assem.push_mf(mf);
+    assem.push_mat(M);
+    assem.assembly(rg);
+  }
+  
+}
 
 typedef enum {
   DO_SCAL_VOLUMIC_SOURCE,
@@ -153,621 +441,6 @@ void g_params::init(int argc, char *argv[]) {
                                 "which test do you want to run?"));
 }
 
-namespace getfem {
-  template<class VECT1, class VECT2>
-  void old_asm_Neumann_condition(VECT1 &B, const mesh_im &mim,
-				 const mesh_fem &mf,
-				 size_type boundary, const mesh_fem &mfdata,
-				 const VECT2 &F, dim_type N) {
-    size_type cv, nbd1, nbd2, f;
-    dal::bit_vector nn = mf.convex_index(), nf;
-    base_tensor t;
-    pfem pf1, pf2, pf1prec = NULL, pf2prec = NULL;
-    pintegration_method pim, pimprec = 0;
-    bgeot::pgeometric_trans pgt, pgtprec = NULL;
-    pmat_elem_type pme; pmat_elem_computation pmec = 0;
-
-    if (&(mf.linked_mesh()) != &(mfdata.linked_mesh()))
-      GMM_ASSERT1(false,
-		  "This assembling procedure only works on a single mesh");
-  
-    for (cv << nn; cv != ST_NIL; cv << nn) {
-      nf =
-        dal::bit_vector(mf.linked_mesh().region(boundary).faces_of_convex(cv));
-      if (nf.card() > 0) {
-	pf1 =     mf.fem_of_element(cv); nbd1 = pf1->nb_dof(cv);
-	pf2 = mfdata.fem_of_element(cv); nbd2 = pf2->nb_dof(cv);
-	pgt = mf.linked_mesh().trans_of_convex(cv);
-	pim = mim.int_method_of_element(cv);
-	if (pf1prec != pf1 || pf2prec != pf2 || pgtprec!=pgt || pimprec!=pim) {
-	  pme = mat_elem_product(mat_elem_base(pf1), mat_elem_base(pf2));
-	  pmec = mat_elem(pme, pim, pgt);
-	  pf1prec = pf1; pf2prec = pf2; pgtprec = pgt; pimprec = pim;
-	}
-	for (f << nf; f != ST_NIL; f << nf) {
-	  pmec->gen_compute_on_face(t,mf.linked_mesh().points_of_convex(cv),
-                                    f, cv);
-	  base_tensor::iterator p = t.begin();
-	  for (size_type i = 0; i < nbd2; i++)
-	    {
-	      size_type dof2 = mfdata.ind_basic_dof_of_element(cv)[i];
-	      for (size_type j = 0; j < nbd1; j++, ++p)
-		{
-		  size_type dof1 = mf.ind_basic_dof_of_element(cv)[j];
-		  for (size_type k = 0; k < N; k++) {
-		    B[dof1*N + k] += F[dof2*N+k]*(*p);
-		  }
-		}
-	    }
-	  if (p != t.end()) GMM_ASSERT1(false, "internal error"); 
-	}
-      }
-    }
-  }
-
-  template<class VECT1, class VECT2>
-  void old_asm_volumic_source_term(VECT1 &B, const mesh_im &mim,
-                                   const mesh_fem &mf,
-				   const mesh_fem &mfdata,
-                                   const VECT2 &F, dim_type N)
-  {
-    size_type cv, nbd1, nbd2;
-    dal::bit_vector nn = mf.convex_index();
-    base_tensor t;
-    pfem pf1, pf2, pf1prec = NULL, pf2prec = NULL;
-    pintegration_method pim, pimprec = 0;
-    bgeot::pgeometric_trans pgt, pgtprec = NULL;
-    pmat_elem_type pme; pmat_elem_computation pmec = 0;
-
-    if (&(mf.linked_mesh()) != &(mfdata.linked_mesh()))
-      GMM_ASSERT1(false,
-		  "This assembling procedure only works on a single mesh");
-
-    for (cv << nn; cv != ST_NIL; cv << nn)
-      {
-	pf1 =     mf.fem_of_element(cv); nbd1 = pf1->nb_dof(cv);
-	pf2 = mfdata.fem_of_element(cv); nbd2 = pf2->nb_dof(cv);
-	pgt = mf.linked_mesh().trans_of_convex(cv);
-	pim = mim.int_method_of_element(cv);
-	if (pf1prec != pf1 || pf2prec != pf2 || pgtprec != pgt ||
-            pimprec != pim) {
-          pme = mat_elem_product(mat_elem_base(pf1), mat_elem_base(pf2));
-          pmec = mat_elem(pme, pim, pgt);
-          pf1prec = pf1; pf2prec = pf2; pgtprec = pgt; pimprec = pim;
-        }
-	pmec->gen_compute(t, mf.linked_mesh().points_of_convex(cv), cv);
-	base_tensor::iterator p = t.begin();
-	for (size_type i = 0; i < nbd2; i++) {
-          size_type dof2 = mfdata.ind_basic_dof_of_element(cv)[i];
-          for (size_type j = 0; j < nbd1; j++, ++p) {
-            size_type dof1 = mf.ind_basic_dof_of_element(cv)[j];
-            for (size_type k = 0; k < N; k++)
-              B[dof1*N + k] += F[dof2*N+k]*(*p);
-          }
-        }
-	if (p != t.end()) GMM_ASSERT1(false, "internal error"); 
-      }
-  }
-
-  template<class MATRM, class MESH_FEM>
-  void old_asm_mass_matrix(MATRM &M, const mesh_im &mim, const MESH_FEM &mf1,
-			   const MESH_FEM &mf2, dim_type N) {
-    size_type cv, nbd1, nbd2;
-    dal::bit_vector nn = mf1.convex_index();
-    base_tensor t;
-    pfem pf1, pf1prec = 0, pf2, pf2prec = 0;
-    pintegration_method pim, pimprec = 0;
-    bgeot::pgeometric_trans pgt, pgtprec = NULL;
-    pmat_elem_type pme; pmat_elem_computation pmec = 0;
-
-    if (&(mf1.linked_mesh()) != &(mf2.linked_mesh()))
-      GMM_ASSERT1(false,
-		  "This assembling procedure only works on a single mesh");
-
-    for (cv << nn; cv != ST_NIL; cv << nn) {
-	pf1 = mf1.fem_of_element(cv); nbd1 = pf1->nb_dof(cv);
-	pf2 = mf2.fem_of_element(cv); nbd2 = pf2->nb_dof(cv);
-	pgt = mf1.linked_mesh().trans_of_convex(cv);
-	pim = mim.int_method_of_element(cv);
-	if (pf1prec != pf1 || pf2prec != pf2 || pgtprec != pgt ||
-            pimprec != pim)
-	  {
-	    pme = mat_elem_product(mat_elem_base(pf1), mat_elem_base(pf2));
-	    pmec = mat_elem(pme, pim, pgt);
-	    pf1prec = pf1; pf2prec = pf2; pgtprec = pgt; pimprec = pim;
-	  }
-	pmec->gen_compute(t, mf1.linked_mesh().points_of_convex(cv), cv);
-
-	// cout << "t = " << t << endl;
-      
-	base_tensor::iterator p = t.begin();
-	for (size_type i = 0; i < nbd2; i++) {
-	    size_type dof2 = mf2.ind_basic_dof_of_element(cv)[i];
-	    // cout << "cv = " << cv << " dof2 = " << dof2 << endl;
-	    for (size_type j = 0; j < nbd1; j++, ++p) {
-		size_type dof1 = mf1.ind_basic_dof_of_element(cv)[j];
-		// cout << "dof1 = " << dof1 << " dof2 = " << dof2 << endl;
-		for (size_type k = 0; k < N; k++)
-		  M(dof1*N + k, dof2*N + k) += (*p);
-	      }
-	  }
-	if (p != t.end()) GMM_ASSERT1(false, "internal error"); 
-      }
-  }
-
-  template<class MAT, class VECT>
-  void old_asm_stiffness_matrix_for_linear_elasticity
-  (MAT &RM, const mesh_im &mim, const mesh_fem &mf, 
-   const mesh_fem &mfdata, const VECT &LAMBDA, const VECT &MU) {
-
-    size_type cv, nbd2, N = mf.linked_mesh().dim();
-    dal::bit_vector nn = mf.convex_index();
-    base_tensor t;
-    pfem pf1, pf2, pf1prec = NULL, pf2prec = NULL;
-    pintegration_method pim, pimprec = 0;
-    bgeot::pgeometric_trans pgt, pgtprec = NULL;
-    pmat_elem_type pme; pmat_elem_computation pmec = 0;
-
-    if (&(mf.linked_mesh()) != &(mfdata.linked_mesh()))
-      GMM_ASSERT1(false,
-		  "This assembling procedure only works on a single mesh");
-  
-    for (cv << nn; cv != ST_NIL; cv << nn) {
-      pf1 =     mf.fem_of_element(cv); 
-      pf2 = mfdata.fem_of_element(cv); nbd2 = pf2->nb_dof(cv);
-      pgt = mf.linked_mesh().trans_of_convex(cv);
-      pim = mim.int_method_of_element(cv);
-      if (pf1prec != pf1 || pf2prec != pf2 || pgtprec != pgt || pimprec != pim)
-	{
-	  pme = mat_elem_product(mat_elem_product(mat_elem_grad(pf1),
-						  mat_elem_grad(pf1)), 
-				 mat_elem_base(pf2));
-	  pmec = mat_elem(pme, pim, pgt);
-	  pf1prec = pf1; pf2prec = pf2; pgtprec = pgt; pimprec = pim;
-	}
-      pmec->gen_compute(t, mf.linked_mesh().points_of_convex(cv), cv);
-      base_tensor::iterator p = t.begin();
-      
-      size_type nbd = mf.nb_basic_dof_of_element(cv);
-      
-      for (size_type r = 0; r < nbd2; r++) {
-	size_type dof3 = mfdata.ind_basic_dof_of_element(cv)[r];
-	for (dim_type l = 0; l < N; l++)
-	  for (size_type j = 0; j < nbd; j++) {
-	    size_type dof2 = mf.ind_basic_dof_of_element(cv)[j];
-	    
-	    for (dim_type k = 0; k < N; k++)
-	      for (size_type i = 0; i < nbd; i++, ++p) {
-		size_type dof1 = mf.ind_basic_dof_of_element(cv)[i];
-		
-		if (dof1*N + k >= dof2*N + l) {
-		  RM(dof1*N + k, dof2*N + l) += LAMBDA[dof3] * (*p);
-		  RM(dof2*N + l, dof1*N + k) = RM(dof1*N + k, dof2*N + l);
-		}
-		
-		if (dof1*N + l >= dof2*N + k) {
-		  RM(dof1*N + l, dof2*N + k) += MU[dof3] * (*p);
-		  RM(dof2*N + k, dof1*N + l) = RM(dof1*N + l, dof2*N + k);
-		}
-		
-		if (l == k && dof1 >= dof2)
-		  for (size_type n = 0; n < N; ++n) {
-		    RM(dof1*N + n, dof2*N + n) += MU[dof3] * (*p);
-		    RM(dof2*N + n, dof1*N + n) = RM(dof1*N + n, dof2*N + n);
-		  }
-		
-	      }
-	  }
-      }
-      if (p != t.end()) GMM_ASSERT1(false, "internal error"); 
-    }
-  }
-
-} /* namespace getfem */
-
-
-static void gen_mesh(getfem::mesh& mesh) {
-  cout << "Mesh generation, N=" << param.NX << " Ndim=" << param.Ndim << endl;
-  base_node org(param.Ndim); gmm::clear(org);
-  std::vector<base_small_vector> vtab(param.Ndim);
-  std::vector<size_type> ref(param.Ndim);
-  std::fill(ref.begin(), ref.end(), param.NX);
-  for (size_type i = 0; i < param.Ndim; i++) { 
-    vtab[i] = base_small_vector(param.Ndim); gmm::clear(vtab[i]);
-    (vtab[i])[i] = 1. / scalar_type(param.NX);
-  }
-  switch (param.mesh_type) {
-  case 0: getfem::parallelepiped_regular_simplex_mesh
-      (mesh, dim_type(param.Ndim), org,vtab.begin(), ref.begin()); 
-    cerr << mesh.convex_index().card() << " " << param.Ndim
-         << "D simplexes generated\n";
-    break;
-  case 1 : getfem::parallelepiped_regular_mesh
-      (mesh, dim_type(param.Ndim), org, vtab.begin(), ref.begin()); 
-    cerr << mesh.convex_index().card() << " " << param.Ndim
-         << "D parallelepipeds generated\n";
-    break;
-  case 2 : getfem::parallelepiped_regular_prism_mesh
-      (mesh, dim_type(param.Ndim), org, vtab.begin(), ref.begin()); 
-    cerr << mesh.convex_index().card() << " " << param.Ndim
-         << "D prisms generated\n";
-    break;
-  default : GMM_ASSERT1(false, "Unknown type of mesh");
-  }
-
-  assert(param.NX>2);
-  /* un ptit trou dans la liste des convexes ne fait pas de mal */
-  mesh.sup_convex(param.NX/2);
-  mesh.sup_convex(param.NX/2 + 1);
-  mesh.optimize_structure();
-
-  /* bouge un peu les noeuds */
-  /*  for (size_type i=0; i < mesh.points().size(); ++i) {
-    for (size_type j=0; j < param.Ndim; ++j) {
-      float d = ((rand() % 100)-50)/(500.*param.NX);
-      mesh.points()[i][j] += d;
-    }
-    }*/
-  for (unsigned cv=0; cv < std::min(mesh.convex_index().card(),
-			   param.NX*param.Ndim*param.Ndim*10); cv += 2) {
-    mesh.region(1).add(cv, bgeot::short_type((cv/4) % (param.Ndim > 1 ? 3 : 2))); 
-  }
-  mesh.region(1).add(0,0);
-}
-
-static void init_mesh_fem(getfem::mesh_fem &mf, bool datamf) {
-  if (datamf)
-    mf.set_classical_finite_element(dim_type(param.Kdata));
-  else {
-    dal::bit_vector cvlst = mf.linked_mesh().convex_index();
-    for (dal::bv_visitor cv(cvlst); !cv.finished(); ++cv) {
-      bgeot::pgeometric_trans pgt = mf.linked_mesh().trans_of_convex(cv);
-      if ((cv+1) % 100) {
-	mf.set_finite_element(cv,
-                              getfem::classical_fem(pgt,short_type(param.K)));
-      } else {
-	mf.set_finite_element(cv,
-                              getfem::classical_fem(pgt,short_type(param.K2)));
-      }
-    }
-  }
-}
-
-static void init_mesh_im(getfem::mesh_im &mim, bool use_exact_im=true) {
-  size_type cv;
-  dal::bit_vector cvlst = mim.linked_mesh().convex_index();
-  for (cv << cvlst; cv != size_type(-1); cv << cvlst) {      
-    bgeot::pgeometric_trans pgt = mim.linked_mesh().trans_of_convex(cv);
-    if ((cv+1) % 100) {
-      mim.set_integration_method(cv, 
-	(use_exact_im && (rand() % 10)==0) ? getfem::classical_exact_im(pgt) : 
-		      getfem::classical_approx_im(pgt,dim_type(param.K*3)));
-    } else {
-      mim.set_integration_method(cv, 
-      (use_exact_im && (rand() % 10)==0)  ? getfem::classical_exact_im(pgt) : 
-		       getfem::classical_approx_im(pgt,dim_type(param.K2*3)));
-    }
-  }
-}
-
-static void comp_mat(const sparse_matrix_type& M1,
-                     const sparse_matrix_type& M2) {
-  scalar_type d = 0;
-  scalar_type mx = 1e-200; /* avoid triggering an FPE for bound assembly */
-                           /* when there is no boundary                  */
-  sparse_vector_type r(gmm::mat_ncols(M1));
-  for (size_type i = 0; i < gmm::mat_nrows(M1); ++i) {
-    mx = std::max(mx,gmm::vect_norminf(gmm::mat_const_row(M1,i)));
-    mx = std::max(mx,gmm::vect_norminf(gmm::mat_const_row(M2,i)));
-    /*    int r = gmm::add(gmm::scaled(gmm::mat_const_row(M1,i), -1.0),
-	  gmm::mat_row(M2,i));*/
-    gmm::copy(gmm::mat_const_row(M2,i),r);
-    gmm::add(gmm::scaled(gmm::mat_const_row(M1,i), -1.0),r);
-    scalar_type d2 = gmm::vect_norminf(r);
-    d = std::max(d,d2);
-    if (mx > 1e-10 && d/mx > 1e-6) {
-      sparse_vector_type r1(gmm::mat_ncols(M1));
-      sparse_vector_type r2(gmm::mat_ncols(M2));
-      gmm::copy(gmm::mat_const_row(M1,i),r1);
-      gmm::copy(gmm::mat_const_row(M2,i),r2);    
-      cout << "\nrow(" << i+1 << "),\nM1=" << r1 << "\nM2=" << r2 << endl;
-      fail_cnt++;
-      GMM_ASSERT1(false, "Failed ! ");
-      break;
-    }
-  }
-  assert(mx!=0.);
-  cout << " ---> difference between assemblies: " << d / mx << "\n\n";
-}
-
-static void comp_vec(const base_vector& V1, const base_vector& V2) {
-  scalar_type mx = std::max(gmm::vect_norminf(V1),gmm::vect_norminf(V2));
-  base_vector dv = V2;
-  gmm::add(gmm::scaled(V1, -1.0),dv);
-  scalar_type d = gmm::vect_norminf(dv);
-  if (mx != 0. && d/mx > 1e-6) {
-    fail_cnt++;
-    cout << " FAILED !";
-  }
-  assert(mx!=0.);
-  cout << " ---> difference between assemblies: " << d / mx << "\n\n";
-}
-
-
-
-static double nrand() { return (::rand() % 10000) / 10000. + 0.01; }
-
-
-static void run_tests(getfem::mesh_im &mim, 
-               getfem::mesh_fem& mf, getfem::mesh_fem& mfq,
-               getfem::mesh_fem& mfd, getfem::mesh_fem& mfdq,
-               bool do_new, bool do_old, const std::vector<bool>& do_what,
-               unsigned nloop, unsigned nloop_bound) {
-  size_type Ndim = mf.linked_mesh().dim();
-  base_vector V1q(Ndim*mf.nb_dof()), V2q(mfq.nb_dof());
-  base_vector V1(mf.nb_dof()), V2(mf.nb_dof());
-  sparse_matrix_type M1(mfq.nb_dof(),mfq.nb_dof());
-  sparse_matrix_type M2(mfq.nb_dof(),mfq.nb_dof());
-
-  chrono c;
-    
-
-  cout << "mf.nb_dof=" << mf.nb_dof() << " mfq=" << mfq.nb_dof() << endl;
-  cout << "mfd.nb_dof=" << mfd.nb_dof() << " mfdq=" << mfdq.nb_dof() << endl;
-
-  base_vector A(mfd.nb_dof()); std::generate(A.begin(), A.end(), nrand);
-  base_vector A2(mfd.nb_dof()); std::generate(A2.begin(), A2.end(), nrand);
-  base_vector Aq(mfdq.nb_dof()); std::generate(Aq.begin(), Aq.end(), nrand);
-
-
-  /* --- SCALAR VOLUMIC SOURCE --- */
-  if (do_what[DO_SCAL_VOLUMIC_SOURCE]) {
-    if (do_old) {
-      cout << "volumic source, Q=" << 1 << ", old way [" << nloop_bound
-           << " times] .." << flushy;
-      c.init();
-      for (size_type cnt = 0; cnt < nloop_bound; ++cnt) {
-	gmm::clear(V1); c.tic(); //gmm::resize(M1, mfq.nb_dof(),mfq.nb_dof());
-	getfem::old_asm_volumic_source_term(V1, mim, mf, mfd, A, 1u);
-	c.toc(); cout << "#" << flushy;
-      }
-      cout << "done " << c << endl;
-    }
-    if (do_new) {
-      cout << "volumic source, Q=" << 1 << ", new way [" << nloop_bound
-           << " times] .." << flushy;
-      c.init();
-      for (size_type cnt = 0; cnt < nloop_bound; ++cnt) {
-	gmm::clear(V2); c.tic();
-	getfem::asm_source_term(V2, mim, mf, mfd, A);
-	c.toc(); cout << "#" << flushy;
-      }
-      cout << "done " << c << endl;
-    }
-    if (do_old && do_new) comp_vec(V1,V2);
-  }
-  //  cerr << "V1(old)=" << V1 << endl;
-  //cerr << "V2(new)=" << V2 << endl;
-
-  /* --- VECTOR VOLUMIC SOURCE --- */
-  if (do_what[DO_VEC_VOLUMIC_SOURCE]) {
-    if (do_old) {
-      cout << "volumic source, Q=" << Ndim << ", old way ["
-           << nloop_bound << " times] .." << flushy;
-      c.init();
-      for (size_type cnt = 0; cnt < nloop_bound; ++cnt) {
-	gmm::clear(V1q); c.tic(); //gmm::resize(M1, mfq.nb_dof(),mfq.nb_dof());
-	getfem::old_asm_volumic_source_term(V1q, mim, mf, mfd,
-                                            Aq, dim_type(Ndim));
-	c.toc(); cout << "#" << flushy;
-      }
-      cout << "done " << c << endl;
-    }
-    if (do_new) {
-      cout << "volumic source, Q=" << Ndim << ", new way ["
-           << nloop_bound << " times] .." << flushy;
-      c.init();
-      for (size_type cnt = 0; cnt < nloop_bound; ++cnt) {
-	gmm::clear(V2q); c.tic();
-	getfem::asm_source_term(V2q, mim, mfq, mfd, Aq);
-	c.toc(); cout << "#" << flushy;
-      }
-      cout << "done " << c << endl;
-    }  
-    if (do_old && do_new) comp_vec(V1q,V2q);
-  }
-
-  /* --- SCALAR MASS MATRIX --- */
-  if (do_what[DO_SCAL_MASS_MATRIX]) {
-    if (do_old) {
-      cout << "mass matrix, Q=" << 1 << ", old way ["
-           << nloop << " times] .." << flushy;
-      c.init();
-      for (size_type cnt = 0; cnt < nloop; ++cnt) {
-	gmm::clear(M1); c.tic(); //gmm::resize(M1, mfq.nb_dof(),mfq.nb_dof());
-	getfem::old_asm_mass_matrix(M1, mim, mf, mfd, 1);
-      c.toc(); cout << "#" << flushy;
-    }
-    cout << "done " << c << endl;
-  }
-  if (do_new) {
-    cout << "mass matrix, Q=" << 1 << ", new way ["
-         << nloop << " times] .." << flushy;
-    c.init();
-    for (size_type cnt = 0; cnt < nloop; ++cnt) {
-      gmm::clear(M2); c.tic(); 
-      getfem::asm_mass_matrix(M2, mim, mf, mfd);
-      c.toc(); cout << "#" << flushy;
-    }
-    cout << "done " << c << endl;
-  }
-  if (do_old && do_new) comp_mat(M1,M2);
-  }
-
-  /* --- VECTOR MASS MATRIX --- */
-  if (do_what[DO_VEC_MASS_MATRIX]) {
-  if (do_old) {
-    cout << "mass matrix, Q=" << Ndim << ", old way [" << nloop
-         << " times] .." << flushy;
-    c.init();
-    for (size_type cnt = 0; cnt < nloop; ++cnt) {
-      gmm::clear(M1); c.tic(); //gmm::resize(M1, mfq.nb_dof(),mfq.nb_dof());
-      getfem::old_asm_mass_matrix(M1, mim, mf, mfd, dim_type(Ndim));
-      c.toc(); cout << "#" << flushy;
-    }
-    cout << "done " << c << endl;
-  }
-  if (do_new) {
-    cout << "mass matrix, Q=" << Ndim << ", new way [" << nloop
-         << " times] .." << flushy;
-    c.init();
-    for (size_type cnt = 0; cnt < nloop; ++cnt) {
-      gmm::clear(M2); c.tic();
-      getfem::asm_mass_matrix(M2, mim, mfq, mfdq);
-      c.toc(); cout << "#" << flushy;
-    }
-    cout << "done " << c << endl;
-  }
-  if (do_old && do_new) comp_mat(M1,M2);
-  }
-
-  /* ---- LINEAR ELASTICITY ---- */
-  if (do_what[DO_LIN_ELAST]) {
-  if (do_old) {
-    cout << "linear elasticity, Q=" << Ndim<<", old way ["
-         << nloop << " times] .." << flushy;
-    c.init();
-    for (size_type cnt = 0; cnt < nloop; ++cnt) {
-      gmm::clear(M1); c.tic();
-      getfem::old_asm_stiffness_matrix_for_linear_elasticity(M1, mim, mf,
-                                                             mfd, A, A2);
-      c.toc(); cout << "#" << flushy;
-    }
-    cout << "done " << c << endl;
-  }
-  if (do_new) {
-    cout << "linear elasticity, Q=" << Ndim << ", new way ["
-         << nloop << " times] .." << flushy;
-    c.init();
-    for (size_type cnt = 0; cnt < nloop; ++cnt) {
-      gmm::clear(M2); c.tic();
-      getfem::asm_stiffness_matrix_for_linear_elasticity(M2, mim, mfq,
-                                                         mfd, A, A2);
-      c.toc(); cout << "#" << flushy;
-    }
-    cout << "done " << c << endl;
-
-  }
-  if (do_old && do_new) comp_mat(M1,M2);
-  }
-}
-
-
-struct dummy_nonlin : public getfem::nonlinear_elem_term {
-  unsigned i,j;
-  bgeot::multi_index sizes_;
-  dummy_nonlin(size_type N) : sizes_(2)
-  { sizes_[0] = sizes_[1] = short_type(N); }
-  const bgeot::multi_index &sizes(size_type) const { return sizes_; }
-  virtual void compute(getfem::fem_interpolation_context& /*ctx*/,
-		       bgeot::base_tensor &t) {
-    t.adjust_sizes(sizes_); std::fill(t.begin(), t.end(), 0.);
-    t[j*sizes_[0]+i] = 1.0;
-  }
-};
-
-static void test_nonlin(const getfem::mesh_im &mim, const getfem::mesh_fem &mf)
-{
-  size_type N = mf.linked_mesh().dim();
-  dummy_nonlin bidon(N);
-  cerr << "testing assembly of nonlinear terms\n";
-  for (bidon.i=0; bidon.i < N; ++bidon.i) {
-    for (bidon.j=0; bidon.j < N; ++bidon.j) {
-      std::vector<scalar_type> V1(mf.nb_dof()), V2(mf.nb_dof());
-      char s[512]; sprintf(s,"t=comp(NonLin(#1).vGrad(#1));"
-			   "V$1(#1) += t(i,j,:,i,j); "
-			   "V$2(#1) += comp(vGrad(#1))(:,%d,%d)",
-                           bidon.i+1, bidon.j+1);
-      cout << s << "\n";
-      getfem::generic_assembly assem(s);
-      assem.push_mi(mim);
-      assem.push_mf(mf);
-      assem.push_nonlinear_term(&bidon);
-      assem.push_vec(V1);
-      assem.push_vec(V2);
-      assem.assembly();
-      gmm::add(gmm::scaled(V2,-1.),V1);
-      scalar_type err = gmm::vect_norm2(V1);
-      cout << "i=" << bidon.i << ", j=" << bidon.j << " |V1-V2| = "
-           << err << "\n";
-      assert(err < 1e-10);      
-    }
-  }
-}
-
-template<typename VECT1> class shape_der_nonlinear_term 
-  : public getfem::nonlinear_elem_term {
-  
-  const getfem::mesh_fem &mf;
-  const VECT1 &U;
-  size_type N;
-  base_vector coeff;
-  base_matrix gradU, E, Sigma;
-  bgeot::multi_index sizes_;
-  scalar_type lambda, mu;
-  
-public:
-  shape_der_nonlinear_term(const getfem::mesh_fem &mf_, const VECT1 &U_,
-			  scalar_type lambda_, scalar_type mu_) 
-    : mf(mf_), U(U_),
-      N(mf_.get_qdim()),
-      gradU(N, N), E(N, N), Sigma(N,N), sizes_(N,N),
-      lambda(lambda_), mu(mu_) { }
-  
-  const bgeot::multi_index &sizes(size_type) const { return sizes_; }
-  
-  virtual void compute(getfem::fem_interpolation_context& ,
-		       bgeot::base_tensor &t) {
-    assert(t.size() == N*N);
-    for (size_type i = 0; i < N; ++i) 
-      for (size_type j = 0; j < N; ++j)
-	t(i,j) = 0.0;
-    
-  }
-};
-
-void testbug() {
-  std::vector<size_type> nsubdiv(3); nsubdiv[0] = nsubdiv[1] = nsubdiv[2] = 3;
-  getfem::mesh m; 
-  getfem::regular_unit_mesh(m, nsubdiv, bgeot::simplex_geotrans(3,1));
-  getfem::mesh_fem mf1(m,3), mf2(m,3);
-  mf1.set_classical_finite_element(m.convex_index(), 1);
-  mf2.set_classical_finite_element(m.convex_index(), 1);
-  getfem::mesh_im mim(m); mim.set_integration_method(m.convex_index(), 5);
-  std::vector<scalar_type> U(mf1.nb_dof()), SD(mf2.nb_dof());
-  gmm::fill_random(U);
-
-  shape_der_nonlinear_term<std::vector<scalar_type> > nl(mf1, U, 0, 1);
-  
-  // trigers a real bug: printing an empty (because of the "vectorization"
-  // of vBase) subtensor will crash
-  getfem::generic_assembly assem2
-    ("t=comp(vBase(#1).vBase(#2));"
-     "print(t(:,:,2,3)); ");
-
-  assem2.push_mi(mim);
-  assem2.push_mf(mf1);
-  assem2.push_nonlinear_term(&nl);
-  assem2.push_mf(mf2);
-  assem2.push_vec(SD);
-  
-  double t0 = gmm::uclock_sec();
-  assem2.assembly();
-  cerr << " done : " << gmm::uclock_sec() - t0 << "\n"; exit(1);
-  exit(1);
-}
-
-
 
 #define SCAL_TEST_0(title, expr, mim_, val)                             \
   cout << "\n" << title << endl;                                        \
@@ -779,7 +452,7 @@ void testbug() {
     cout << "Result=" << E1 << endl;                                    \
     scalar_type error = gmm::abs(E1-val);                               \
     cout << "Error : " << error << endl;                                \
-    GMM_ASSERT1(error < 1E-8,                                          \
+    GMM_ASSERT1(error < 1E-8,						\
                 "Error in high or low level generic assembly");         \
   }
 
@@ -907,6 +580,7 @@ static void test_new_assembly(int N, int NX, int pK) {
       ((std::string("GT_PK(") + Ns + ",1)").c_str());
     std::vector<size_type> nsubdiv(N, NX);
     getfem::regular_unit_mesh(m, nsubdiv, pgt);
+    m.optimize_structure();
 
     const size_type NEUMANN_BOUNDARY_NUM = 1;
     const size_type DIRICHLET_BOUNDARY_NUM = 2;
@@ -1010,7 +684,7 @@ static void test_new_assembly(int N, int NX, int pK) {
 
     if (all) {
       SCAL_TEST_1("Test on L2 norm", "u.u", mim,
-                  gmm::sqr(getfem::asm_L2_norm(mim, mf_u, U)));
+                  gmm::sqr(getfem::old_asm_L2_norm(mim, mf_u, U)));
       SCAL_TEST_2("Norm_sqr(u)", mim);
 
       if (N == 2) {
@@ -1026,7 +700,7 @@ static void test_new_assembly(int N, int NX, int pK) {
 
     if (all) {
       SCAL_TEST_1("Test on H1 semi-norm", "Grad_u:Grad_u", mim2,
-                  gmm::sqr(getfem::asm_H1_semi_norm(mim2, mf_u, U)));
+                  gmm::sqr(getfem::old_asm_H1_semi_norm(mim2, mf_u, U)));
 
       SCAL_TEST_2("Id(meshdim)*Grad_u:Grad_u", mim2);
 
@@ -1049,7 +723,7 @@ static void test_new_assembly(int N, int NX, int pK) {
 
     if (all) {
       VEC_TEST_1("Test for source term", ndofu, "u.Test_u", mim, size_type(-1),
-                 Iu, getfem::asm_source_term(V, mim, mf_u, mf_u, U));
+                 Iu, getfem::old_asm_source_term(V, mim, mf_u, mf_u, U));
 
     }
 
@@ -1057,32 +731,32 @@ static void test_new_assembly(int N, int NX, int pK) {
 
       {VEC_TEST_1("Test for Neumann term", ndofu, "u.Test_u",
                   mim, NEUMANN_BOUNDARY_NUM,
-                  Iu, getfem::asm_source_term(V, mim, mf_u, mf_u,
+                  Iu, getfem::old_asm_source_term(V, mim, mf_u, mf_u,
                                               U, NEUMANN_BOUNDARY_NUM));}
 
       {VEC_TEST_1("Test for Neumann term", ndofu,
                   "(((Reshape(A,meshdim,meshdim))')*Normal).Test_u",
                   mim, NEUMANN_BOUNDARY_NUM,
-                  Iu, getfem::asm_normal_source_term(V, mim, mf_u, mf_u,
+                  Iu, getfem::old_asm_normal_source_term(V, mim, mf_u, mf_u,
                                               A, NEUMANN_BOUNDARY_NUM));}
       
       if (N == 2)
       {VEC_TEST_1("Test for Neumann term", ndofu,
                   "(A'*Normal).Test_u", mim,
                   NEUMANN_BOUNDARY_NUM,
-                  Iu, getfem::asm_normal_source_term(V, mim, mf_u, mf_u,
+                  Iu, getfem::old_asm_normal_source_term(V, mim, mf_u, mf_u,
                                                  A, NEUMANN_BOUNDARY_NUM));}
       if (N == 3)
       {VEC_TEST_1("Test for Neumann term", ndofu,
                   "(A'*Normal).Test_u", mim, NEUMANN_BOUNDARY_NUM,
-                  Iu, getfem::asm_normal_source_term(V, mim, mf_u, mf_u,
+                  Iu, getfem::old_asm_normal_source_term(V, mim, mf_u, mf_u,
                                                  A, NEUMANN_BOUNDARY_NUM));}
     }
 
     if (all) {
       {VEC_TEST_1("Test for Neumann term with reduced fem", ndofchi,
                   "p*Test_chi", mim, DIRICHLET_BOUNDARY_NUM,
-                  Ichi, getfem::asm_source_term(V, mim, mf_chi, mf_p,
+                  Ichi, getfem::old_asm_source_term(V, mim, mf_chi, mf_p,
                                                 P, DIRICHLET_BOUNDARY_NUM));}
     }
 
@@ -1092,13 +766,13 @@ static void test_new_assembly(int N, int NX, int pK) {
 
     if (all) {
       MAT_TEST_1("Test for Mass matrix", ndofu, ndofu, "Test_u.Test2_u", mim,
-                 Iu, Iu,  getfem::asm_mass_matrix(K, mim, mf_u));
+                 Iu, Iu,  getfem::old_asm_mass_matrix(K, mim, mf_u));
     }
 
     if (all) {
       MAT_TEST_1("Test for Laplacian stiffness matrix", ndofp, ndofp,
                  "Grad_Test_p:Grad_Test2_p", mim2, Ip, Ip,
-                 getfem::asm_stiffness_matrix_for_homogeneous_laplacian
+                 getfem::old_asm_stiffness_matrix_for_homogeneous_laplacian
                  (K, mim2, mf_p));
       MAT_TEST_2(ndofp, ndofp, "(Grad_p:Grad_p)/2", mim2, Ip, Ip);
       MAT_TEST_2(ndofp, ndofp, "sqr(Norm(Grad_p))/2", mim2, Ip, Ip);
@@ -1139,7 +813,7 @@ static void test_new_assembly(int N, int NX, int pK) {
                  ndofu, ndofu, "(lambda*Trace(Grad_Test_u)*Id(qdim(u)) "
                  "+ mu*(Grad_Test_u'+Grad_Test_u)):Grad_Test2_u", mim2,
                  Iu, Iu,
-                 getfem::asm_stiffness_matrix_for_homogeneous_linear_elasticity
+                 getfem::old_asm_stiffness_matrix_for_homogeneous_linear_elasticity
                  (K, mim2, mf_u, lambda, mu));
       MAT_TEST_2(ndofu, ndofu, "lambda*Div_Test_u*Div_Test2_u "
                  "+ mu*(Grad_Test_u'+Grad_Test_u):Grad_Test2_u", mim2, Iu, Iu);
@@ -1203,7 +877,7 @@ static void test_new_assembly(int N, int NX, int pK) {
                  ndofu, ndofu, "(lambda2*Trace(Grad_Test_u)*Id(meshdim) "
                  "+ mu2*(Grad_Test_u'+Grad_Test_u)):Grad_Test2_u",
                  mim2, Iu, Iu,
-                 getfem::asm_stiffness_matrix_for_linear_elasticity
+                 getfem::old_asm_stiffness_matrix_for_linear_elasticity
                  (K, mim2, mf_u, mf_p, lambda2, mu2));
     }
 
@@ -1233,34 +907,6 @@ int main(int argc, char *argv[]) {
   
   cerr << "\n\n-----------------------------PERFORMANCE TESTS------------"
        << "---------\n\n";   
-  {
-    getfem::mesh m; 
-    gen_mesh(m);
-    
-    getfem::mesh_fem mf(m); 
-    init_mesh_fem(mf,false);
-    
-    getfem::mesh_im mim(m);
-    init_mesh_im(mim, false);
-    
-    getfem::mesh_fem mfq(m); 
-    mfq.set_qdim(m.dim());
-    init_mesh_fem(mfq,false);
-    
-    getfem::mesh_fem mfqne(m);
-    init_mesh_fem(mfqne,false);
-    
-    test_nonlin(mim,mfq);
-    
-    getfem::mesh_fem mfd(m); 
-    init_mesh_fem(mfd,true);
-    
-    getfem::mesh_fem mfdq(m); 
-    mfdq.set_qdim(m.dim());
-    init_mesh_fem(mfdq,true);
-    
-    run_tests(mim,mf,mfq,mfd,mfdq,param.do_new,param.do_old,tests,1,1);
-  }
   
   cout << "failures: " << fail_cnt << endl;
   return fail_cnt; 
diff --git a/tests/test_assembly.pl b/tests/test_assembly.pl
index 9f068d4..3c2d58b 100644
--- a/tests/test_assembly.pl
+++ b/tests/test_assembly.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_continuation.cc b/tests/test_continuation.cc
index 311b474..92f49e8 100644
--- a/tests/test_continuation.cc
+++ b/tests/test_continuation.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2011-2016 Yves Renard, Tomas Ligursky.
+ Copyright (C) 2011-2017 Yves Renard, Tomas Ligursky.
 
  This file is a part of GetFEM++
 
@@ -203,7 +203,7 @@ bool state_problem::cont(plain_vector &U) {
       }
       sing_out.push_back(s1);
     }
-    cout << "End of Step nº " << step + 1 << " / " << nb_step << endl;
+    cout << "End of Step n " << step + 1 << " / " << nb_step << endl;
   }
 
   if (sing_out.size() > 0) {
@@ -228,6 +228,8 @@ bool state_problem::cont(plain_vector &U) {
 
 int main(int argc, char *argv[]) {
 
+  srand(7689);
+  
   GMM_SET_EXCEPTION_DEBUG; // Exceptions make a memory fault, to debug.
   FE_ENABLE_EXCEPT;        // Enable floating point exception for Nan.
 
diff --git a/tests/test_continuation.param b/tests/test_continuation.param
index b445340..61aadeb 100644
--- a/tests/test_continuation.param
+++ b/tests/test_continuation.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program test_continuation                                %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/tests/test_continuation.pl b/tests/test_continuation.pl
index a98616e..5541c16 100644
--- a/tests/test_continuation.pl
+++ b/tests/test_continuation.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2015-2016 Yves Renard
+# Copyright (C) 2015-2017 Tomas Ligursky
 #
 # This file is a part of GetFEM++
 #
@@ -50,15 +50,23 @@ NOISY = 1;
 close(TMPF);
 
 $er = 0;
-open F, "./test_continuation $tmp 2>&1 |" or die "could not open $tmp\n";
-while (<F>) {
-  #print $_; #uncomment this line in case of problem..
-  if ($_ =~ /smooth bifurcation point/) {
-    ($a, $b) = split(',', $_);
-    if (abs($b - 2) > 0) { print "\nWrong number of bifurcation points\n"; $er = 1; }
+$ok=0;
+$nbtest=0;
+while ($ok==0) {
+  $nbtest=$nbtest+1;
+  open F, "./test_continuation $tmp 2>&1 |" or die "could not open $tmp\n";
+  while (<F>) {
+    #print $_; #uncomment this line in case of problem..
+    if ($_ =~ /smooth bifurcation point/) {
+      ($a, $b) = split(',', $_);
+      if (abs($b - 2) == 0) { $ok = 1; }
+    }
   }
+  close(F);
+  if ($nbtest == 100)
+  { print "\nWrong number of bifurcation points\n"; $er = 1;  $ok = 1; }
 }
-close(F); if ($?) { `rm -f $tmp`; exit(1); }
+if ($?) { `rm -f $tmp`; exit(1); }
 if ($er == 1) { `rm -f $tmp`; exit(1); }
 `rm -f $tmp`;
 
diff --git a/tests/test_gmm_matrix_functions.cc b/tests/test_gmm_matrix_functions.cc
index 9971d0c..9589926 100644
--- a/tests/test_gmm_matrix_functions.cc
+++ b/tests/test_gmm_matrix_functions.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2014-2016 Konstantinos Poulios.
+ Copyright (C) 2014-2017 Konstantinos Poulios.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_gmm_matrix_functions.pl b/tests/test_gmm_matrix_functions.pl
index 56bfcd8..a23222d 100644
--- a/tests/test_gmm_matrix_functions.pl
+++ b/tests/test_gmm_matrix_functions.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2016 Yves Renard
+# Copyright (C) 2014-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_int_set.cc b/tests/test_int_set.cc
index 9b55c01..e51d161 100644
--- a/tests/test_int_set.cc
+++ b/tests/test_int_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard.
+ Copyright (C) 2002-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_int_set.pl b/tests/test_int_set.pl
index fa53b2a..c2378b4 100644
--- a/tests/test_int_set.pl
+++ b/tests/test_int_set.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_interpolated_fem.cc b/tests/test_interpolated_fem.cc
index c376abd..ead6367 100644
--- a/tests/test_interpolated_fem.cc
+++ b/tests/test_interpolated_fem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard.
+ Copyright (C) 2002-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
@@ -41,7 +41,7 @@ using bgeot::size_type;
 using bgeot::dim_type;
 
 typedef gmm::wsvector<scalar_type> sparse_vector_type;
-typedef gmm::row_matrix<sparse_vector_type> sparse_matrix_type;
+typedef gmm::col_matrix<sparse_vector_type> sparse_matrix_type;
 typedef std::vector<scalar_type> linalg_vector;
 
 /**************************************************************************/
@@ -302,7 +302,7 @@ void test3() {
   cout << "MM=" << MM << "\n";
   cout << "mflnk.nb_dof()=" << mflnk.nb_dof() << ", mf2.nb_dof()="
        << mf2.nb_dof() << ", mf1.nb_dof=" << mf1.nb_dof() << "\n";
-  cout << "Matrice de masse\n";
+  cout << "Mass matrix\n";
   scalar_type sum = 0.0; 
   for (size_type i = 0; i < MM.nrows(); i++) { 
     scalar_type slig = 0;
diff --git a/tests/test_interpolated_fem.param b/tests/test_interpolated_fem.param
old mode 100755
new mode 100644
index 33b18e6..4fb77b1
--- a/tests/test_interpolated_fem.param
+++ b/tests/test_interpolated_fem.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program test_link_fem                                    %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/tests/test_interpolated_fem.pl b/tests/test_interpolated_fem.pl
index a12147b..2a4ce9f 100644
--- a/tests/test_interpolated_fem.pl
+++ b/tests/test_interpolated_fem.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_interpolation.cc b/tests/test_interpolation.cc
index cf15f89..5d6ba74 100644
--- a/tests/test_interpolation.cc
+++ b/tests/test_interpolation.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_interpolation.pl b/tests/test_interpolation.pl
index 590dec7..7bff08c 100755
--- a/tests/test_interpolation.pl
+++ b/tests/test_interpolation.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_kdtree.cc b/tests/test_kdtree.cc
index 53f53a6..44f679d 100644
--- a/tests/test_kdtree.cc
+++ b/tests/test_kdtree.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_kdtree.pl b/tests/test_kdtree.pl
index 052ba53..7472f22 100755
--- a/tests/test_kdtree.pl
+++ b/tests/test_kdtree.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_mat_elem.cc b/tests/test_mat_elem.cc
index 634027a..152549d 100644
--- a/tests/test_mat_elem.cc
+++ b/tests/test_mat_elem.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard.
+ Copyright (C) 2002-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_mat_elem.pl b/tests/test_mat_elem.pl
index 714eda3..64579c2 100755
--- a/tests/test_mat_elem.pl
+++ b/tests/test_mat_elem.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_mesh.cc b/tests/test_mesh.cc
index 781961f..acdb0b3 100644
--- a/tests/test_mesh.cc
+++ b/tests/test_mesh.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard.
+ Copyright (C) 2002-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
@@ -198,7 +198,7 @@ void test_mesh(getfem::mesh &m) {
   m.sup_convex(0);
   m.sup_convex(1);
   assert(!m.region(3).is_in(0));
-  m.optimize_structure();
+  m.optimize_structure(false);
   m.write_to_file("test_mesh.mesh");
 
   getfem::mesh m2; m2.read_from_file("test_mesh.mesh");
diff --git a/tests/test_mesh.pl b/tests/test_mesh.pl
index 4aa22a2..a02904f 100644
--- a/tests/test_mesh.pl
+++ b/tests/test_mesh.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_mesh_generation.cc b/tests/test_mesh_generation.cc
index 3d2a217..fc3ead9 100644
--- a/tests/test_mesh_generation.cc
+++ b/tests/test_mesh_generation.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -138,11 +138,13 @@ int main(int argc, char **argv) {
     getfem::pmesher_signed_distance dist = D0;
     switch (opt) {
     case 0: dist = D0; break; /* disk */
-    case 1: {
-      getfem::scalar_type z = sqrt(4 - 1.5*1.5);
-      fixed.push_back(base_node(0,z));
-      fixed.push_back(base_node(0,-z));
-    }
+    case 1:
+      {
+	getfem::scalar_type z = sqrt(4 - 1.5*1.5);
+	fixed.push_back(base_node(0,z));
+	fixed.push_back(base_node(0,-z));
+      }
+      dist = D2; break;  /* union of 2 disks */
     case 2: dist = D2; break; /* union of 2 disks */
     case 3: dist = D3; break; /* cube */
     case 4: dist = D4; break; /* cylinder */
diff --git a/tests/test_mesh_generation.pl b/tests/test_mesh_generation.pl
index 34e121a..eb3db4d 100644
--- a/tests/test_mesh_generation.pl
+++ b/tests/test_mesh_generation.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_mesh_im_level_set.cc b/tests/test_mesh_im_level_set.cc
index d5772f6..457da3a 100644
--- a/tests/test_mesh_im_level_set.cc
+++ b/tests/test_mesh_im_level_set.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_mesh_im_level_set.pl b/tests/test_mesh_im_level_set.pl
index 253394a..15bb7a2 100644
--- a/tests/test_mesh_im_level_set.pl
+++ b/tests/test_mesh_im_level_set.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_range_basis.cc b/tests/test_range_basis.cc
index 46b93ea..9732da7 100644
--- a/tests/test_range_basis.cc
+++ b/tests/test_range_basis.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2009-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_range_basis.param b/tests/test_range_basis.param
index 16c2232..b539cb2 100644
--- a/tests/test_range_basis.param
+++ b/tests/test_range_basis.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program laplacian                                        %
diff --git a/tests/test_range_basis.pl b/tests/test_range_basis.pl
index 52ecc7d..616fe1c 100644
--- a/tests/test_range_basis.pl
+++ b/tests/test_range_basis.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_rtree.cc b/tests/test_rtree.cc
index c689ab9..3d165e8 100644
--- a/tests/test_rtree.cc
+++ b/tests/test_rtree.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_rtree.pl b/tests/test_rtree.pl
index 9ba4a70..b6883a6 100644
--- a/tests/test_rtree.pl
+++ b/tests/test_rtree.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_slice.cc b/tests/test_slice.cc
index 7d442bb..21dce10 100644
--- a/tests/test_slice.cc
+++ b/tests/test_slice.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_slice.pl b/tests/test_slice.pl
index 93f387e..c6b7635 100755
--- a/tests/test_slice.pl
+++ b/tests/test_slice.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_small_vector.cc b/tests/test_small_vector.cc
index e05b669..ccbbdc0 100644
--- a/tests/test_small_vector.cc
+++ b/tests/test_small_vector.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2007-2016 Yves Renard, Julien Pommier.
+ Copyright (C) 2007-2017 Yves Renard, Julien Pommier.
 
  This file is a part of GetFEM++
 
@@ -98,6 +98,7 @@ namespace test {
       node_id(gmm::uint32_type b, gmm::uint32_type cid, bool al_) : p((b*BLOCKSZ+cid)+(al_?0x80000000:0)) {}
       bool null() const { return p == 0; }
       void nullify() { p = 0; }
+      bool operator ==(const node_id &a) { return p == a.p; }
     };
 
 
@@ -270,7 +271,7 @@ namespace test {
       : id(allocate(a.size())) { std::transform(a.begin(), a.end(), begin(), op); }
     template<class BINOP> small_vector(const small_vector<T>& a, const small_vector<T>& b, BINOP op) 
       : id(allocate(a.size())) { std::transform(a.begin(), a.end(), b.begin(), begin(), op); }
-    bool empty() const { return this->id==node_id(0); }
+    bool empty() const { return this->id == node_id(0); }
     unsigned char refcnt() const { return allocator().refcnt(id); }
     dim_type size() const { return allocator().obj_sz(id)/sizeof(value_type); }
     small_vector<T> operator+(const small_vector<T>& other) const 
@@ -457,7 +458,7 @@ namespace getfem {
     typedef double *iterator;
     typedef const double * const_iterator;
     pointer p;
-    pointer base() const { return (double*)((unsigned long)p&(~7UL)); }
+    pointer base() const { return (double*)((size_type)p&(~7UL)); }
     reference operator[](size_type i) { return base()[i]; }
     const double& operator[](size_type i) const { return base()[i]; }
     micro_vec() : p(0) {}
@@ -490,7 +491,7 @@ namespace getfem {
       return *this;
     }
     ~micro_vec() { deallocate(); }
-    size_type size() const { return (unsigned long)p & 7UL; }
+    size_type size() const { return (size_type)(p) & 7UL; }
     micro_vec(const micro_vec& va, const micro_vec& vb) : p(alloc(va.size())) { 
       /*double * restrict__ pb = base(), *pe = base()+size(), *pva = va.base(), *pvb = vb.base();
 	for (; pb < pe;) *pb++=*pva+++*pvb++;*/
@@ -550,10 +551,11 @@ namespace getfem {
       for (size_type j=0; j < vv.size(); ++j) {
 	for (size_type k=0; k < vv[j].size(); ++k) {
 	  vv[j][k] = double(j+k);
-	  assert(vv[j][k] == j+k);
+	  assert(vv[j][k] == double(j+k));
 	}
 	vv[j] = vv[j];
-	for (size_type k=0; k < vv[j].size(); ++k) assert(vv[j][k] == j+k);
+	for (size_type k=0; k < vv[j].size(); ++k)
+	  assert(vv[j][k] == double(j+k));
       }
     }
     cout << "remplissage : " << c.toc().cpu() << " sec\n";
diff --git a/tests/test_small_vector.pl b/tests/test_small_vector.pl
index be7fb7b..897f1b3 100755
--- a/tests/test_small_vector.pl
+++ b/tests/test_small_vector.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/test_tree_sorted.cc b/tests/test_tree_sorted.cc
index e2ab8ae..73eb14b 100644
--- a/tests/test_tree_sorted.cc
+++ b/tests/test_tree_sorted.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2002-2016 Yves Renard.
+ Copyright (C) 2002-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/tests/test_tree_sorted.pl b/tests/test_tree_sorted.pl
index 4c11d3b..a1a4f73 100644
--- a/tests/test_tree_sorted.pl
+++ b/tests/test_tree_sorted.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/thermo_elasticity_electrical_coupling.cc b/tests/thermo_elasticity_electrical_coupling.cc
index f5e459f..9ce4662 100644
--- a/tests/thermo_elasticity_electrical_coupling.cc
+++ b/tests/thermo_elasticity_electrical_coupling.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2015-2016 Yves Renard.
+ Copyright (C) 2015-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/tests/thermo_elasticity_electrical_coupling.param b/tests/thermo_elasticity_electrical_coupling.param
index 7715ed8..973a9c1 100644
--- a/tests/thermo_elasticity_electrical_coupling.param
+++ b/tests/thermo_elasticity_electrical_coupling.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program thermo_elasticity_electrical_coupling            %
diff --git a/tests/thermo_elasticity_electrical_coupling.pl b/tests/thermo_elasticity_electrical_coupling.pl
index 9fb19bf..4f7b62c 100644
--- a/tests/thermo_elasticity_electrical_coupling.pl
+++ b/tests/thermo_elasticity_electrical_coupling.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2015-2016 Yves Renard
+# Copyright (C) 2015-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #
diff --git a/tests/wave_equation.cc b/tests/wave_equation.cc
index 7cd0086..1f32bfd 100644
--- a/tests/wave_equation.cc
+++ b/tests/wave_equation.cc
@@ -1,6 +1,6 @@
 /*===========================================================================
 
- Copyright (C) 2009-2016 Yves Renard.
+ Copyright (C) 2009-2017 Yves Renard.
 
  This file is a part of GetFEM++
 
diff --git a/tests/wave_equation.param b/tests/wave_equation.param
index 9425788..3b7bd19 100644
--- a/tests/wave_equation.param
+++ b/tests/wave_equation.param
@@ -1,3 +1,19 @@
+% Copyright (C) 2017-2017 Yves Renard.
+%
+% This file is a part of GetFEM++
+%
+% GetFEM++  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 along with the GCC Runtime Library
+% Exception either version 3.1 or (at your option) any later version.
+% This program  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 and GCC Runtime Library Exception for more details.
+% You  should  have received a copy of the GNU Lesser General Public License
+% along  with  this program;  if not, write to the Free Software Foundation,
+% Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 % -*- matlab -*- (enables emacs matlab mode)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % parameters for program heat equation                                    %
diff --git a/tests/wave_equation.pl b/tests/wave_equation.pl
index 893fe56..b95aaa8 100644
--- a/tests/wave_equation.pl
+++ b/tests/wave_equation.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2016 Yves Renard
+# Copyright (C) 2001-2017 Yves Renard
 #
 # This file is a part of GetFEM++
 #

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/getfem.git



More information about the debian-science-commits mailing list